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