blob: d4726f0d35b5e442ed61178457cc5f8266ee9a36 [file] [log] [blame]
Chris Lattnerbd199fb2002-12-24 00:01:05 +00001//===-- 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 Brukmanabb027c2003-05-27 21:40:39 +000012#include "Support/CommandLine.h"
13
John Criswell69582b32003-08-21 21:12:30 +000014#include "Config/stdlib.h"
15
Misha Brukman4e8c9992003-06-06 06:59:55 +000016// FIXME: REMOVE THIS
17#include "llvm/PassManager.h"
18
Misha Brukman82742912003-07-02 17:53:19 +000019#if !defined(ENABLE_X86_JIT) && !defined(ENABLE_SPARC_JIT)
20#define NO_JITS_ENABLED
21#endif
Chris Lattner97ac14f2003-06-17 15:43:13 +000022
Misha Brukman82742912003-07-02 17:53:19 +000023namespace {
24 enum ArchName { x86, Sparc };
25
26#ifndef NO_JITS_ENABLED
Chris Lattner97ac14f2003-06-17 15:43:13 +000027 cl::opt<ArchName>
28 Arch("march", cl::desc("Architecture to JIT to:"), cl::Prefix,
Misha Brukman82742912003-07-02 17:53:19 +000029 cl::values(
30#ifdef ENABLE_X86_JIT
31 clEnumVal(x86, " IA-32 (Pentium and above)"),
32#endif
33#ifdef ENABLE_SPARC_JIT
Chris Lattnerde3209b2003-06-17 15:54:02 +000034 clEnumValN(Sparc, "sparc", " Sparc-V9"),
Misha Brukmanabb027c2003-05-27 21:40:39 +000035#endif
Chris Lattner97ac14f2003-06-17 15:43:13 +000036 0),
Misha Brukman82742912003-07-02 17:53:19 +000037#if defined(ENABLE_X86_JIT)
Chris Lattner97ac14f2003-06-17 15:43:13 +000038 cl::init(x86)
Misha Brukman82742912003-07-02 17:53:19 +000039#elif defined(ENABLE_SPARC_JIT)
Chris Lattnerde3209b2003-06-17 15:54:02 +000040 cl::init(Sparc)
Chris Lattner97ac14f2003-06-17 15:43:13 +000041#endif
42 );
Misha Brukman82742912003-07-02 17:53:19 +000043#endif /* NO_JITS_ENABLED */
Misha Brukmanabb027c2003-05-27 21:40:39 +000044}
Chris Lattnerbd199fb2002-12-24 00:01:05 +000045
Chris Lattnerbd199fb2002-12-24 00:01:05 +000046/// createJIT - Create an return a new JIT compiler if there is one available
47/// for the current target. Otherwise it returns null.
48///
49ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) {
Misha Brukmanabb027c2003-05-27 21:40:39 +000050
51 TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
Chris Lattnerbd199fb2002-12-24 00:01:05 +000052
Misha Brukmanabb027c2003-05-27 21:40:39 +000053 // 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 Brukman82742912003-07-02 17:53:19 +000055 // our X86 machines are much faster at recompiling LLVM and linking LLI.
56#ifdef NO_JITS_ENABLED
57 return 0;
58#endif
59
Chris Lattner97ac14f2003-06-17 15:43:13 +000060 switch (Arch) {
Misha Brukman82742912003-07-02 17:53:19 +000061#ifdef ENABLE_X86_JIT
Chris Lattner97ac14f2003-06-17 15:43:13 +000062 case x86:
Misha Brukmanabb027c2003-05-27 21:40:39 +000063 TargetMachineAllocator = allocateX86TargetMachine;
Chris Lattner97ac14f2003-06-17 15:43:13 +000064 break;
Misha Brukman82742912003-07-02 17:53:19 +000065#endif
66#ifdef ENABLE_SPARC_JIT
Chris Lattnerde3209b2003-06-17 15:54:02 +000067 case Sparc:
Misha Brukman906f5fa2003-06-02 03:23:16 +000068 TargetMachineAllocator = allocateSparcTargetMachine;
Chris Lattner97ac14f2003-06-17 15:43:13 +000069 break;
Chris Lattner7aefa962003-06-17 15:32:38 +000070#endif
Chris Lattner97ac14f2003-06-17 15:43:13 +000071 default:
72 assert(0 && "-march flag not supported on this host!");
Misha Brukmanabb027c2003-05-27 21:40:39 +000073 }
Chris Lattner97ac14f2003-06-17 15:43:13 +000074
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 Lattnerbd199fb2002-12-24 00:01:05 +000081}
82
83VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) {
84 setTargetData(TM.getTargetData());
Misha Brukmanabb027c2003-05-27 21:40:39 +000085
86 // Initialize MCE
Misha Brukman906f5fa2003-06-02 03:23:16 +000087 MCE = createEmitter(*this);
Misha Brukmanabb027c2003-05-27 21:40:39 +000088
Chris Lattnerbd199fb2002-12-24 00:01:05 +000089 setupPassManager();
Misha Brukman4e8c9992003-06-06 06:59:55 +000090
Misha Brukman82742912003-07-02 17:53:19 +000091#ifdef ENABLE_SPARC_JIT
Misha Brukman4e8c9992003-06-06 06:59:55 +000092 // 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 Lattner7aefa962003-06-17 15:32:38 +0000101#endif
Misha Brukman4e8c9992003-06-06 06:59:55 +0000102
Chris Lattner56adf152003-05-12 02:14:34 +0000103 emitGlobals();
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000104}
105
John Criswell69582b32003-08-21 21:12:30 +0000106//
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//
126int VM::run(const std::string &FnName,
127 const std::vector<std::string> &Args,
128 const char ** envp) {
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000129 Function *F = getModule().getNamedFunction(FnName);
130 if (F == 0) {
Chris Lattnera84983e2003-07-23 20:21:06 +0000131 std::cerr << "Could not find function '" << FnName << "' in module!\n";
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000132 return 1;
133 }
134
John Criswell69582b32003-08-21 21:12:30 +0000135 int(*PF)(int, char**, const char**) = (int(*)(int, char**, const char**))getPointerToFunction(F);
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000136 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 Criswell69582b32003-08-21 21:12:30 +0000142 int Result = PF(Args.size(), Argv, envp);
Chris Lattner22080f92003-05-14 13:53:40 +0000143
144 // Run any atexit handlers now!
145 runAtExitHandlers();
146 return Result;
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000147}