blob: 5a3245b91b60e8f30f5d42194c46c61f9ed5efa7 [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
Misha Brukman4e8c9992003-06-06 06:59:55 +000014// FIXME: REMOVE THIS
15#include "llvm/PassManager.h"
16
Misha Brukmanabb027c2003-05-27 21:40:39 +000017namespace {
18 cl::opt<std::string>
19 Arch("march", cl::desc("Architecture: `x86' or `sparc'"), cl::Prefix,
20 cl::value_desc("machine architecture"));
21
22 static std::string DefaultArch =
23#if defined(i386) || defined(__i386__) || defined(__x86__)
24 "x86";
25#elif defined(sparc) || defined(__sparc__) || defined(__sparcv9)
26 "sparc";
27#else
28 "";
29#endif
Misha Brukmanabb027c2003-05-27 21:40:39 +000030}
Chris Lattnerbd199fb2002-12-24 00:01:05 +000031
Chris Lattnerbd199fb2002-12-24 00:01:05 +000032/// createJIT - Create an return a new JIT compiler if there is one available
33/// for the current target. Otherwise it returns null.
34///
35ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) {
Misha Brukmanabb027c2003-05-27 21:40:39 +000036
37 TargetMachine* (*TargetMachineAllocator)(unsigned) = 0;
38 if (Arch == "")
39 Arch = DefaultArch;
Chris Lattnerbd199fb2002-12-24 00:01:05 +000040
Misha Brukmanabb027c2003-05-27 21:40:39 +000041 // Allow a command-line switch to override what *should* be the default target
42 // machine for this platform. This allows for debugging a Sparc JIT on X86 --
43 // our X86 machines are much faster at recompiling LLVM and linking lli.
44 if (Arch == "x86") {
45 TargetMachineAllocator = allocateX86TargetMachine;
Chris Lattner7aefa962003-06-17 15:32:38 +000046#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
Misha Brukmanabb027c2003-05-27 21:40:39 +000047 } else if (Arch == "sparc") {
Misha Brukman906f5fa2003-06-02 03:23:16 +000048 TargetMachineAllocator = allocateSparcTargetMachine;
Chris Lattner7aefa962003-06-17 15:32:38 +000049#endif
Misha Brukmanabb027c2003-05-27 21:40:39 +000050 }
51
52 if (TargetMachineAllocator) {
53 // Allocate a target...
54 TargetMachine *Target = (*TargetMachineAllocator)(Config);
55 assert(Target && "Could not allocate target machine!");
56
57 // Create the virtual machine object...
58 return new VM(M, Target);
59 } else {
60 return 0;
61 }
Chris Lattnerbd199fb2002-12-24 00:01:05 +000062}
63
64VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) {
65 setTargetData(TM.getTargetData());
Misha Brukmanabb027c2003-05-27 21:40:39 +000066
67 // Initialize MCE
Misha Brukman906f5fa2003-06-02 03:23:16 +000068 MCE = createEmitter(*this);
Misha Brukmanabb027c2003-05-27 21:40:39 +000069
Chris Lattnerbd199fb2002-12-24 00:01:05 +000070 setupPassManager();
Misha Brukman4e8c9992003-06-06 06:59:55 +000071
Chris Lattner7aefa962003-06-17 15:32:38 +000072#if defined(sparc) || defined(__sparc__) || defined(__sparcv9)
Misha Brukman4e8c9992003-06-06 06:59:55 +000073 // THIS GOES BEYOND UGLY HACKS
74 if (TM.getName() == "UltraSparc-Native") {
75 extern Pass *createPreSelectionPass(TargetMachine &TM);
76 PassManager PM;
77 // Specialize LLVM code for this target machine and then
78 // run basic dataflow optimizations on LLVM code.
79 PM.add(createPreSelectionPass(TM));
80 PM.run(*M);
81 }
Chris Lattner7aefa962003-06-17 15:32:38 +000082#endif
Misha Brukman4e8c9992003-06-06 06:59:55 +000083
Chris Lattner56adf152003-05-12 02:14:34 +000084 emitGlobals();
Chris Lattnerbd199fb2002-12-24 00:01:05 +000085}
86
87int VM::run(const std::string &FnName, const std::vector<std::string> &Args) {
88 Function *F = getModule().getNamedFunction(FnName);
89 if (F == 0) {
90 std::cerr << "Could not find function '" << FnName <<"' in module!\n";
91 return 1;
92 }
93
94 int(*PF)(int, char**) = (int(*)(int, char**))getPointerToFunction(F);
95 assert(PF != 0 && "Null pointer to function?");
96
97 // Build an argv vector...
98 char **Argv = (char**)CreateArgv(Args);
99
100 // Call the main function...
Chris Lattner22080f92003-05-14 13:53:40 +0000101 int Result = PF(Args.size(), Argv);
102
103 // Run any atexit handlers now!
104 runAtExitHandlers();
105 return Result;
Chris Lattnerbd199fb2002-12-24 00:01:05 +0000106}