Allow for specification of which JIT to run on the commandline.
[oota-llvm.git] / lib / ExecutionEngine / JIT / JITEmitter.cpp
1 //===-- Emitter.cpp - Write machine code to executable memory -------------===//
2 //
3 // This file defines a MachineCodeEmitter object that is used by Jello to write
4 // machine code to memory and remember where relocatable values lie.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "VM.h"
9 #include "llvm/CodeGen/MachineCodeEmitter.h"
10 #include "llvm/CodeGen/MachineFunction.h"
11 #include "llvm/CodeGen/MachineConstantPool.h"
12 #include "llvm/Target/TargetData.h"
13 #include "llvm/Function.h"
14 #include "Support/Statistic.h"
15
16 namespace {
17   Statistic<> NumBytes("jello", "Number of bytes of machine code compiled");
18
19   class Emitter : public MachineCodeEmitter {
20     VM &TheVM;
21
22     unsigned char *CurBlock, *CurByte;
23
24     // When outputting a function stub in the context of some other function, we
25     // save CurBlock and CurByte here.
26     unsigned char *SavedCurBlock, *SavedCurByte;
27     
28     std::vector<std::pair<BasicBlock*, unsigned *> > BBRefs;
29     std::map<BasicBlock*, unsigned> BBLocations;
30     std::vector<void*> ConstantPoolAddresses;
31   public:
32     Emitter(VM &vm) : TheVM(vm) {}
33
34     virtual void startFunction(MachineFunction &F);
35     virtual void finishFunction(MachineFunction &F);
36     virtual void emitConstantPool(MachineConstantPool *MCP);
37     virtual void startBasicBlock(MachineBasicBlock &BB);
38     virtual void startFunctionStub(const Function &F, unsigned StubSize);
39     virtual void* finishFunctionStub(const Function &F);
40     virtual void emitByte(unsigned char B);
41     virtual void emitPCRelativeDisp(Value *V);
42     virtual void emitGlobalAddress(GlobalValue *V, bool isPCRelative);
43     virtual void emitGlobalAddress(const std::string &Name, bool isPCRelative);
44     virtual void emitFunctionConstantValueAddress(unsigned ConstantNum,
45                                                   int Offset);
46   private:
47     void emitAddress(void *Addr, bool isPCRelative);
48   };
49 }
50
51 MachineCodeEmitter *VM::createX86Emitter(VM &V) {
52   return new Emitter(V);
53 }
54
55
56 #define _POSIX_MAPPED_FILES
57 #include <unistd.h>
58 #include <sys/mman.h>
59
60 // FIXME: This should be rewritten to support a real memory manager for
61 // executable memory pages!
62 static void *getMemory(unsigned NumPages) {
63   return mmap(0, 4096*NumPages, PROT_READ|PROT_WRITE|PROT_EXEC,
64               MAP_PRIVATE|MAP_ANONYMOUS, 0, 0);
65 }
66
67
68 void Emitter::startFunction(MachineFunction &F) {
69   CurBlock = (unsigned char *)getMemory(8);
70   CurByte = CurBlock;  // Start writing at the beginning of the fn.
71   TheVM.addGlobalMapping(F.getFunction(), CurBlock);
72 }
73
74 void Emitter::finishFunction(MachineFunction &F) {
75   ConstantPoolAddresses.clear();
76   for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) {
77     unsigned Location = BBLocations[BBRefs[i].first];
78     unsigned *Ref = BBRefs[i].second;
79     *Ref = Location-(unsigned)(intptr_t)Ref-4;
80   }
81   BBRefs.clear();
82   BBLocations.clear();
83
84   NumBytes += CurByte-CurBlock;
85
86   DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
87                   << (unsigned)(intptr_t)CurBlock
88                   << std::dec << "] Function: " << F.getFunction()->getName()
89                   << ": " << CurByte-CurBlock << " bytes of text\n");
90 }
91
92 void Emitter::emitConstantPool(MachineConstantPool *MCP) {
93   const std::vector<Constant*> &Constants = MCP->getConstants();
94   for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
95     // For now we just allocate some memory on the heap, this can be
96     // dramatically improved.
97     const Type *Ty = ((Value*)Constants[i])->getType();
98     void *Addr = malloc(TheVM.getTargetData().getTypeSize(Ty));
99     TheVM.InitializeMemory(Constants[i], Addr);
100     ConstantPoolAddresses.push_back(Addr);
101   }
102 }
103
104
105 void Emitter::startBasicBlock(MachineBasicBlock &BB) {
106   BBLocations[BB.getBasicBlock()] = (unsigned)(intptr_t)CurByte;
107 }
108
109
110 void Emitter::startFunctionStub(const Function &F, unsigned StubSize) {
111   SavedCurBlock = CurBlock;  SavedCurByte = CurByte;
112   // FIXME: this is a huge waste of memory.
113   CurBlock = (unsigned char *)getMemory((StubSize+4095)/4096);
114   CurByte = CurBlock;  // Start writing at the beginning of the fn.
115 }
116
117 void *Emitter::finishFunctionStub(const Function &F) {
118   NumBytes += CurByte-CurBlock;
119   DEBUG(std::cerr << "Finished CodeGen of [0x" << std::hex
120                   << (unsigned)(intptr_t)CurBlock
121                   << std::dec << "] Function stub for: " << F.getName()
122                   << ": " << CurByte-CurBlock << " bytes of text\n");
123   std::swap(CurBlock, SavedCurBlock);
124   CurByte = SavedCurByte;
125   return SavedCurBlock;
126 }
127
128 void Emitter::emitByte(unsigned char B) {
129   *CurByte++ = B;   // Write the byte to memory
130 }
131
132
133 // emitPCRelativeDisp - For functions, just output a displacement that will
134 // cause a reference to the zero page, which will cause a seg-fault, causing
135 // things to get resolved on demand.  Keep track of these markers.
136 //
137 // For basic block references, keep track of where the references are so they
138 // may be patched up when the basic block is defined.
139 //
140 void Emitter::emitPCRelativeDisp(Value *V) {
141   BasicBlock *BB = cast<BasicBlock>(V);     // Keep track of reference...
142   BBRefs.push_back(std::make_pair(BB, (unsigned*)CurByte));
143   CurByte += 4;
144 }
145
146 // emitAddress - Emit an address in either direct or PCRelative form...
147 //
148 void Emitter::emitAddress(void *Addr, bool isPCRelative) {
149   if (isPCRelative) {
150     *(intptr_t*)CurByte = (intptr_t)Addr - (intptr_t)CurByte-4;
151   } else {
152     *(void**)CurByte = Addr;
153   }
154   CurByte += 4;
155 }
156
157 void Emitter::emitGlobalAddress(GlobalValue *V, bool isPCRelative) {
158   if (isPCRelative) { // must be a call, this is a major hack!
159     // Try looking up the function to see if it is already compiled!
160     if (void *Addr = TheVM.getPointerToGlobalIfAvailable(V)) {
161       emitAddress(Addr, isPCRelative);
162     } else {  // Function has not yet been code generated!
163       TheVM.addFunctionRef(CurByte, cast<Function>(V));
164
165       // Delayed resolution...
166       emitAddress((void*)VM::CompilationCallback, isPCRelative);
167     }
168   } else {
169     emitAddress(TheVM.getPointerToGlobal(V), isPCRelative);
170   }
171 }
172
173 void Emitter::emitGlobalAddress(const std::string &Name, bool isPCRelative) {
174   emitAddress(TheVM.getPointerToNamedFunction(Name), isPCRelative);
175 }
176
177 void Emitter::emitFunctionConstantValueAddress(unsigned ConstantNum,
178                                                int Offset) {
179   assert(ConstantNum < ConstantPoolAddresses.size() &&
180          "Invalid ConstantPoolIndex!");
181   *(void**)CurByte = (char*)ConstantPoolAddresses[ConstantNum]+Offset;
182   CurByte += 4;
183 }