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