blob: f66d4d7b7ea267f3fd4f2a9906d13460afc89b70 [file] [log] [blame]
Chris Lattnerbd199fb2002-12-24 00:01:05 +00001//===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
2//
3// This tool implements a just-in-time compiler for LLVM, allowing direct
4// execution of LLVM bytecode in an efficient manner.
5//
6//===----------------------------------------------------------------------===//
7
8#include "VM.h"
9#include "llvm/Target/TargetMachine.h"
10#include "llvm/CodeGen/MachineCodeEmitter.h"
11#include "llvm/Function.h"
12#include <dlfcn.h> // dlsym access
13
14
15VM::~VM() {
16 delete MCE;
17 delete &TM;
18}
19
20/// setupPassManager - Initialize the VM PassManager object with all of the
21/// passes needed for the target to generate code.
22///
23void VM::setupPassManager() {
24 // Compile LLVM Code down to machine code in the intermediate representation
25 if (TM.addPassesToJITCompile(PM)) {
26 std::cerr << "lli: target '" << TM.getName()
27 << "' doesn't support JIT compilation!\n";
28 abort();
29 }
30
31 // Turn the machine code intermediate representation into bytes in memory that
32 // may be executed.
33 //
34 if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
35 std::cerr << "lli: target '" << TM.getName()
36 << "' doesn't support machine code emission!\n";
37 abort();
38 }
39}
40
41void *VM::resolveFunctionReference(void *RefAddr) {
42 Function *F = FunctionRefs[RefAddr];
43 assert(F && "Reference address not known!");
44
45 void *Addr = getPointerToFunction(F);
46 assert(Addr && "Pointer to function unknown!");
47
48 FunctionRefs.erase(RefAddr);
49 return Addr;
50}
51
52const std::string &VM::getFunctionReferencedName(void *RefAddr) {
53 return FunctionRefs[RefAddr]->getName();
54}
55
56static void NoopFn() {}
57
58/// getPointerToFunction - This method is used to get the address of the
59/// specified function, compiling it if neccesary.
60///
61void *VM::getPointerToFunction(const Function *F) {
62 void *&Addr = GlobalAddress[F]; // Function already code gen'd
63 if (Addr) return Addr;
64
65 if (F->isExternal()) {
66 // If it's an external function, look it up in the process image...
67 void *Ptr = dlsym(0, F->getName().c_str());
68 if (Ptr == 0) {
69 std::cerr << "WARNING: Cannot resolve fn '" << F->getName()
70 << "' using a dummy noop function instead!\n";
71 Ptr = (void*)NoopFn;
72 }
73
74 return Addr = Ptr;
75 }
76
77 // JIT all of the functions in the module. Eventually this will JIT functions
78 // on demand. This has the effect of populating all of the non-external
79 // functions into the GlobalAddress table.
80 PM.run(getModule());
81
82 assert(Addr && "Code generation didn't add function to GlobalAddress table!");
83 return Addr;
84}