| 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 |  | 
| John Criswell | 69582b3 | 2003-08-21 21:12:30 +0000 | [diff] [blame^] | 14 | #include "Config/stdlib.h" | 
 | 15 |  | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 16 | // FIXME: REMOVE THIS | 
 | 17 | #include "llvm/PassManager.h" | 
 | 18 |  | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 19 | #if !defined(ENABLE_X86_JIT) && !defined(ENABLE_SPARC_JIT) | 
 | 20 | #define NO_JITS_ENABLED | 
 | 21 | #endif | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 22 |  | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 23 | namespace { | 
 | 24 |   enum ArchName { x86, Sparc }; | 
 | 25 |  | 
 | 26 | #ifndef NO_JITS_ENABLED | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 27 |   cl::opt<ArchName> | 
 | 28 |   Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix, | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 29 |        cl::values( | 
 | 30 | #ifdef ENABLE_X86_JIT | 
 | 31 |                   clEnumVal(x86, "  IA-32 (Pentium and above)"), | 
 | 32 | #endif | 
 | 33 | #ifdef ENABLE_SPARC_JIT | 
| Chris Lattner | de3209b | 2003-06-17 15:54:02 +0000 | [diff] [blame] | 34 |                   clEnumValN(Sparc, "sparc", "  Sparc-V9"), | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 35 | #endif | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 36 |                   0), | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 37 | #if defined(ENABLE_X86_JIT) | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 38 |   cl::init(x86) | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 39 | #elif defined(ENABLE_SPARC_JIT) | 
| Chris Lattner | de3209b | 2003-06-17 15:54:02 +0000 | [diff] [blame] | 40 |   cl::init(Sparc) | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 41 | #endif | 
 | 42 |        ); | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 43 | #endif /* NO_JITS_ENABLED */ | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 44 | } | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 45 |  | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 46 | /// createJIT - Create an return a new JIT compiler if there is one available | 
 | 47 | /// for the current target.  Otherwise it returns null. | 
 | 48 | /// | 
 | 49 | ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) { | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 50 |    | 
 | 51 |   TargetMachine* (*TargetMachineAllocator)(unsigned) = 0; | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 52 |  | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 53 |   // Allow a command-line switch to override what *should* be the default target | 
 | 54 |   // machine for this platform. This allows for debugging a Sparc JIT on X86 -- | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 55 |   // our X86 machines are much faster at recompiling LLVM and linking LLI. | 
 | 56 | #ifdef NO_JITS_ENABLED | 
 | 57 |   return 0; | 
 | 58 | #endif | 
 | 59 |  | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 60 |   switch (Arch) { | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 61 | #ifdef ENABLE_X86_JIT | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 62 |   case x86: | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 63 |     TargetMachineAllocator = allocateX86TargetMachine; | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 64 |     break; | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 65 | #endif | 
 | 66 | #ifdef ENABLE_SPARC_JIT | 
| Chris Lattner | de3209b | 2003-06-17 15:54:02 +0000 | [diff] [blame] | 67 |   case Sparc: | 
| Misha Brukman | 906f5fa | 2003-06-02 03:23:16 +0000 | [diff] [blame] | 68 |     TargetMachineAllocator = allocateSparcTargetMachine; | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 69 |     break; | 
| Chris Lattner | 7aefa96 | 2003-06-17 15:32:38 +0000 | [diff] [blame] | 70 | #endif | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 71 |   default: | 
 | 72 |     assert(0 && "-march flag not supported on this host!"); | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 73 |   } | 
| Chris Lattner | 97ac14f | 2003-06-17 15:43:13 +0000 | [diff] [blame] | 74 |  | 
 | 75 |   // Allocate a target... | 
 | 76 |   TargetMachine *Target = (*TargetMachineAllocator)(Config); | 
 | 77 |   assert(Target && "Could not allocate target machine!"); | 
 | 78 |    | 
 | 79 |   // Create the virtual machine object... | 
 | 80 |   return new VM(M, Target); | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 81 | } | 
 | 82 |  | 
 | 83 | VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) { | 
 | 84 |   setTargetData(TM.getTargetData()); | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 85 |  | 
 | 86 |   // Initialize MCE | 
| Misha Brukman | 906f5fa | 2003-06-02 03:23:16 +0000 | [diff] [blame] | 87 |   MCE = createEmitter(*this); | 
| Misha Brukman | abb027c | 2003-05-27 21:40:39 +0000 | [diff] [blame] | 88 |  | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 89 |   setupPassManager(); | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 90 |  | 
| Misha Brukman | 8274291 | 2003-07-02 17:53:19 +0000 | [diff] [blame] | 91 | #ifdef ENABLE_SPARC_JIT | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 92 |   // THIS GOES BEYOND UGLY HACKS | 
 | 93 |   if (TM.getName() == "UltraSparc-Native") { | 
 | 94 |     extern Pass *createPreSelectionPass(TargetMachine &TM); | 
 | 95 |     PassManager PM; | 
 | 96 |     // Specialize LLVM code for this target machine and then | 
 | 97 |     // run basic dataflow optimizations on LLVM code. | 
 | 98 |     PM.add(createPreSelectionPass(TM)); | 
 | 99 |     PM.run(*M); | 
 | 100 |   } | 
| Chris Lattner | 7aefa96 | 2003-06-17 15:32:38 +0000 | [diff] [blame] | 101 | #endif | 
| Misha Brukman | 4e8c999 | 2003-06-06 06:59:55 +0000 | [diff] [blame] | 102 |  | 
| Chris Lattner | 56adf15 | 2003-05-12 02:14:34 +0000 | [diff] [blame] | 103 |   emitGlobals(); | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 104 | } | 
 | 105 |  | 
