• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- CodeEmitter.h - CodeEmitter Class -----------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See external/llvm/LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defines the CodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef BCC_CODEEMITTER_H
15 #define BCC_CODEEMITTER_H
16 
17 #include <bcc/bcc.h>
18 #include <bcc/bcc_assert.h>
19 #include <bcc/bcc_cache.h>
20 #include "ExecutionEngine/bcc_internal.h"
21 
22 #include "Config.h"
23 
24 #include "llvm/ADT/DenseMap.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/StringRef.h"
27 #include "llvm/CodeGen/MachineConstantPool.h"
28 #include "llvm/CodeGen/MachineRelocation.h"
29 #include "llvm/CodeGen/JITCodeEmitter.h"
30 #include "llvm/Support/ValueHandle.h"
31 
32 #include <map>
33 #include <vector>
34 #include <set>
35 
36 #include <stdint.h>
37 
38 namespace llvm {
39   class Constant;
40   class GenericValue;
41   class GlobalVariable;
42   class GlobalValue;
43   class Function;
44   class MachineBasicBlock;
45   class MachineFunction;
46   class MachineJumpTableInfo;
47   class MachineModuleInfo;
48   class MCSymbol;
49   class Target;
50   class TargetData;
51   class TargetJITInfo;
52   class TargetMachine;
53   class Type;
54 }
55 
56 namespace bcc {
57   class CodeMemoryManager;
58   class ScriptCompiled;
59 
60   class CodeEmitter : public llvm::JITCodeEmitter {
61   private:
62     typedef llvm::DenseMap<const llvm::GlobalValue *, void *>
63       GlobalAddressMapTy;
64 
65     typedef llvm::DenseMap<const llvm::Function *, void*>
66       FunctionToLazyStubMapTy;
67 
68     typedef std::map<llvm::AssertingVH<llvm::GlobalValue>, void *>
69       GlobalToIndirectSymMapTy;
70 
71   public:
72     typedef GlobalAddressMapTy::const_iterator global_addresses_const_iterator;
73 
74 
75   private:
76     ScriptCompiled *mpResult;
77 
78     CodeMemoryManager *mpMemMgr;
79 
80     llvm::TargetMachine *mpTargetMachine;
81 
82     // The JITInfo for the target we are compiling to
83     const llvm::Target *mpTarget;
84 
85     llvm::TargetJITInfo *mpTJI;
86 
87     const llvm::TargetData *mpTD;
88 
89 
90     FuncInfo *mpCurEmitFunction;
91 
92     GlobalAddressMapTy mGlobalAddressMap;
93 
94     // This vector is a mapping from MBB ID's to their address. It is filled in
95     // by the StartMachineBasicBlock callback and queried by the
96     // getMachineBasicBlockAddress callback.
97     std::vector<uintptr_t> mMBBLocations;
98 
99     // The constant pool for the current function.
100     llvm::MachineConstantPool *mpConstantPool;
101 
102     // A pointer to the first entry in the constant pool.
103     void *mpConstantPoolBase;
104 
105     // Addresses of individual constant pool entries.
106     llvm::SmallVector<uintptr_t, 8> mConstPoolAddresses;
107 
108     // The jump tables for the current function.
109     llvm::MachineJumpTableInfo *mpJumpTable;
110 
111     // A pointer to the first entry in the jump table.
112     void *mpJumpTableBase;
113 
114     // When outputting a function stub in the context of some other function, we
115     // save BufferBegin/BufferEnd/CurBufferPtr here.
116     uint8_t *mpSavedBufferBegin, *mpSavedBufferEnd, *mpSavedCurBufferPtr;
117 
118     // These are the relocations that the function needs, as emitted.
119     std::vector<llvm::MachineRelocation> mRelocations;
120 
121 #if 0
122     std::vector<oBCCRelocEntry> mCachingRelocations;
123 #endif
124 
125     // This vector is a mapping from Label ID's to their address.
126     llvm::DenseMap<llvm::MCSymbol*, uintptr_t> mLabelLocations;
127 
128     // Machine module info for exception informations
129     llvm::MachineModuleInfo *mpMMI;
130 
131 
132     FunctionToLazyStubMapTy mFunctionToLazyStubMap;
133 
134     std::set<const llvm::Function*> PendingFunctions;
135 
136     GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
137 
138     std::map<void*, void*> ExternalFnToStubMap;
139 
140   public:
141     // Resolver to undefined symbol in CodeEmitter
142     BCCSymbolLookupFn mpSymbolLookupFn;
143     void *mpSymbolLookupContext;
144 
145     // Will take the ownership of @MemMgr
146     explicit CodeEmitter(ScriptCompiled *result, CodeMemoryManager *pMemMgr);
147 
148     virtual ~CodeEmitter();
149 
global_address_begin()150     global_addresses_const_iterator global_address_begin() const {
151       return mGlobalAddressMap.begin();
152     }
153 
global_address_end()154     global_addresses_const_iterator global_address_end() const {
155       return mGlobalAddressMap.end();
156     }
157 
158 #if 0
159     std::vector<oBCCRelocEntry> const &getCachingRelocations() const {
160       return mCachingRelocations;
161     }
162 #endif
163 
registerSymbolCallback(BCCSymbolLookupFn pFn,void * pContext)164     void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
165       mpSymbolLookupFn = pFn;
166       mpSymbolLookupContext = pContext;
167     }
168 
169     void setTargetMachine(llvm::TargetMachine &TM);
170 
171     // This callback is invoked when the specified function is about to be code
172     // generated.  This initializes the BufferBegin/End/Ptr fields.
173     virtual void startFunction(llvm::MachineFunction &F);
174 
175     // This callback is invoked when the specified function has finished code
176     // generation. If a buffer overflow has occurred, this method returns true
177     // (the callee is required to try again).
178     virtual bool finishFunction(llvm::MachineFunction &F);
179 
180     // Allocates and fills storage for an indirect GlobalValue, and returns the
181     // address.
182     virtual void *allocIndirectGV(const llvm::GlobalValue *GV,
183                                   const uint8_t *Buffer, size_t Size,
184                                   unsigned Alignment);
185 
186     // Emits a label
emitLabel(llvm::MCSymbol * Label)187     virtual void emitLabel(llvm::MCSymbol *Label) {
188       mLabelLocations[Label] = getCurrentPCValue();
189     }
190 
191     // Allocate memory for a global. Unlike allocateSpace, this method does not
192     // allocate memory in the current output buffer, because a global may live
193     // longer than the current function.
194     virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment);
195 
196     // This should be called by the target when a new basic block is about to be
197     // emitted. This way the MCE knows where the start of the block is, and can
198     // implement getMachineBasicBlockAddress.
199     virtual void StartMachineBasicBlock(llvm::MachineBasicBlock *MBB);
200 
201     // Whenever a relocatable address is needed, it should be noted with this
202     // interface.
addRelocation(const llvm::MachineRelocation & MR)203     virtual void addRelocation(const llvm::MachineRelocation &MR) {
204       mRelocations.push_back(MR);
205     }
206 
207     // Return the address of the @Index entry in the constant pool that was
208     // last emitted with the emitConstantPool method.
getConstantPoolEntryAddress(unsigned Index)209     virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
210       bccAssert(Index < mpConstantPool->getConstants().size() &&
211                 "Invalid constant pool index!");
212       return mConstPoolAddresses[Index];
213     }
214 
215     // Return the address of the jump table with index @Index in the function
216     // that last called initJumpTableInfo.
217     virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const;
218 
219     // Return the address of the specified MachineBasicBlock, only usable after
220     // the label for the MBB has been emitted.
221     virtual uintptr_t getMachineBasicBlockAddress(
222                                         llvm::MachineBasicBlock *MBB) const;
223 
224     // Return the address of the specified LabelID, only usable after the
225     // LabelID has been emitted.
getLabelAddress(llvm::MCSymbol * Label)226     virtual uintptr_t getLabelAddress(llvm::MCSymbol *Label) const {
227       bccAssert(mLabelLocations.count(Label) && "Label not emitted!");
228       return mLabelLocations.find(Label)->second;
229     }
230 
231     // Specifies the MachineModuleInfo object. This is used for exception
232     // handling purposes.
setModuleInfo(llvm::MachineModuleInfo * Info)233     virtual void setModuleInfo(llvm::MachineModuleInfo *Info) {
234       mpMMI = Info;
235     }
236 
237     void releaseUnnecessary();
238 
239     void reset();
240 
241   private:
242     void startGVStub(const llvm::GlobalValue *GV, unsigned StubSize,
243                      unsigned Alignment);
244 
245     void startGVStub(void *Buffer, unsigned StubSize);
246 
247     void finishGVStub();
248 
249     // Replace an existing mapping for GV with a new address. This updates both
250     // maps as required. If Addr is null, the entry for the global is removed
251     // from the mappings.
252     void *UpdateGlobalMapping(const llvm::GlobalValue *GV, void *Addr);
253 
254     // Tell the execution engine that the specified global is at the specified
255     // location. This is used internally as functions are JIT'd and as global
256     // variables are laid out in memory.
AddGlobalMapping(const llvm::GlobalValue * GV,void * Addr)257     void AddGlobalMapping(const llvm::GlobalValue *GV, void *Addr) {
258        void *&CurVal = mGlobalAddressMap[GV];
259        assert((CurVal == 0 || Addr == 0) && "GlobalMapping already established!");
260        CurVal = Addr;
261     }
262 
263     // This returns the address of the specified global value if it is has
264     // already been codegen'd, otherwise it returns null.
GetPointerToGlobalIfAvailable(const llvm::GlobalValue * GV)265     void *GetPointerToGlobalIfAvailable(const llvm::GlobalValue *GV) {
266       GlobalAddressMapTy::iterator I = mGlobalAddressMap.find(GV);
267       return ((I != mGlobalAddressMap.end()) ? I->second : NULL);
268     }
269 
270     unsigned int GetConstantPoolSizeInBytes(llvm::MachineConstantPool *MCP);
271 
272     // This function converts a Constant* into a GenericValue. The interesting
273     // part is if C is a ConstantExpr.
274     void GetConstantValue(const llvm::Constant *C, llvm::GenericValue &Result);
275 
276     // Stores the data in @Val of type @Ty at address @Addr.
277     void StoreValueToMemory(const llvm::GenericValue &Val, void *Addr,
278                             llvm::Type *Ty);
279 
280     // Recursive function to apply a @Constant value into the specified memory
281     // location @Addr.
282     void InitializeConstantToMemory(const llvm::Constant *C, void *Addr);
283 
284     void emitConstantPool(llvm::MachineConstantPool *MCP);
285 
286     void initJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
287 
288     void emitJumpTableInfo(llvm::MachineJumpTableInfo *MJTI);
289 
290     void *GetPointerToGlobal(llvm::GlobalValue *V,
291                              void *Reference,
292                              bool MayNeedFarStub);
293 
294     // If the specified function has been code-gen'd, return a pointer to the
295     // function. If not, compile it, or use a stub to implement lazy compilation
296     // if available.
297     void *GetPointerToFunctionOrStub(llvm::Function *F);
298 
GetLazyFunctionStubIfAvailable(llvm::Function * F)299     void *GetLazyFunctionStubIfAvailable(llvm::Function *F) {
300       return mFunctionToLazyStubMap.lookup(F);
301     }
302 
303     void *GetLazyFunctionStub(llvm::Function *F);
304 
305     void updateFunctionStub(const llvm::Function *F);
306 
307     void *GetPointerToFunction(const llvm::Function *F, bool AbortOnFailure);
308 
309     void *GetPointerToNamedSymbol(const std::string &Name,
310                                   bool AbortOnFailure);
311 
312     // Return the address of the specified global variable, possibly emitting it
313     // to memory if needed. This is used by the Emitter.
314     void *GetOrEmitGlobalVariable(llvm::GlobalVariable *GV);
315 
316     // This method abstracts memory allocation of global variable so that the
317     // JIT can allocate thread local variables depending on the target.
318     void *GetMemoryForGV(llvm::GlobalVariable *GV);
319 
320     void EmitGlobalVariable(llvm::GlobalVariable *GV);
321 
322     void *GetPointerToGVIndirectSym(llvm::GlobalValue *V, void *Reference);
323 
324     // This is the equivalent of FunctionToLazyStubMap for external functions.
325     //
326     // TODO(llvm.org): Of course, external functions don't need a lazy stub.
327     //                 It's actually here to make it more likely that far calls
328     //                 succeed, but no single stub can guarantee that. I'll
329     //                 remove this in a subsequent checkin when I actually fix
330     //                 far calls.
331 
332     // Return a stub for the function at the specified address.
333     void *GetExternalFunctionStub(void *FnAddr);
334 
335   };
336 
337 } // namespace bcc
338 
339 #endif // BCC_CODEEMITTER_H
340