JIT.cpp revision 7aefa966cdeaf054922de341a1e36b4fceee08ce
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 { 18abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman cl::opt<std::string> 19abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman Arch("march", cl::desc("Architecture: `x86' or `sparc'"), cl::Prefix, 20abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman cl::value_desc("machine architecture")); 21abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 22abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman static std::string DefaultArch = 23abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#if defined(i386) || defined(__i386__) || defined(__x86__) 24abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman "x86"; 25abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9) 26abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman "sparc"; 27abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#else 28abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman ""; 29abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#endif 30abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman} 31bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 32bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// createJIT - Create an return a new JIT compiler if there is one available 33bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// for the current target. Otherwise it returns null. 34bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// 35bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris LattnerExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) { 36abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 37abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachine* (*TargetMachineAllocator)(unsigned) = 0; 38abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman if (Arch == "") 39abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman Arch = DefaultArch; 40abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 41abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Allow a command-line switch to override what *should* be the default target 42abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // machine for this platform. This allows for debugging a Sparc JIT on X86 -- 43abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // our X86 machines are much faster at recompiling LLVM and linking lli. 44abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman if (Arch == "x86") { 45abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachineAllocator = allocateX86TargetMachine; 467aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 47abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } else if (Arch == "sparc") { 48906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman TargetMachineAllocator = allocateSparcTargetMachine; 497aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 50abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } 51abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 52abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman if (TargetMachineAllocator) { 53abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Allocate a target... 54abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachine *Target = (*TargetMachineAllocator)(Config); 55abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman assert(Target && "Could not allocate target machine!"); 56bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 57abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Create the virtual machine object... 58abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman return new VM(M, Target); 59abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } else { 60abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman return 0; 61abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } 62bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 63bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 64bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris LattnerVM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) { 65bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setTargetData(TM.getTargetData()); 66abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 67abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Initialize MCE 68906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman MCE = createEmitter(*this); 69abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 70bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setupPassManager(); 714e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 727aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#if defined(sparc) || defined(__sparc__) || defined(__sparcv9) 734e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // THIS GOES BEYOND UGLY HACKS 744e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman if (TM.getName() == "UltraSparc-Native") { 754e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman extern Pass *createPreSelectionPass(TargetMachine &TM); 764e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PassManager PM; 774e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // Specialize LLVM code for this target machine and then 784e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // run basic dataflow optimizations on LLVM code. 794e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.add(createPreSelectionPass(TM)); 804e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.run(*M); 814e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman } 827aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 834e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 8456adf152f6354a9b5609e059050fd2315ad5960cChris Lattner emitGlobals(); 85bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 86bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 87bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattnerint VM::run(const std::string &FnName, const std::vector<std::string> &Args) { 88bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner Function *F = getModule().getNamedFunction(FnName); 89bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner if (F == 0) { 90bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner std::cerr << "Could not find function '" << FnName <<"' in module!\n"; 91bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner return 1; 92bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner } 93bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 94bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner int(*PF)(int, char**) = (int(*)(int, char**))getPointerToFunction(F); 95bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner assert(PF != 0 && "Null pointer to function?"); 96bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 97bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Build an argv vector... 98bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner char **Argv = (char**)CreateArgv(Args); 99bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 100bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Call the main function... 10122080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner int Result = PF(Args.size(), Argv); 10222080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner 10322080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner // Run any atexit handlers now! 10422080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner runAtExitHandlers(); 10522080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner return Result; 106bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 107