JIT.cpp revision 39c07264da992fd5d37fa7eaac0b9f02f55f80d0
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 1782742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#if !defined(ENABLE_X86_JIT) && !defined(ENABLE_SPARC_JIT) 1882742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#define NO_JITS_ENABLED 1982742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#endif 2082742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman 21abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukmannamespace { 2282742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman enum ArchName { x86, Sparc }; 2397ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 2482742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifndef NO_JITS_ENABLED 2597ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::opt<ArchName> 2697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix, 2782742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman cl::values( 2882742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef ENABLE_X86_JIT 2982742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman clEnumVal(x86, " IA-32 (Pentium and above)"), 3082742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#endif 3182742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef ENABLE_SPARC_JIT 32de3209bfdbb5b26198af8e6f30684bc50eb39ab6Chris Lattner clEnumValN(Sparc, "sparc", " Sparc-V9"), 3397ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner#endif 3497ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 0), 3582742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#if defined(ENABLE_X86_JIT) 3697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner cl::init(x86) 3782742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#elif defined(ENABLE_SPARC_JIT) 38de3209bfdbb5b26198af8e6f30684bc50eb39ab6Chris Lattner cl::init(Sparc) 39abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman#endif 4097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner ); 4182742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#endif /* NO_JITS_ENABLED */ 42abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman} 43bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 44bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// createJIT - Create an return a new JIT compiler if there is one available 45bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// for the current target. Otherwise it returns null. 46bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner/// 4739c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris LattnerExecutionEngine *ExecutionEngine::createJIT(Module *M) { 48abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 4939c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner TargetMachine* (*TargetMachineAllocator)(const Module &) = 0; 50abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 51abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Allow a command-line switch to override what *should* be the default target 52abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // machine for this platform. This allows for debugging a Sparc JIT on X86 -- 5382742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman // our X86 machines are much faster at recompiling LLVM and linking LLI. 5482742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef NO_JITS_ENABLED 5582742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman return 0; 5682742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#endif 5782742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman 5897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner switch (Arch) { 5982742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef ENABLE_X86_JIT 6097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner case x86: 61abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman TargetMachineAllocator = allocateX86TargetMachine; 6297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner break; 6382742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#endif 6482742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef ENABLE_SPARC_JIT 65de3209bfdbb5b26198af8e6f30684bc50eb39ab6Chris Lattner case Sparc: 66906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman TargetMachineAllocator = allocateSparcTargetMachine; 6797ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner break; 687aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 6997ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner default: 7097ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner assert(0 && "-march flag not supported on this host!"); 71abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman } 7297ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 7397ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner // Allocate a target... 7439c07264da992fd5d37fa7eaac0b9f02f55f80d0Chris Lattner TargetMachine *Target = TargetMachineAllocator(*M); 7597ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner assert(Target && "Could not allocate target machine!"); 7697ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner 7797ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner // Create the virtual machine object... 7897ac14f33cc8fed7f34cb8c7199ef42be124de7eChris Lattner return new VM(M, Target); 79bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 80bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 81bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris LattnerVM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) { 82bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setTargetData(TM.getTargetData()); 83abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 84abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman // Initialize MCE 85906f5fa5c8bb790201c79a33ea6d906f9f57f827Misha Brukman MCE = createEmitter(*this); 86abb027cf412944db4d27579ba3ae00717d23c25eMisha Brukman 87bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner setupPassManager(); 884e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 8982742916f30b09b878d1ad9d95005389c23b02c6Misha Brukman#ifdef ENABLE_SPARC_JIT 904e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // THIS GOES BEYOND UGLY HACKS 914e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman if (TM.getName() == "UltraSparc-Native") { 924e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman extern Pass *createPreSelectionPass(TargetMachine &TM); 934e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PassManager PM; 944e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // Specialize LLVM code for this target machine and then 954e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman // run basic dataflow optimizations on LLVM code. 964e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.add(createPreSelectionPass(TM)); 974e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman PM.run(*M); 984e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman } 997aefa966cdeaf054922de341a1e36b4fceee08ceChris Lattner#endif 1004e8c999518361ceafd2f816e29f76284c7f8a210Misha Brukman 10156adf152f6354a9b5609e059050fd2315ad5960cChris Lattner emitGlobals(); 102bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 103bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 10405a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// VM::run - This method begins the execution of a program beginning at the 10505a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// specified function name. The function is called with the specified 10605a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// arguments and array of environment variables (a la main()). 10705a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// 10805a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// Inputs: 10905a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// FnName - The name of the function as a C++ string. 11005a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// Args - A vector of C++ strings containing the arguments. 11105a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// envp - An array of C strings containing the environment. 11205a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// 11305a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// Return value: 11405a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// 1 - An error occurred. 11505a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// Otherwise, the return value from the specified function is returned. 11605a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner/// 11705a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattnerint VM::run(const std::string &FnName, const std::vector<std::string> &Args, 11805a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner const char **envp) { 119bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner Function *F = getModule().getNamedFunction(FnName); 120bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner if (F == 0) { 121a84983ea72ca5569585a4f321e2bb89cf78d6d9cChris Lattner std::cerr << "Could not find function '" << FnName << "' in module!\n"; 122bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner return 1; 123bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner } 124bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 12505a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner int (*PF)(int, char**, const char**) = 12605a1a306bcfba2b533dc1210d24924e5f3e9ed0eChris Lattner (int(*)(int, char**, const char**))getPointerToFunction(F); 127bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner assert(PF != 0 && "Null pointer to function?"); 128bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 129bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Build an argv vector... 130bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner char **Argv = (char**)CreateArgv(Args); 131bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 132bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner // Call the main function... 13369582b35b6aa4e48cbbad7f6f1193c967da96b25John Criswell int Result = PF(Args.size(), Argv, envp); 13422080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner 13522080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner // Run any atexit handlers now! 13622080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner runAtExitHandlers(); 13722080f9f168b0129d0ed3a2a29a145e17723c3baChris Lattner return Result; 138bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 139