JIT.cpp revision 97ac14f33cc8fed7f34cb8c7199ef42be124de7e
1bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===// 2bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 3bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// This file implements the top-level support for creating a Just-In-Time 4bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// compiler for the current architecture. 5bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 6bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===// 7bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 8bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "VM.h" 9bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "llvm/Target/TargetMachine.h" 10bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "llvm/Target/TargetMachineImpls.h" 11bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "llvm/Module.h" 12abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#include "Support/CommandLine.h" 13abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 144e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman// FIXME: REMOVE THIS 154e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman#include "llvm/PassManager.h" 164e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 17abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukmannamespace { 1897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner enum ArchName { nojit, x86, sparc }; 1997ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 2097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::opt<ArchName> 2197ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix, 2297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::values(clEnumVal(x86, " IA-32 (pentium and above)"), 2397ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 2497ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner clEnumVal(sparc, " Sparc-V9"), 2597ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner#endif 2697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 0), 27abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#if defined(i386) || defined(__i386__) || defined(__x86__) 2897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::init(x86) 29abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9) 3097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::init(sparc) 31abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#else 3297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::init(nojit) 33abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#endif 3497ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner ); 35abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman} 36bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 37bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// createJIT - Create an return a new JIT compiler if there is one available 38bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// for the current target. Otherwise it returns null. 39bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// 40bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris LattnerExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) { 41abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 42abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachine* (*TargetMachineAllocator)(unsigned) = 0; 43abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 44abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Allow a command-line switch to override what *should* be the default target 45abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // machine for this platform. This allows for debugging a Sparc JIT on X86 -- 46abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // our X86 machines are much faster at recompiling LLVM and linking lli. 4797ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner switch (Arch) { 4897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner case x86: 49abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachineAllocator = allocateX86TargetMachine; 5097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner break; 517aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 5297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner case sparc: 53906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman TargetMachineAllocator = allocateSparcTargetMachine; 5497ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner break; 557aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 5697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner default: 5797ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner assert(0 && "-march flag not supported on this host!"); 5897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner case nojit: 59abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman return 0; 60abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } 6197ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 6297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner // Allocate a target... 6397ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner TargetMachine *Target = (*TargetMachineAllocator)(Config); 6497ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner assert(Target && "Could not allocate target machine!"); 6597ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 6697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner // Create the virtual machine object... 6797ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner return new VM(M, Target); 68bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 69bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 70bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris LattnerVM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) { 71bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setTargetData(TM.getTargetData()); 72abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 73abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Initialize MCE 74906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman MCE = createEmitter(*this); 75abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 76bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setupPassManager(); 774e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 787aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 794e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // THIS GOES BEYOND UGLY HACKS 804e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman if (TM.getName() == "UltraSparc-Native") { 814e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman extern Pass *createPreSelectionPass(TargetMachine &TM); 824e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PassManager PM; 834e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // Specialize LLVM code for this target machine and then 844e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // run basic dataflow optimizations on LLVM code. 854e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.add(createPreSelectionPass(TM)); 864e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.run(*M); 874e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman } 887aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 894e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 9056adf152f6354a9b5609e059050fd2315ad5960cChris Lattner emitGlobals(); 91bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 92bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 93bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattnerint VM::run(const std::string &FnName, const std::vector<std::string> &Args) { 94bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner Function *F = getModule().getNamedFunction(FnName); 95bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner if (F == 0) { 96bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner std::cerr << "Could not find function '" << FnName <<"' in module!\n"; 97bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner return 1; 98bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner } 99bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 100bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner int(*PF)(int, char**) = (int(*)(int, char**))getPointerToFunction(F); 101bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner assert(PF != 0 && "Null pointer to function?"); 102bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 103bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Build an argv vector... 104bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner char **Argv = (char**)CreateArgv(Args); 105bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 106bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Call the main function... 10722080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner int Result = PF(Args.size(), Argv); 10822080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner 10922080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner // Run any atexit handlers now! 11022080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner runAtExitHandlers(); 11122080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner return Result; 112bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 113