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