llvm.org GIT mirror llvm / bd199fb
Initial checkin of new LLI with JIT compiler git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@5126 91177308-0d34-0410-b5e6-96231b3b80d8 Chris Lattner 17 years ago
11 changed file(s) with 722 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 //===- ExecutionEngine.h - Abstract Execution Engine Interface --*- C++ -*-===//
1 //
2 // This file defines the abstract interface that implements execution support
3 // for LLVM.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #ifndef EXECUTION_ENGINE_H
8 #define EXECUTION_ENGINE_H
9
10 #include
11 #include
12 #include
13 class Constant;
14 class Type;
15 class GlobalValue;
16 class Function;
17 class Module;
18 class TargetData;
19 union GenericValue;
20
21 class ExecutionEngine {
22 Module &CurMod;
23 const TargetData *TD;
24
25 protected:
26 // GlobalAddress - A mapping between LLVM global values and their actualized
27 // version...
28 std::map GlobalAddress;
29
30 void setTargetData(const TargetData &td) {
31 TD = &td;
32 emitGlobals();
33 }
34 public:
35 ExecutionEngine(Module *M) : CurMod(*M) {
36 assert(M && "Module is null?");
37 }
38 virtual ~ExecutionEngine();
39
40 Module &getModule() const { return CurMod; }
41 const TargetData &getTargetData() const { return *TD; }
42
43 /// run - Start execution with the specified function and arguments.
44 ///
45 virtual int run(const std::string &FnName,
46 const std::vector &Args) = 0;
47
48 /// createJIT - Create an return a new JIT compiler if there is one available
49 /// for the current target. Otherwise it returns null.
50 ///
51 static ExecutionEngine *createJIT(Module *M, unsigned Config);
52
53 /// createInterpreter - Create a new interpreter object. This can never fail.
54 ///
55 static ExecutionEngine *createInterpreter(Module *M, unsigned Config,
56 bool DebugMode, bool TraceMode);
57
58 void addGlobalMapping(const Function *F, void *Addr) {
59 void *&CurVal = GlobalAddress[(const GlobalValue*)F];
60 assert(CurVal == 0 && "GlobalMapping already established!");
61 CurVal = Addr;
62 }
63
64 // getPointerToGlobal - This returns the address of the specified global
65 // value. This may involve code generation if it's a function.
66 //
67 void *getPointerToGlobal(const GlobalValue *GV);
68
69 // getPointerToFunction - The different EE's represent function bodies in
70 // different ways. They should each implement this to say what a function
71 // pointer should look like.
72 //
73 virtual void *getPointerToFunction(const Function *F) = 0;
74
75 private:
76 void emitGlobals();
77
78 public: // FIXME: protected: // API shared among subclasses
79 GenericValue getConstantValue(const Constant *C);
80 void StoreValueToMemory(GenericValue Val, GenericValue *Ptr, const Type *Ty);
81 void *CreateArgv(const std::vector &InputArgv);
82 void InitializeMemory(const Constant *Init, void *Addr);
83 };
84
85 #endif
0 //===-- GenericValue.h - Represent any type of LLVM value -------*- C++ -*-===//
1 //
2 // The GenericValue class is used to represent an LLVM value of arbitrary type.
3 //
4 //===----------------------------------------------------------------------===//
5
6
7 #ifndef GENERIC_VALUE_H
8 #define GENERIC_VALUE_H
9
10 #include "Support/DataTypes.h"
11
12 typedef uint64_t PointerTy;
13
14 union GenericValue {
15 bool BoolVal;
16 unsigned char UByteVal;
17 signed char SByteVal;
18 unsigned short UShortVal;
19 signed short ShortVal;
20 unsigned int UIntVal;
21 signed int IntVal;
22 uint64_t ULongVal;
23 int64_t LongVal;
24 double DoubleVal;
25 float FloatVal;
26 PointerTy PointerVal;
27 unsigned char Untyped[8];
28
29 GenericValue() {}
30 GenericValue(void *V) {
31 PointerVal = (PointerTy)(intptr_t)V;
32 }
33 };
34
35 inline GenericValue PTOGV(void *P) { return GenericValue(P); }
36 inline void* GVTOP(const GenericValue &GV) {
37 return (void*)(intptr_t)GV.PointerVal;
38 }
39 #endif
0 //===-- ExecutionEngine.cpp - Common Implementation shared by EE's --------===//
1 //
2 // This file defines the common interface used by the various execution engine
3 // subclasses.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "ExecutionEngine.h"
8 #include "GenericValue.h"
9 #include "llvm/DerivedTypes.h"
10 #include "llvm/Constants.h"
11 #include "llvm/Module.h"
12 #include "llvm/Target/TargetData.h"
13 #include "Support/Statistic.h"
14
15 Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized");
16
17 // getPointerToGlobal - This returns the address of the specified global
18 // value. This may involve code generation if it's a function.
19 //
20 void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
21 if (const Function *F = dyn_cast(GV))
22 return getPointerToFunction(F);
23
24 assert(GlobalAddress[GV] && "Global hasn't had an address allocated yet?");
25 return GlobalAddress[GV];
26 }
27
28
29 GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
30 GenericValue Result;
31 #define GET_CONST_VAL(TY, CLASS) \
32 case Type::TY##TyID: Result.TY##Val = cast(C)->getValue(); break
33
34 switch (C->getType()->getPrimitiveID()) {
35 GET_CONST_VAL(Bool , ConstantBool);
36 GET_CONST_VAL(UByte , ConstantUInt);
37 GET_CONST_VAL(SByte , ConstantSInt);
38 GET_CONST_VAL(UShort , ConstantUInt);
39 GET_CONST_VAL(Short , ConstantSInt);
40 GET_CONST_VAL(UInt , ConstantUInt);
41 GET_CONST_VAL(Int , ConstantSInt);
42 GET_CONST_VAL(ULong , ConstantUInt);
43 GET_CONST_VAL(Long , ConstantSInt);
44 GET_CONST_VAL(Float , ConstantFP);
45 GET_CONST_VAL(Double , ConstantFP);
46 #undef GET_CONST_VAL
47 case Type::PointerTyID:
48 if (isa(C)) {
49 Result.PointerVal = 0;
50 } else if (const ConstantPointerRef *CPR = dyn_cast(C)){
51 Result = PTOGV(getPointerToGlobal(CPR->getValue()));
52
53 } else {
54 assert(0 && "Unknown constant pointer type!");
55 }
56 break;
57 default:
58 cout << "ERROR: Constant unimp for type: " << C->getType() << "\n";
59 }
60 return Result;
61 }
62
63 void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
64 const Type *Ty) {
65 if (getTargetData().isLittleEndian()) {
66 switch (Ty->getPrimitiveID()) {
67 case Type::BoolTyID:
68 case Type::UByteTyID:
69 case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break;
70 case Type::UShortTyID:
71 case Type::ShortTyID: Ptr->Untyped[0] = Val.UShortVal & 255;
72 Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255;
73 break;
74 case Type::FloatTyID:
75 case Type::UIntTyID:
76 case Type::IntTyID: Ptr->Untyped[0] = Val.UIntVal & 255;
77 Ptr->Untyped[1] = (Val.UIntVal >> 8) & 255;
78 Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255;
79 Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255;
80 break;
81 case Type::DoubleTyID:
82 case Type::ULongTyID:
83 case Type::LongTyID:
84 case Type::PointerTyID: Ptr->Untyped[0] = Val.ULongVal & 255;
85 Ptr->Untyped[1] = (Val.ULongVal >> 8) & 255;
86 Ptr->Untyped[2] = (Val.ULongVal >> 16) & 255;
87 Ptr->Untyped[3] = (Val.ULongVal >> 24) & 255;
88 Ptr->Untyped[4] = (Val.ULongVal >> 32) & 255;
89 Ptr->Untyped[5] = (Val.ULongVal >> 40) & 255;
90 Ptr->Untyped[6] = (Val.ULongVal >> 48) & 255;
91 Ptr->Untyped[7] = (Val.ULongVal >> 56) & 255;
92 break;
93 default:
94 cout << "Cannot store value of type " << Ty << "!\n";
95 }
96 } else {
97 switch (Ty->getPrimitiveID()) {
98 case Type::BoolTyID:
99 case Type::UByteTyID:
100 case Type::SByteTyID: Ptr->Untyped[0] = Val.UByteVal; break;
101 case Type::UShortTyID:
102 case Type::ShortTyID: Ptr->Untyped[1] = Val.UShortVal & 255;
103 Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255;
104 break;
105 case Type::FloatTyID:
106 case Type::UIntTyID:
107 case Type::IntTyID: Ptr->Untyped[3] = Val.UIntVal & 255;
108 Ptr->Untyped[2] = (Val.UIntVal >> 8) & 255;
109 Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255;
110 Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255;
111 break;
112 case Type::DoubleTyID:
113 case Type::ULongTyID:
114 case Type::LongTyID:
115 case Type::PointerTyID: Ptr->Untyped[7] = Val.ULongVal & 255;
116 Ptr->Untyped[6] = (Val.ULongVal >> 8) & 255;
117 Ptr->Untyped[5] = (Val.ULongVal >> 16) & 255;
118 Ptr->Untyped[4] = (Val.ULongVal >> 24) & 255;
119 Ptr->Untyped[3] = (Val.ULongVal >> 32) & 255;
120 Ptr->Untyped[2] = (Val.ULongVal >> 40) & 255;
121 Ptr->Untyped[1] = (Val.ULongVal >> 48) & 255;
122 Ptr->Untyped[0] = (Val.ULongVal >> 56) & 255;
123 break;
124 default:
125 cout << "Cannot store value of type " << Ty << "!\n";
126 }
127 }
128 }
129
130 // InitializeMemory - Recursive function to apply a Constant value into the
131 // specified memory location...
132 //
133 void ExecutionEngine::InitializeMemory(const Constant *Init, void *Addr) {
134 if (Init->getType()->isFirstClassType()) {
135 GenericValue Val = getConstantValue(Init);
136 StoreValueToMemory(Val, (GenericValue*)Addr, Init->getType());
137 return;
138 }
139
140 switch (Init->getType()->getPrimitiveID()) {
141 case Type::ArrayTyID: {
142 const ConstantArray *CPA = cast(Init);
143 const vector &Val = CPA->getValues();
144 unsigned ElementSize =
145 getTargetData().getTypeSize(cast(CPA->getType())->getElementType());
146 for (unsigned i = 0; i < Val.size(); ++i)
147 InitializeMemory(cast(Val[i].get()), (char*)Addr+i*ElementSize);
148 return;
149 }
150
151 case Type::StructTyID: {
152 const ConstantStruct *CPS = cast(Init);
153 const StructLayout *SL =
154 getTargetData().getStructLayout(cast(CPS->getType()));
155 const vector &Val = CPS->getValues();
156 for (unsigned i = 0; i < Val.size(); ++i)
157 InitializeMemory(cast(Val[i].get()),
158 (char*)Addr+SL->MemberOffsets[i]);
159 return;
160 }
161
162 default:
163 std::cerr << "Bad Type: " << Init->getType() << "\n";
164 assert(0 && "Unknown constant type to initialize memory with!");
165 }
166 }
167
168
169
170 void *ExecutionEngine::CreateArgv(const std::vector &InputArgv) {
171 // Pointers are 64 bits...
172 PointerTy *Result = new PointerTy[InputArgv.size()+1]; // 64 bit assumption
173 DEBUG(std::cerr << "ARGV = " << (void*)Result << "\n");
174
175 for (unsigned i = 0; i < InputArgv.size(); ++i) {
176 unsigned Size = InputArgv[i].size()+1;
177 char *Dest = new char[Size];
178 DEBUG(std::cerr << "ARGV[" << i << "] = " << (void*)Dest << "\n");
179
180 copy(InputArgv[i].begin(), InputArgv[i].end(), Dest);
181 Dest[Size-1] = 0;
182
183 // Endian safe: Result[i] = (PointerTy)Dest;
184 StoreValueToMemory(PTOGV(Dest), (GenericValue*)(Result+i),
185 Type::LongTy); // 64 bit assumption
186 }
187
188 Result[InputArgv.size()] = 0;
189 return Result;
190 }
191
192 /// EmitGlobals - Emit all of the global variables to memory, storing their
193 /// addresses into GlobalAddress. This must make sure to copy the contents of
194 /// their initializers into the memory.
195 ///
196 void ExecutionEngine::emitGlobals() {
197 const TargetData &TD = getTargetData();
198
199 // Loop over all of the global variables in the program, allocating the memory
200 // to hold them.
201 for (Module::giterator I = getModule().gbegin(), E = getModule().gend();
202 I != E; ++I)
203 if (!I->isExternal()) {
204 // Get the type of the global...
205 const Type *Ty = I->getType()->getElementType();
206
207 // Allocate some memory for it!
208 unsigned Size = TD.getTypeSize(Ty);
209 GlobalAddress[I] = new char[Size];
210 NumInitBytes += Size;
211
212 DEBUG(std::cerr << "Global '" << I->getName() << "' -> "
213 << (void*)GlobalAddress[I] << "\n");
214 } else {
215 assert(0 && "References to external globals not handled yet!");
216 }
217
218 // Now that all of the globals are set up in memory, loop through them all and
219 // initialize their contents.
220 for (Module::giterator I = getModule().gbegin(), E = getModule().gend();
221 I != E; ++I)
222 if (!I->isExternal())
223 InitializeMemory(I->getInitializer(), GlobalAddress[I]);
224 }
225
0 //===- Interpreter.cpp - Top-Level LLVM Interpreter Implementation --------===//
1 //
2 // This file implements the top-level functionality for the LLVM interpreter.
3 // This interpreter is designed to be a very simple, portable, inefficient
4 // interpreter.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "Interpreter.h"
9 #include "llvm/Target/TargetMachineImpls.h"
10
11 /// createInterpreter - Create a new interpreter object. This can never fail.
12 ///
13 ExecutionEngine *ExecutionEngine::createInterpreter(Module *M,
14 unsigned Config,
15 bool DebugMode,
16 bool TraceMode) {
17 return new Interpreter(M, Config, DebugMode, TraceMode);
18 }
19
20 //===----------------------------------------------------------------------===//
21 // Interpreter ctor - Initialize stuff
22 //
23 Interpreter::Interpreter(Module *M, unsigned Config,
24 bool DebugMode, bool TraceMode)
25 : ExecutionEngine(M), ExitCode(0), Debug(DebugMode), Trace(TraceMode),
26 CurFrame(-1), TD("lli", (Config & TM::EndianMask) == TM::LittleEndian,
27 1, 4,
28 (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4,
29 (Config & TM::PtrSizeMask) == TM::PtrSize64 ? 8 : 4) {
30
31 setTargetData(TD);
32 // Initialize the "backend"
33 initializeExecutionEngine();
34 initializeExternalMethods();
35 CW.setModule(M); // Update Writer
36 }
37
38 /// run - Start execution with the specified function and arguments.
39 ///
40 int Interpreter::run(const std::string &MainFunction,
41 const std::vector &Args) {
42 // Start interpreter into the main function...
43 //
44 if (!callMainMethod(MainFunction, Args) && !Debug) {
45 // If not in debug mode and if the call succeeded, run the code now...
46 run();
47 }
48
49 // If debug mode, allow the user to interact... also, if the user pressed
50 // ctrl-c or execution hit an error, enter the event loop...
51 if (Debug || isStopped())
52 handleUserInput();
53 return ExitCode;
54 }
55
0 LEVEL = ../../..
1 LIBRARYNAME = lli-interpreter
2
3 include $(LEVEL)/Makefile.common
0 //===-- Callback.cpp - Trap handler for function resolution ---------------===//
1 //
2 // This file defines the SIGSEGV handler which is invoked when a reference to a
3 // non-codegen'd function is found.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "VM.h"
8 #include "Support/Statistic.h"
9 #include
10 #include
11 #include
12
13 static VM *TheVM = 0;
14
15 static void TrapHandler(int TN, siginfo_t *SI, ucontext_t *ucp) {
16 assert(TN == SIGSEGV && "Should be SIGSEGV!");
17
18 #ifdef REG_EIP /* this code does not compile on Sparc! */
19 if (SI->si_code != SEGV_MAPERR || SI->si_addr != 0 ||
20 ucp->uc_mcontext.gregs[REG_EIP] != 0) {
21 std::cerr << "Bad SEGV encountered!\n";
22 abort();
23 }
24
25 // The call instruction should have pushed the return value onto the stack...
26 unsigned RefAddr = *(unsigned*)ucp->uc_mcontext.gregs[REG_ESP];
27 RefAddr -= 4; // Backtrack to the reference itself...
28
29 DEBUG(std::cerr << "In SEGV handler! Addr=0x" << std::hex << RefAddr
30 << " ESP=0x" << ucp->uc_mcontext.gregs[REG_ESP] << std::dec
31 << ": Resolving call to function: "
32 << TheVM->getFunctionReferencedName((void*)RefAddr) << "\n");
33
34 // Sanity check to make sure this really is a call instruction...
35 assert(((unsigned char*)RefAddr)[-1] == 0xE8 && "Not a call instr!");
36
37 unsigned NewVal = (unsigned)TheVM->resolveFunctionReference((void*)RefAddr);
38
39 // Rewrite the call target... so that we don't fault every time we execute
40 // the call.
41 *(unsigned*)RefAddr = NewVal-RefAddr-4;
42
43 // Change the instruction pointer to be the real target of the call...
44 ucp->uc_mcontext.gregs[REG_EIP] = NewVal;
45
46 #endif
47 }
48
49
50 void VM::registerCallback() {
51 TheVM = this;
52
53 // Register the signal handler...
54 struct sigaction SA;
55 SA.sa_sigaction = (void (*)(int, siginfo_t*, void*))TrapHandler;
56 sigfillset(&SA.sa_mask); // Block all signals while codegen'ing
57 SA.sa_flags = SA_NOCLDSTOP|SA_SIGINFO; // Get siginfo
58 sigaction(SIGSEGV, &SA, 0); // Install the handler
59 }
60
61
0 //===-- JIT.cpp - LLVM Just in Time Compiler ------------------------------===//
1 //
2 // This file implements the top-level support for creating a Just-In-Time
3 // compiler for the current architecture.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "VM.h"
8 #include "llvm/Target/TargetMachine.h"
9 #include "llvm/Target/TargetMachineImpls.h"
10 #include "llvm/Module.h"
11
12
13 /// createJIT - Create an return a new JIT compiler if there is one available
14 /// for the current target. Otherwise it returns null.
15 ///
16 ExecutionEngine *ExecutionEngine::createJIT(Module *M, unsigned Config) {
17 // FIXME: This should be controlled by which subdirectory gets linked in!
18 #if !defined(i386) && !defined(__i386__) && !defined(__x86__)
19 return 0;
20 #endif
21 // Allocate a target... in the future this will be controllable on the
22 // command line.
23 TargetMachine *Target = allocateX86TargetMachine(Config);
24 assert(Target && "Could not allocate X86 target machine!");
25
26 // Create the virtual machine object...
27 return new VM(M, Target);
28 }
29
30 VM::VM(Module *M, TargetMachine *tm) : ExecutionEngine(M), TM(*tm) {
31 setTargetData(TM.getTargetData());
32 MCE = createEmitter(*this); // Initialize MCE
33 setupPassManager();
34 registerCallback();
35 }
36
37 int VM::run(const std::string &FnName, const std::vector &Args) {
38 Function *F = getModule().getNamedFunction(FnName);
39 if (F == 0) {
40 std::cerr << "Could not find function '" << FnName <<"' in module!\n";
41 return 1;
42 }
43
44 int(*PF)(int, char**) = (int(*)(int, char**))getPointerToFunction(F);
45 assert(PF != 0 && "Null pointer to function?");
46
47 // Build an argv vector...
48 char **Argv = (char**)CreateArgv(Args);
49
50 // Call the main function...
51 return PF(Args.size(), Argv);
52 }
0 //===-- Emitter.cpp - Write machine code to executable memory -------------===//
1 //
2 // This file defines a MachineCodeEmitter object that is used by Jello to write
3 // machine code to memory and remember where relocatable values lie.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "VM.h"
8 #include "llvm/CodeGen/MachineCodeEmitter.h"
9 #include "llvm/CodeGen/MachineFunction.h"
10 #include "llvm/Function.h"
11 #include "Support/Statistic.h"
12
13 namespace {
14 Statistic<> NumBytes("jello", "Number of bytes of machine code compiled");
15
16 class Emitter : public MachineCodeEmitter {
17 VM &TheVM;
18
19 unsigned char *CurBlock;
20 unsigned char *CurByte;
21
22 std::vector > BBRefs;
23 std::map BBLocations;
24 public:
25 Emitter(VM &vm) : TheVM(vm) {}
26
27 virtual void startFunction(MachineFunction &F);
28 virtual void finishFunction(MachineFunction &F);
29 virtual void startBasicBlock(MachineBasicBlock &BB);
30 virtual void emitByte(unsigned char B);
31 virtual void emitPCRelativeDisp(Value *V);
32 virtual void emitGlobalAddress(GlobalValue *V);
33 };
34 }
35
36 MachineCodeEmitter *VM::createEmitter(VM &V) {
37 return new Emitter(V);
38 }
39
40
41 #define _POSIX_MAPPED_FILES
42 #include
43 #include
44
45 static void *getMemory() {
46 return mmap(0, 4096*2, PROT_READ|PROT_WRITE|PROT_EXEC,
47 MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
48 }
49
50
51 void Emitter::startFunction(MachineFunction &F) {
52 CurBlock = (unsigned char *)getMemory();
53 CurByte = CurBlock; // Start writing at the beginning of the fn.
54 TheVM.addGlobalMapping(F.getFunction(), CurBlock);
55 }
56
57 void Emitter::finishFunction(MachineFunction &F) {
58 for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
59 unsigned Location = BBLocations[BBRefs[i].first];
60 unsigned *Ref = BBRefs[i].second;
61 *Ref = Location-(unsigned)Ref-4;
62 }
63 BBRefs.clear();
64 BBLocations.clear();
65
66 NumBytes += CurByte-CurBlock;
67
68 DEBUG(std::cerr << "Finished CodeGen of [" << std::hex << (unsigned)CurBlock
69 << std::dec << "] Function: " << F.getFunction()->getName()
70 << ": " << CurByte-CurBlock << " bytes of text\n");
71 }
72
73 void Emitter::startBasicBlock(MachineBasicBlock &BB) {
74 BBLocations[BB.getBasicBlock()] = (unsigned)CurByte;
75 }
76
77
78 void Emitter::emitByte(unsigned char B) {
79 *CurByte++ = B; // Write the byte to memory
80 }
81
82
83 // emitPCRelativeDisp - For functions, just output a displacement that will
84 // cause a reference to the zero page, which will cause a seg-fault, causing
85 // things to get resolved on demand. Keep track of these markers.
86 //
87 // For basic block references, keep track of where the references are so they
88 // may be patched up when the basic block is defined.
89 //
90 void Emitter::emitPCRelativeDisp(Value *V) {
91 if (Function *F = dyn_cast(V)) {
92 TheVM.addFunctionRef(CurByte, F);
93 unsigned ZeroAddr = -(unsigned)CurByte-4; // Calculate displacement to null
94 *(unsigned*)CurByte = ZeroAddr; // 4 byte offset
95 CurByte += 4;
96 } else {
97 BasicBlock *BB = cast(V); // Keep track of reference...
98 BBRefs.push_back(std::make_pair(BB, (unsigned*)CurByte));
99 CurByte += 4;
100 }
101 }
102
103 void Emitter::emitGlobalAddress(GlobalValue *V) {
104 *(void**)CurByte = TheVM.getPointerToGlobal(V);
105 CurByte += 4;
106 }
0 LEVEL = ../../..
1 LIBRARYNAME = lli-jit
2
3 include $(LEVEL)/Makefile.common
0 //===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
1 //
2 // This tool implements a just-in-time compiler for LLVM, allowing direct
3 // execution of LLVM bytecode in an efficient manner.
4 //
5 //===----------------------------------------------------------------------===//
6
7 #include "VM.h"
8 #include "llvm/Target/TargetMachine.h"
9 #include "llvm/CodeGen/MachineCodeEmitter.h"
10 #include "llvm/Function.h"
11 #include // dlsym access
12
13
14 VM::~VM() {
15 delete MCE;
16 delete &TM;
17 }
18
19 /// setupPassManager - Initialize the VM PassManager object with all of the
20 /// passes needed for the target to generate code.
21 ///
22 void VM::setupPassManager() {
23 // Compile LLVM Code down to machine code in the intermediate representation
24 if (TM.addPassesToJITCompile(PM)) {
25 std::cerr << "lli: target '" << TM.getName()
26 << "' doesn't support JIT compilation!\n";
27 abort();
28 }
29
30 // Turn the machine code intermediate representation into bytes in memory that
31 // may be executed.
32 //
33 if (TM.addPassesToEmitMachineCode(PM, *MCE)) {
34 std::cerr << "lli: target '" << TM.getName()
35 << "' doesn't support machine code emission!\n";
36 abort();
37 }
38 }
39
40 void *VM::resolveFunctionReference(void *RefAddr) {
41 Function *F = FunctionRefs[RefAddr];
42 assert(F && "Reference address not known!");
43
44 void *Addr = getPointerToFunction(F);
45 assert(Addr && "Pointer to function unknown!");
46
47 FunctionRefs.erase(RefAddr);
48 return Addr;
49 }
50
51 const std::string &VM::getFunctionReferencedName(void *RefAddr) {
52 return FunctionRefs[RefAddr]->getName();
53 }
54
55 static void NoopFn() {}
56
57 /// getPointerToFunction - This method is used to get the address of the
58 /// specified function, compiling it if neccesary.
59 ///
60 void *VM::getPointerToFunction(const Function *F) {
61 void *&Addr = GlobalAddress[F]; // Function already code gen'd
62 if (Addr) return Addr;
63
64 if (F->isExternal()) {
65 // If it's an external function, look it up in the process image...
66 void *Ptr = dlsym(0, F->getName().c_str());
67 if (Ptr == 0) {
68 std::cerr << "WARNING: Cannot resolve fn '" << F->getName()
69 << "' using a dummy noop function instead!\n";
70 Ptr = (void*)NoopFn;
71 }
72
73 return Addr = Ptr;
74 }
75
76 // JIT all of the functions in the module. Eventually this will JIT functions
77 // on demand. This has the effect of populating all of the non-external
78 // functions into the GlobalAddress table.
79 PM.run(getModule());
80
81 assert(Addr && "Code generation didn't add function to GlobalAddress table!");
82 return Addr;
83 }