From 7301178aac1baf1cc334e7c7a66bfe50a65fbf49 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 28 Dec 2003 09:44:37 +0000 Subject: [PATCH] Pass around IntrinsicLowering instances as appropriate. Reimplement the Interpreters implementation of va_* to be more direct. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@10627 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/ExecutionEngine/ExecutionEngine.cpp | 12 ++++-- lib/ExecutionEngine/Interpreter/Execution.cpp | 41 ++++++++++++++++--- .../Interpreter/ExternalFunctions.cpp | 26 ------------ .../Interpreter/Interpreter.cpp | 20 ++++++--- lib/ExecutionEngine/Interpreter/Interpreter.h | 12 ++++-- lib/ExecutionEngine/JIT/JIT.h | 6 ++- lib/ExecutionEngine/JIT/TargetSelect.cpp | 7 ++-- 7 files changed, 74 insertions(+), 50 deletions(-) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index bb52c943111..45643abca9d 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -17,6 +17,7 @@ #include "JIT/JIT.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/Module.h" #include "llvm/ModuleProvider.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" @@ -105,20 +106,23 @@ int ExecutionEngine::runFunctionAsMain(Function *Fn, /// NULL is returned. /// ExecutionEngine *ExecutionEngine::create(ModuleProvider *MP, - bool ForceInterpreter) { + bool ForceInterpreter, + IntrinsicLowering *IL) { ExecutionEngine *EE = 0; - // Unless the interpreter was explicitly selected, make a JIT. + // Unless the interpreter was explicitly selected, try making a JIT. if (!ForceInterpreter) - EE = JIT::create(MP); + EE = JIT::create(MP, IL); // If we can't make a JIT, make an interpreter instead. try { if (EE == 0) - EE = Interpreter::create(MP->materializeModule()); + EE = Interpreter::create(MP->materializeModule(), IL); } catch (...) { EE = 0; } + + if (EE == 0) delete IL; return EE; } diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index abade5f857a..bec4b7b9056 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -12,11 +12,12 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "interpreter" - #include "Interpreter.h" -#include "llvm/Instructions.h" -#include "llvm/DerivedTypes.h" #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/IntrinsicLowering.h" +#include "llvm/Intrinsics.h" #include "llvm/Support/GetElementPtrTypeIterator.h" #include "Support/Statistic.h" #include "Support/Debug.h" @@ -25,15 +26,15 @@ using namespace llvm; namespace { Statistic<> NumDynamicInsts("lli", "Number of dynamic instructions executed"); -} -namespace llvm { Interpreter *TheEE = 0; } + //===----------------------------------------------------------------------===// // Value Manipulation code //===----------------------------------------------------------------------===// + static GenericValue executeAddInst(GenericValue Src1, GenericValue Src2, const Type *Ty); static GenericValue executeSubInst(GenericValue Src1, GenericValue Src2, @@ -764,6 +765,36 @@ void Interpreter::visitStoreInst(StoreInst &I) { void Interpreter::visitCallSite(CallSite CS) { ExecutionContext &SF = ECStack.back(); + + // Check to see if this is an intrinsic function call... + if (Function *F = CS.getCalledFunction()) + switch (F->getIntrinsicID()) { + case Intrinsic::va_start: // va_start: implemented by getFirstVarArg() + SetValue(CS.getInstruction(), getFirstVarArg(), SF); + return; + case Intrinsic::va_end: // va_end is a noop for the interpreter + return; + case Intrinsic::va_copy: // va_copy: dest = src + SetValue(CS.getInstruction(), getOperandValue(*CS.arg_begin(), SF), SF); + return; + default: + // If it is an unknown intrinsic function, using the intrinsic lowering + // class to transform it into hopefully tasty LLVM code. + // + Instruction *Prev = CS.getInstruction()->getPrev(); + BasicBlock *Parent = CS.getInstruction()->getParent(); + IL->LowerIntrinsicCall(cast(CS.getInstruction())); + + // Restore the CurInst pointer to the first instruction newly inserted, if + // any. + if (!Prev) { + SF.CurInst = Parent->begin(); + } else { + SF.CurInst = Prev; + ++SF.CurInst; + } + } + SF.Caller = CS; std::vector ArgVals; const unsigned NumArgs = SF.Caller.arg_size(); diff --git a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index 8cde5fe535c..1fe0c01275d 100644 --- a/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -676,28 +676,6 @@ GenericValue lle_X_fprintf(FunctionType *M, const vector &Args) { return GV; } -//===----------------------------------------------------------------------===// -// LLVM Intrinsic Functions... -//===----------------------------------------------------------------------===// - -// llvm.va_start() - Implement the va_start operation... -GenericValue llvm_va_start(FunctionType *F, const vector &Args) { - assert(Args.size() == 0); - return TheInterpreter->getFirstVarArg(); -} - -// void llvm.va_end( *) - Implement the va_end operation... -GenericValue llvm_va_end(FunctionType *F, const vector &Args) { - assert(Args.size() == 1); - return GenericValue(); // Noop! -} - -// llvm.va_copy() - Implement the va_copy operation... -GenericValue llvm_va_copy(FunctionType *F, const vector &Args) { - assert(Args.size() == 1); - return Args[0]; -} - } // End extern "C" @@ -749,9 +727,5 @@ void Interpreter::initializeExternalFunctions() { FuncNames["lle_X_ungetc"] = lle_X_ungetc; FuncNames["lle_X_fprintf"] = lle_X_fprintf; FuncNames["lle_X_freopen"] = lle_X_freopen; - - FuncNames["lle_X_llvm.va_start"]= llvm_va_start; - FuncNames["lle_X_llvm.va_end"] = llvm_va_end; - FuncNames["lle_X_llvm.va_copy"] = llvm_va_copy; } diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.cpp b/lib/ExecutionEngine/Interpreter/Interpreter.cpp index 77c008730ff..46e5ef0b6ac 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.cpp +++ b/lib/ExecutionEngine/Interpreter/Interpreter.cpp @@ -14,13 +14,14 @@ //===----------------------------------------------------------------------===// #include "Interpreter.h" -#include "llvm/Module.h" +#include "llvm/IntrinsicLowering.h" #include "llvm/DerivedTypes.h" +#include "llvm/Module.h" using namespace llvm; /// create - Create a new interpreter object. This can never fail. /// -ExecutionEngine *Interpreter::create(Module *M){ +ExecutionEngine *Interpreter::create(Module *M, IntrinsicLowering *IL) { bool isLittleEndian = false; switch (M->getEndianness()) { case Module::LittleEndian: isLittleEndian = true; break; @@ -41,22 +42,29 @@ ExecutionEngine *Interpreter::create(Module *M){ break; } - return new Interpreter(M, isLittleEndian, isLongPointer); + return new Interpreter(M, isLittleEndian, isLongPointer, IL); } //===----------------------------------------------------------------------===// // Interpreter ctor - Initialize stuff // -Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer) - : ExecutionEngine(M), ExitCode(0), +Interpreter::Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, + IntrinsicLowering *il) + : ExecutionEngine(M), ExitCode(0), TD("lli", isLittleEndian, isLongPointer ? 8 : 4, isLongPointer ? 8 : 4, - isLongPointer ? 8 : 4) { + isLongPointer ? 8 : 4), IL(il) { setTargetData(TD); // Initialize the "backend" initializeExecutionEngine(); initializeExternalFunctions(); emitGlobals(); + + if (IL == 0) IL = new DefaultIntrinsicLowering(); +} + +Interpreter::~Interpreter() { + delete IL; } void Interpreter::runAtExitHandlers () { diff --git a/lib/ExecutionEngine/Interpreter/Interpreter.h b/lib/ExecutionEngine/Interpreter/Interpreter.h index 1f50777351f..5757327c208 100644 --- a/lib/ExecutionEngine/Interpreter/Interpreter.h +++ b/lib/ExecutionEngine/Interpreter/Interpreter.h @@ -79,6 +79,7 @@ struct ExecutionContext { class Interpreter : public ExecutionEngine, public InstVisitor { int ExitCode; // The exit code to be returned by the lli util TargetData TD; + IntrinsicLowering *IL; // The runtime stack of executing code. The top of the stack is the current // function record. @@ -89,17 +90,20 @@ class Interpreter : public ExecutionEngine, public InstVisitor { std::vector AtExitHandlers; public: - Interpreter(Module *M, bool isLittleEndian, bool isLongPointer); - inline ~Interpreter() { } + Interpreter(Module *M, bool isLittleEndian, bool isLongPointer, + IntrinsicLowering *IL); + ~Interpreter(); /// runAtExitHandlers - Run any functions registered by the program's calls to /// atexit(3), which we intercept and store in AtExitHandlers. /// void runAtExitHandlers(); - /// create - Create an interpreter ExecutionEngine. This can never fail. + /// create - Create an interpreter ExecutionEngine. This can never fail. The + /// specified IntrinsicLowering implementation will be deleted when the + /// Interpreter execution engine is destroyed. /// - static ExecutionEngine *create(Module *M); + static ExecutionEngine *create(Module *M, IntrinsicLowering *IL); /// run - Start execution with the specified function and arguments. /// diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index 53e8738bb84..414d1c6e683 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -44,9 +44,11 @@ public: ~JIT(); /// create - Create an return a new JIT compiler if there is one available - /// for the current target. Otherwise, return null. + /// for the current target. Otherwise, return null. If the JIT is created + /// successfully, it takes responsibility for deleting the specified + /// IntrinsicLowering implementation. /// - static ExecutionEngine *create(ModuleProvider *MP); + static ExecutionEngine *create(ModuleProvider *MP, IntrinsicLowering *IL = 0); /// run - Start execution with the specified function and arguments. /// diff --git a/lib/ExecutionEngine/JIT/TargetSelect.cpp b/lib/ExecutionEngine/JIT/TargetSelect.cpp index 4a381fb5a2d..05408628703 100644 --- a/lib/ExecutionEngine/JIT/TargetSelect.cpp +++ b/lib/ExecutionEngine/JIT/TargetSelect.cpp @@ -53,8 +53,9 @@ namespace { /// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// -ExecutionEngine *JIT::create(ModuleProvider *MP) { - TargetMachine* (*TargetMachineAllocator)(const Module &) = 0; +ExecutionEngine *JIT::create(ModuleProvider *MP, IntrinsicLowering *IL) { + TargetMachine* (*TargetMachineAllocator)(const Module &, + IntrinsicLowering *IL) = 0; // Allow a command-line switch to override what *should* be the default target // machine for this platform. This allows for debugging a Sparc JIT on X86 -- @@ -80,7 +81,7 @@ ExecutionEngine *JIT::create(ModuleProvider *MP) { #endif // Allocate a target... - TargetMachine *Target = TargetMachineAllocator(*MP->getModule()); + TargetMachine *Target = TargetMachineAllocator(*MP->getModule(), IL); assert(Target && "Could not allocate target machine!"); // If the target supports JIT code generation, return a new JIT now. -- 2.34.1