From fe11a97fcde7c63109c3ad36570657807d0cd6ef Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 23 Dec 2002 23:59:41 +0000 Subject: Substantial changes to refactor LLI to incorporate both the Jello JIT and the traditional LLI interpreter git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5125 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/Makefile | 6 ++- tools/lli/lli.cpp | 134 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 80 insertions(+), 60 deletions(-) (limited to 'tools/lli') diff --git a/tools/lli/Makefile b/tools/lli/Makefile index a0e73d7150..c31fb5e2da 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -1,6 +1,10 @@ LEVEL = ../.. TOOLNAME = lli -USEDLIBS = bcreader vmcore analysis.a support.a target.a transforms.a +PARALLEL_DIRS = Interpreter JIT + +JITLIBS = lli-jit codegen x86 scalaropts.a +USEDLIBS = lli-interpreter $(JITLIBS) bcreader vmcore analysis.a support.a target.a +#transforms.a # Have gcc tell the linker to export symbols from the program so that # dynamically loaded modules can be linked against them. diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 3f718e599e..be6ed11794 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -1,85 +1,101 @@ -//===----------------------------------------------------------------------===// -// LLVM INTERPRETER/DEBUGGER/PROFILER UTILITY +//===- lli.cpp - LLVM Interpreter / Dynamic compiler ----------------------===// // -// This utility is an interactive frontend to almost all other LLVM -// functionality. It may be used as an interpreter to run code, a debugger to -// find problems, or a profiler to analyze execution frequencies. +// This utility provides a way to execute LLVM bytecode without static +// compilation. This consists of a very simple and slow (but portable) +// interpreter, along with capability for system specific dynamic compilers. At +// runtime, the fastest (stable) execution engine is selected to run the +// program. This means the JIT compiler for the current platform if it's +// available. // //===----------------------------------------------------------------------===// -#include "Interpreter.h" +#include "ExecutionEngine.h" #include "Support/CommandLine.h" +#include "llvm/Bytecode/Reader.h" +#include "llvm/Module.h" +#include "llvm/Target/TargetMachineImpls.h" -static cl::opt -InputFile(cl::desc(""), cl::Positional, cl::init("-")); - -static cl::list -InputArgv(cl::ConsumeAfter, cl::desc("...")); +namespace { + cl::opt + InputFile(cl::desc(""), cl::Positional, cl::init("-")); -static cl::opt -MainFunction ("f", cl::desc("Function to execute"), cl::init("main"), - cl::value_desc("function name")); + cl::list + InputArgv(cl::ConsumeAfter, cl::desc("...")); -static cl::opt -DebugMode("d", cl::desc("Start program in debugger")); + cl::opt + MainFunction ("f", cl::desc("Function to execute"), cl::init("main"), + cl::value_desc("function name")); -static cl::opt -TraceMode("trace", cl::desc("Enable Tracing")); + cl::opt DebugMode("d", cl::desc("Start program in debugger")); -static cl::opt -ProfileMode("profile", cl::desc("Enable Profiling [unimp]")); + cl::opt TraceMode("trace", cl::desc("Enable Tracing")); + cl::opt ForceInterpreter("force-interpreter", + cl::desc("Force interpretation: disable JIT"), + cl::init(true)); +} //===----------------------------------------------------------------------===// -// Interpreter ctor - Initialize stuff +// ExecutionEngine Class Implementation // -Interpreter::Interpreter() : ExitCode(0), Profile(ProfileMode), - Trace(TraceMode), CurFrame(-1) { - CurMod = 0; - loadModule(InputFile); - - // Initialize the "backend" - initializeExecutionEngine(); - initializeExternalMethods(); + +ExecutionEngine::~ExecutionEngine() { + delete &CurMod; } //===----------------------------------------------------------------------===// // main Driver function // int main(int argc, char** argv) { - cl::ParseCommandLineOptions(argc, argv, " llvm interpreter\n"); + cl::ParseCommandLineOptions(argc, argv, + " llvm interpreter & dynamic compiler\n"); + + // Load the bytecode... + string ErrorMsg; + Module *M = ParseBytecodeFile(InputFile, &ErrorMsg); + if (M == 0) { + cout << "Error parsing '" << InputFile << "': " + << ErrorMsg << "\n"; + exit(1); + } + +#if 0 + // Link in the runtime library for LLI... + string RuntimeLib = getCurrentExecutablePath(); + if (!RuntimeLib.empty()) RuntimeLib += "/"; + RuntimeLib += "RuntimeLib.bc"; + + if (Module *SupportLib = ParseBytecodeFile(RuntimeLib, &ErrorMsg)) { + if (LinkModules(M, SupportLib, &ErrorMsg)) + std::cerr << "Error Linking runtime library into current module: " + << ErrorMsg << "\n"; + } else { + std::cerr << "Error loading runtime library '"+RuntimeLib+"': " + << ErrorMsg << "\n"; + } +#endif + + // FIXME: This should look at the PointerSize and endianness of the bytecode + // file to determine the endianness and pointer size of target machine to use. + unsigned Config = TM::PtrSize64 | TM::BigEndian; + + ExecutionEngine *EE = 0; + + // If there is nothing that is forcing us to use the interpreter, make a JIT. + if (!ForceInterpreter && !DebugMode && !TraceMode) + EE = ExecutionEngine::createJIT(M, Config); + + // If we can't make a JIT, make an interpreter instead. + if (EE == 0) + EE = ExecutionEngine::createInterpreter(M, Config, DebugMode, TraceMode); // Add the module name to the start of the argv vector... - // InputArgv.insert(InputArgv.begin(), InputFile); - // Create the interpreter... - Interpreter I; - - // Handle alternate names of the program. If started as llp, enable profiling - // if started as ldb, enable debugging... - // - if (argv[0] == "ldb") // TODO: Obviously incorrect, but you get the idea - DebugMode = true; - else if (argv[0] == "llp") - ProfileMode = true; - - // If running with the profiler, enable it now... - if (ProfileMode) I.enableProfiling(); - if (TraceMode) I.enableTracing(); - - // Start interpreter into the main function... - // - if (!I.callMainMethod(MainFunction, InputArgv) && !DebugMode) { - // If not in debug mode and if the call succeeded, run the code now... - I.run(); - } - - // If debug mode, allow the user to interact... also, if the user pressed - // ctrl-c or execution hit an error, enter the event loop... - if (DebugMode || I.isStopped()) - I.handleUserInput(); + // Run the main function! + int ExitCode = EE->run(MainFunction, InputArgv); - // Return the status code of the program executed... - return I.getExitCode(); + // Now that we are done executing the program, shut down the execution engine + delete EE; + return ExitCode; } -- cgit v1.2.3