| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 1 | //===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===// | 
|  | 2 | // | 
|  | 3 | // This file implements the top-level support for creating a Just-In-Time | 
|  | 4 | // compiler for the current architecture. | 
|  | 5 | // | 
|  | 6 | //===----------------------------------------------------------------------===// | 
|  | 7 |  | 
|  | 8 | #include "VM.h" | 
|  | 9 | #include "llvm/Target/TargetMachine.h" | 
|  | 10 | #include "llvm/Target/TargetMachineImpls.h" | 
|  | 11 | #include "llvm/Module.h" | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 12 | #include "Support/CommandLine.h" | 
|  | 13 |  | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 14 | // FIXME: REMOVE THIS | 
|  | 15 | #include "llvm/PassManager.h" | 
|  | 16 |  | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 17 | namespace { | 
|  | 18 | cl::opt<std::string> | 
|  | 19 | Arch("march", cl::desc("Architecture: `x86' or `sparc'"), cl::Prefix, | 
|  | 20 | cl::value_desc("machine architecture")); | 
|  | 21 |  | 
|  | 22 | static std::string DefaultArch = | 
|  | 23 | #if defined(i386) || defined(__i386__) || defined(__x86__) | 
|  | 24 | "x86"; | 
|  | 25 | #elif defined(sparc) || defined(__sparc__) || defined(__sparcv9) | 
|  | 26 | "sparc"; | 
|  | 27 | #else | 
|  | 28 | ""; | 
|  | 29 | #endif | 
|  | 30 |  | 
|  | 31 | } | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 32 |  | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 33 | /// createJIT - Create an return a new JIT compiler if there is one available | 
|  | 34 | /// for the current target.  Otherwise it returns null. | 
|  | 35 | /// | 
|  | 36 | ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) { | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 37 |  | 
|  | 38 | TargetMachine* (*TargetMachineAllocator)(unsigned) = 0; | 
|  | 39 | if (Arch == "") | 
|  | 40 | Arch = DefaultArch; | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 41 |  | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 42 | // Allow a command-line switch to override what *should* be the default target | 
|  | 43 | // machine for this platform. This allows for debugging a Sparc JIT on X86 -- | 
|  | 44 | // our X86 machines are much faster at recompiling LLVM and linking lli. | 
|  | 45 | if (Arch == "x86") { | 
|  | 46 | TargetMachineAllocator = allocateX86TargetMachine; | 
|  | 47 | } else if (Arch == "sparc") { | 
| Misha Brukman | 906f5fa | 2003-06-02 03:23:16 +0000 | [diff] [blame] | 48 | TargetMachineAllocator = allocateSparcTargetMachine; | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 49 | } | 
|  | 50 |  | 
|  | 51 | if (TargetMachineAllocator) { | 
|  | 52 | // Allocate a target... | 
|  | 53 | TargetMachine *Target = (*TargetMachineAllocator)(Config); | 
|  | 54 | assert(Target && "Could not allocate target machine!"); | 
|  | 55 |  | 
|  | 56 | // Create the virtual machine object... | 
|  | 57 | return new VM(M, Target); | 
|  | 58 | } else { | 
|  | 59 | return 0; | 
|  | 60 | } | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 61 | } | 
|  | 62 |  | 
|  | 63 | VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) { | 
|  | 64 | setTargetData(TM.getTargetData()); | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 65 |  | 
|  | 66 | // Initialize MCE | 
| Misha Brukman | 906f5fa | 2003-06-02 03:23:16 +0000 | [diff] [blame] | 67 | MCE = createEmitter(*this); | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 68 |  | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 69 | setupPassManager(); | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 70 |  | 
|  | 71 | // THIS GOES BEYOND UGLY HACKS | 
|  | 72 | if (TM.getName() == "UltraSparc-Native") { | 
|  | 73 | extern Pass *createPreSelectionPass(TargetMachine &TM); | 
|  | 74 | PassManager PM; | 
|  | 75 | // Specialize LLVM code for this target machine and then | 
|  | 76 | // run basic dataflow optimizations on LLVM code. | 
|  | 77 | PM.add(createPreSelectionPass(TM)); | 
|  | 78 | PM.run(*M); | 
|  | 79 | } | 
|  | 80 |  | 
| Chris Lattner | 56adf15 | 2003-05-12 02:14:34 +0000 | [diff] [blame] | 81 | emitGlobals(); | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 82 | } | 
|  | 83 |  | 
|  | 84 | int VM::run(const std::string &FnName, const std::vector<std::string> &Args) { | 
|  | 85 | Function *F = getModule().getNamedFunction(FnName); | 
|  | 86 | if (F == 0) { | 
|  | 87 | std::cerr << "Could not find function '" << FnName <<"' in module!\n"; | 
|  | 88 | return 1; | 
|  | 89 | } | 
|  | 90 |  | 
|  | 91 | int(*PF)(int, char**) = (int(*)(int, char**))getPointerToFunction(F); | 
|  | 92 | assert(PF != 0 && "Null pointer to function?"); | 
|  | 93 |  | 
|  | 94 | // Build an argv vector... | 
|  | 95 | char **Argv = (char**)CreateArgv(Args); | 
|  | 96 |  | 
|  | 97 | // Call the main function... | 
| Chris Lattner | 22080f9 | 2003-05-14 13:53:40 +0000 | [diff] [blame] | 98 | int Result = PF(Args.size(), Argv); | 
|  | 99 |  | 
|  | 100 | // Run any atexit handlers now! | 
|  | 101 | runAtExitHandlers(); | 
|  | 102 | return Result; | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 103 | } |