| John Criswell | 69582b3 | 2003-08-21 21:12:30 +0000 | [diff] [blame^] | 106 | // | 
 | 107 | // Method: run() | 
 | 108 | // | 
 | 109 | // Description: | 
 | 110 | //	This method begins the execution of a program beginning at the | 
 | 111 | //	specified function name.  The function is called with the | 
 | 112 | //	specified arguments and array of environment variables (a la main()). | 
 | 113 | // | 
 | 114 | // Inputs: | 
 | 115 | //	FnName - The name of the function as a C++ string. | 
 | 116 | //	Args   - A vector of C++ strings containing the arguments. | 
 | 117 | //	envp   - An array of C strings containing the environment. | 
 | 118 | // | 
 | 119 | // Outputs: | 
 | 120 | //	None. | 
 | 121 | // | 
 | 122 | // Return value: | 
 | 123 | //	1 - An error occurred. | 
 | 124 | //	Otherwise, the return value from the specified function is returned. | 
 | 125 | // | 
 | 126 | int VM::run(const std::string &FnName, | 
 | 127 |             const std::vector<std::string> &Args, | 
 | 128 |             const char ** envp) { | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 129 |   Function *F = getModule().getNamedFunction(FnName); | 
 | 130 |   if (F == 0) { | 
| Chris Lattner | a84983e | 2003-07-23 20:21:06 +0000 | [diff] [blame] | 131 |     std::cerr << "Could not find function '" << FnName << "' in module!\n"; | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 132 |     return 1; | 
 | 133 |   } | 
 | 134 |  | 
| John Criswell | 69582b3 | 2003-08-21 21:12:30 +0000 | [diff] [blame^] | 135 |   int(*PF)(int, char**, const char**) = (int(*)(int, char**, const char**))getPointerToFunction(F); | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 136 |   assert(PF != 0 && "Null pointer to function?"); | 
 | 137 |  | 
 | 138 |   // Build an argv vector... | 
 | 139 |   char **Argv = (char**)CreateArgv(Args); | 
 | 140 |  | 
 | 141 |   // Call the main function... | 
| John Criswell | 69582b3 | 2003-08-21 21:12:30 +0000 | [diff] [blame^] | 142 |   int Result = PF(Args.size(), Argv, envp); | 
| Chris Lattner | 22080f9 | 2003-05-14 13:53:40 +0000 | [diff] [blame] | 143 |  | 
 | 144 |   // Run any atexit handlers now! | 
 | 145 |   runAtExitHandlers(); | 
 | 146 |   return Result; | 
| Chris Lattner | bd199fb | 2002-12-24 00:01:05 +0000 | [diff] [blame] | 147 | } |