LLVM API Documentation
00001 //===- ARMJITInfo.h - ARM implementation of the JIT interface --*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains the declaration of the ARMJITInfo class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #ifndef ARMJITINFO_H 00015 #define ARMJITINFO_H 00016 00017 #include "ARMMachineFunctionInfo.h" 00018 #include "llvm/CodeGen/MachineConstantPool.h" 00019 #include "llvm/CodeGen/MachineFunction.h" 00020 #include "llvm/CodeGen/MachineJumpTableInfo.h" 00021 #include "llvm/Target/TargetJITInfo.h" 00022 #include "llvm/ADT/DenseMap.h" 00023 #include "llvm/ADT/SmallVector.h" 00024 00025 namespace llvm { 00026 class ARMTargetMachine; 00027 00028 class ARMJITInfo : public TargetJITInfo { 00029 // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding 00030 // CONSTPOOL_ENTRY addresses. 00031 SmallVector<intptr_t, 16> ConstPoolId2AddrMap; 00032 00033 // JumpTableId2AddrMap - A map from inline jumptable ids to the 00034 // corresponding inline jump table bases. 00035 SmallVector<intptr_t, 16> JumpTableId2AddrMap; 00036 00037 // PCLabelMap - A map from PC labels to addresses. 00038 DenseMap<unsigned, intptr_t> PCLabelMap; 00039 00040 // Sym2IndirectSymMap - A map from symbol (GlobalValue and ExternalSymbol) 00041 // addresses to their indirect symbol addresses. 00042 DenseMap<void*, intptr_t> Sym2IndirectSymMap; 00043 00044 // IsPIC - True if the relocation model is PIC. This is used to determine 00045 // how to codegen function stubs. 00046 bool IsPIC; 00047 00048 public: 00049 explicit ARMJITInfo() : IsPIC(false) { useGOT = false; } 00050 00051 /// replaceMachineCodeForFunction - Make it so that calling the function 00052 /// whose machine code is at OLD turns into a call to NEW, perhaps by 00053 /// overwriting OLD with a branch to NEW. This is used for self-modifying 00054 /// code. 00055 /// 00056 virtual void replaceMachineCodeForFunction(void *Old, void *New); 00057 00058 /// emitGlobalValueIndirectSym - Use the specified MachineCodeEmitter object 00059 /// to emit an indirect symbol which contains the address of the specified 00060 /// ptr. 00061 virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr, 00062 MachineCodeEmitter &MCE); 00063 00064 /// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a 00065 /// small native function that simply calls the function at the specified 00066 /// address. 00067 virtual void *emitFunctionStub(const Function* F, void *Fn, 00068 MachineCodeEmitter &MCE); 00069 00070 /// getLazyResolverFunction - Expose the lazy resolver to the JIT. 00071 virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); 00072 00073 /// relocate - Before the JIT can run a block of code that has been emitted, 00074 /// it must rewrite the code to contain the actual addresses of any 00075 /// referenced global symbols. 00076 virtual void relocate(void *Function, MachineRelocation *MR, 00077 unsigned NumRelocs, unsigned char* GOTBase); 00078 00079 /// hasCustomConstantPool - Allows a target to specify that constant 00080 /// pool address resolution is handled by the target. 00081 virtual bool hasCustomConstantPool() const { return true; } 00082 00083 /// hasCustomJumpTables - Allows a target to specify that jumptables 00084 /// are emitted by the target. 00085 virtual bool hasCustomJumpTables() const { return true; } 00086 00087 /// allocateSeparateGVMemory - If true, globals should be placed in 00088 /// separately allocated heap memory rather than in the same 00089 /// code memory allocated by MachineCodeEmitter. 00090 virtual bool allocateSeparateGVMemory() const { 00091 #ifdef __APPLE__ 00092 return true; 00093 #else 00094 return false; 00095 #endif 00096 } 00097 00098 /// Initialize - Initialize internal stage for the function being JITted. 00099 /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map; resize 00100 /// jump table ids to jump table bases map; remember if codegen relocation 00101 /// model is PIC. 00102 void Initialize(const MachineFunction &MF, bool isPIC) { 00103 const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 00104 ConstPoolId2AddrMap.resize(AFI->getNumConstPoolEntries()); 00105 JumpTableId2AddrMap.resize(AFI->getNumJumpTables()); 00106 IsPIC = isPIC; 00107 } 00108 00109 /// getConstantPoolEntryAddr - The ARM target puts all constant 00110 /// pool entries into constant islands. This returns the address of the 00111 /// constant pool entry of the specified index. 00112 intptr_t getConstantPoolEntryAddr(unsigned CPI) const { 00113 assert(CPI < ConstPoolId2AddrMap.size()); 00114 return ConstPoolId2AddrMap[CPI]; 00115 } 00116 00117 /// addConstantPoolEntryAddr - Map a Constant Pool Index to the address 00118 /// where its associated value is stored. When relocations are processed, 00119 /// this value will be used to resolve references to the constant. 00120 void addConstantPoolEntryAddr(unsigned CPI, intptr_t Addr) { 00121 assert(CPI < ConstPoolId2AddrMap.size()); 00122 ConstPoolId2AddrMap[CPI] = Addr; 00123 } 00124 00125 /// getJumpTableBaseAddr - The ARM target inline all jump tables within 00126 /// text section of the function. This returns the address of the base of 00127 /// the jump table of the specified index. 00128 intptr_t getJumpTableBaseAddr(unsigned JTI) const { 00129 assert(JTI < JumpTableId2AddrMap.size()); 00130 return JumpTableId2AddrMap[JTI]; 00131 } 00132 00133 /// addJumpTableBaseAddr - Map a jump table index to the address where 00134 /// the corresponding inline jump table is emitted. When relocations are 00135 /// processed, this value will be used to resolve references to the 00136 /// jump table. 00137 void addJumpTableBaseAddr(unsigned JTI, intptr_t Addr) { 00138 assert(JTI < JumpTableId2AddrMap.size()); 00139 JumpTableId2AddrMap[JTI] = Addr; 00140 } 00141 00142 /// getPCLabelAddr - Retrieve the address of the PC label of the specified id. 00143 intptr_t getPCLabelAddr(unsigned Id) const { 00144 DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id); 00145 assert(I != PCLabelMap.end()); 00146 return I->second; 00147 } 00148 00149 /// addPCLabelAddr - Remember the address of the specified PC label. 00150 void addPCLabelAddr(unsigned Id, intptr_t Addr) { 00151 PCLabelMap.insert(std::make_pair(Id, Addr)); 00152 } 00153 00154 /// getIndirectSymAddr - Retrieve the address of the indirect symbol of the 00155 /// specified symbol located at address. Returns 0 if the indirect symbol 00156 /// has not been emitted. 00157 intptr_t getIndirectSymAddr(void *Addr) const { 00158 DenseMap<void*,intptr_t>::const_iterator I= Sym2IndirectSymMap.find(Addr); 00159 if (I != Sym2IndirectSymMap.end()) 00160 return I->second; 00161 return 0; 00162 } 00163 00164 /// addIndirectSymAddr - Add a mapping from address of an emitted symbol to 00165 /// its indirect symbol address. 00166 void addIndirectSymAddr(void *SymAddr, intptr_t IndSymAddr) { 00167 Sym2IndirectSymMap.insert(std::make_pair(SymAddr, IndSymAddr)); 00168 } 00169 00170 private: 00171 /// resolveRelocDestAddr - Resolve the resulting address of the relocation 00172 /// if it's not already solved. Constantpool entries must be resolved by 00173 /// ARM target. 00174 intptr_t resolveRelocDestAddr(MachineRelocation *MR) const; 00175 }; 00176 } 00177 00178 #endif