1 //===- ARMJITInfo.h - ARM implementation of the JIT interface --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the declaration of the ARMJITInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef ARMJITINFO_H 15 #define ARMJITINFO_H 16 17 #include "ARMMachineFunctionInfo.h" 18 #include "llvm/CodeGen/MachineConstantPool.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineJumpTableInfo.h" 21 #include "llvm/Target/TargetJITInfo.h" 22 #include "llvm/ADT/DenseMap.h" 23 #include "llvm/ADT/SmallVector.h" 24 25 namespace llvm { 26 class ARMTargetMachine; 27 28 class ARMJITInfo : public TargetJITInfo { 29 // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding 30 // CONSTPOOL_ENTRY addresses. 31 SmallVector<intptr_t, 16> ConstPoolId2AddrMap; 32 33 // JumpTableId2AddrMap - A map from inline jumptable ids to the 34 // corresponding inline jump table bases. 35 SmallVector<intptr_t, 16> JumpTableId2AddrMap; 36 37 // PCLabelMap - A map from PC labels to addresses. 38 DenseMap<unsigned, intptr_t> PCLabelMap; 39 40 // Sym2IndirectSymMap - A map from symbol (GlobalValue and ExternalSymbol) 41 // addresses to their indirect symbol addresses. 42 DenseMap<void*, intptr_t> Sym2IndirectSymMap; 43 44 // IsPIC - True if the relocation model is PIC. This is used to determine 45 // how to codegen function stubs. 46 bool IsPIC; 47 48 public: ARMJITInfo()49 explicit ARMJITInfo() : IsPIC(false) { useGOT = false; } 50 51 /// replaceMachineCodeForFunction - Make it so that calling the function 52 /// whose machine code is at OLD turns into a call to NEW, perhaps by 53 /// overwriting OLD with a branch to NEW. This is used for self-modifying 54 /// code. 55 /// 56 virtual void replaceMachineCodeForFunction(void *Old, void *New); 57 58 /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object 59 /// to emit an indirect symbol which contains the address of the specified 60 /// ptr. 61 virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr, 62 JITCodeEmitter &JCE); 63 64 // getStubLayout - Returns the size and alignment of the largest call stub 65 // on ARM. 66 virtual StubLayout getStubLayout(); 67 68 /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a 69 /// small native function that simply calls the function at the specified 70 /// address. 71 virtual void *emitFunctionStub(const Function* F, void *Fn, 72 JITCodeEmitter &JCE); 73 74 /// getLazyResolverFunction - Expose the lazy resolver to the JIT. 75 virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); 76 77 /// relocate - Before the JIT can run a block of code that has been emitted, 78 /// it must rewrite the code to contain the actual addresses of any 79 /// referenced global symbols. 80 virtual void relocate(void *Function, MachineRelocation *MR, 81 unsigned NumRelocs, unsigned char* GOTBase); 82 83 /// hasCustomConstantPool - Allows a target to specify that constant 84 /// pool address resolution is handled by the target. hasCustomConstantPool()85 virtual bool hasCustomConstantPool() const { return true; } 86 87 /// hasCustomJumpTables - Allows a target to specify that jumptables 88 /// are emitted by the target. hasCustomJumpTables()89 virtual bool hasCustomJumpTables() const { return true; } 90 91 /// allocateSeparateGVMemory - If true, globals should be placed in 92 /// separately allocated heap memory rather than in the same 93 /// code memory allocated by JITCodeEmitter. allocateSeparateGVMemory()94 virtual bool allocateSeparateGVMemory() const { 95 #ifdef __APPLE__ 96 return true; 97 #else 98 return false; 99 #endif 100 } 101 102 /// Initialize - Initialize internal stage for the function being JITted. 103 /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map; resize 104 /// jump table ids to jump table bases map; remember if codegen relocation 105 /// model is PIC. Initialize(const MachineFunction & MF,bool isPIC)106 void Initialize(const MachineFunction &MF, bool isPIC) { 107 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 108 ConstPoolId2AddrMap.resize(AFI->getNumPICLabels()); 109 JumpTableId2AddrMap.resize(AFI->getNumJumpTables()); 110 IsPIC = isPIC; 111 } 112 113 /// getConstantPoolEntryAddr - The ARM target puts all constant 114 /// pool entries into constant islands. This returns the address of the 115 /// constant pool entry of the specified index. getConstantPoolEntryAddr(unsigned CPI)116 intptr_t getConstantPoolEntryAddr(unsigned CPI) const { 117 assert(CPI < ConstPoolId2AddrMap.size()); 118 return ConstPoolId2AddrMap[CPI]; 119 } 120 121 /// addConstantPoolEntryAddr - Map a Constant Pool Index to the address 122 /// where its associated value is stored. When relocations are processed, 123 /// this value will be used to resolve references to the constant. addConstantPoolEntryAddr(unsigned CPI,intptr_t Addr)124 void addConstantPoolEntryAddr(unsigned CPI, intptr_t Addr) { 125 assert(CPI < ConstPoolId2AddrMap.size()); 126 ConstPoolId2AddrMap[CPI] = Addr; 127 } 128 129 /// getJumpTableBaseAddr - The ARM target inline all jump tables within 130 /// text section of the function. This returns the address of the base of 131 /// the jump table of the specified index. getJumpTableBaseAddr(unsigned JTI)132 intptr_t getJumpTableBaseAddr(unsigned JTI) const { 133 assert(JTI < JumpTableId2AddrMap.size()); 134 return JumpTableId2AddrMap[JTI]; 135 } 136 137 /// addJumpTableBaseAddr - Map a jump table index to the address where 138 /// the corresponding inline jump table is emitted. When relocations are 139 /// processed, this value will be used to resolve references to the 140 /// jump table. addJumpTableBaseAddr(unsigned JTI,intptr_t Addr)141 void addJumpTableBaseAddr(unsigned JTI, intptr_t Addr) { 142 assert(JTI < JumpTableId2AddrMap.size()); 143 JumpTableId2AddrMap[JTI] = Addr; 144 } 145 146 /// getPCLabelAddr - Retrieve the address of the PC label of the 147 /// specified id. getPCLabelAddr(unsigned Id)148 intptr_t getPCLabelAddr(unsigned Id) const { 149 DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id); 150 assert(I != PCLabelMap.end()); 151 return I->second; 152 } 153 154 /// addPCLabelAddr - Remember the address of the specified PC label. addPCLabelAddr(unsigned Id,intptr_t Addr)155 void addPCLabelAddr(unsigned Id, intptr_t Addr) { 156 PCLabelMap.insert(std::make_pair(Id, Addr)); 157 } 158 159 /// getIndirectSymAddr - Retrieve the address of the indirect symbol of the 160 /// specified symbol located at address. Returns 0 if the indirect symbol 161 /// has not been emitted. getIndirectSymAddr(void * Addr)162 intptr_t getIndirectSymAddr(void *Addr) const { 163 DenseMap<void*,intptr_t>::const_iterator I= Sym2IndirectSymMap.find(Addr); 164 if (I != Sym2IndirectSymMap.end()) 165 return I->second; 166 return 0; 167 } 168 169 /// addIndirectSymAddr - Add a mapping from address of an emitted symbol to 170 /// its indirect symbol address. addIndirectSymAddr(void * SymAddr,intptr_t IndSymAddr)171 void addIndirectSymAddr(void *SymAddr, intptr_t IndSymAddr) { 172 Sym2IndirectSymMap.insert(std::make_pair(SymAddr, IndSymAddr)); 173 } 174 175 private: 176 /// resolveRelocDestAddr - Resolve the resulting address of the relocation 177 /// if it's not already solved. Constantpool entries must be resolved by 178 /// ARM target. 179 intptr_t resolveRelocDestAddr(MachineRelocation *MR) const; 180 }; 181 } 182 183 #endif 184