131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMJITInfo.h - ARM implementation of the JIT interface -*- C++ -*-===// 2148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// 3148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// The LLVM Compiler Infrastructure 4148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// 8148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//===----------------------------------------------------------------------===// 9148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// 10148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// This file contains the declaration of the ARMJITInfo class. 11148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng// 12148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng//===----------------------------------------------------------------------===// 13148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 14148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#ifndef ARMJITINFO_H 15148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#define ARMJITINFO_H 16148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 17f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng#include "ARMMachineFunctionInfo.h" 18a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/DenseMap.h" 19a1514e24cc24b050f53a12650e047799358833a1Chandler Carruth#include "llvm/ADT/SmallVector.h" 2025e04788bfddc54dde7bed65302146b46089a166Evan Cheng#include "llvm/CodeGen/MachineConstantPool.h" 214df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng#include "llvm/CodeGen/MachineFunction.h" 224df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng#include "llvm/CodeGen/MachineJumpTableInfo.h" 23f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng#include "llvm/Target/TargetJITInfo.h" 24148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 25148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Chengnamespace llvm { 26148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng class ARMTargetMachine; 27148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 28148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng class ARMJITInfo : public TargetJITInfo { 290f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng // ConstPoolId2AddrMap - A map from constant pool ids to the corresponding 300f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng // CONSTPOOL_ENTRY addresses. 314df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng SmallVector<intptr_t, 16> ConstPoolId2AddrMap; 324df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng 334df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng // JumpTableId2AddrMap - A map from inline jumptable ids to the 344df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng // corresponding inline jump table bases. 354df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng SmallVector<intptr_t, 16> JumpTableId2AddrMap; 360f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng 3725e04788bfddc54dde7bed65302146b46089a166Evan Cheng // PCLabelMap - A map from PC labels to addresses. 3825e04788bfddc54dde7bed65302146b46089a166Evan Cheng DenseMap<unsigned, intptr_t> PCLabelMap; 3925e04788bfddc54dde7bed65302146b46089a166Evan Cheng 40588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng // Sym2IndirectSymMap - A map from symbol (GlobalValue and ExternalSymbol) 41588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng // addresses to their indirect symbol addresses. 42588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng DenseMap<void*, intptr_t> Sym2IndirectSymMap; 43588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng 443cc8223a3c062daee763d6db272415a76de38a78Evan Cheng // IsPIC - True if the relocation model is PIC. This is used to determine 453cc8223a3c062daee763d6db272415a76de38a78Evan Cheng // how to codegen function stubs. 463cc8223a3c062daee763d6db272415a76de38a78Evan Cheng bool IsPIC; 473cc8223a3c062daee763d6db272415a76de38a78Evan Cheng 48148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng public: 493cc8223a3c062daee763d6db272415a76de38a78Evan Cheng explicit ARMJITInfo() : IsPIC(false) { useGOT = false; } 50148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 51148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// replaceMachineCodeForFunction - Make it so that calling the function 52148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// whose machine code is at OLD turns into a call to NEW, perhaps by 53148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// overwriting OLD with a branch to NEW. This is used for self-modifying 54148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// code. 55148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// 56148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng virtual void replaceMachineCodeForFunction(void *Old, void *New); 57148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 58a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitGlobalValueIndirectSym - Use the specified JITCodeEmitter object 599ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng /// to emit an indirect symbol which contains the address of the specified 609ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng /// ptr. 619ed2f80910160bbf8051d91cd74c82d4619885b4Evan Cheng virtual void *emitGlobalValueIndirectSym(const GlobalValue* GV, void *ptr, 62a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JITCodeEmitter &JCE); 63e96a490d7a0e224961d37f60f85e8556a64ed2b1Evan Cheng 64108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // getStubLayout - Returns the size and alignment of the largest call stub 65108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // on ARM. 66108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin virtual StubLayout getStubLayout(); 67108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin 68a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// emitFunctionStub - Use the specified JITCodeEmitter object to emit a 69148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// small native function that simply calls the function at the specified 70148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// address. 7151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray virtual void *emitFunctionStub(const Function* F, void *Fn, 72a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes JITCodeEmitter &JCE); 73148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 74148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// getLazyResolverFunction - Expose the lazy resolver to the JIT. 75148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); 76148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 77148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// relocate - Before the JIT can run a block of code that has been emitted, 78148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// it must rewrite the code to contain the actual addresses of any 79148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng /// referenced global symbols. 80148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng virtual void relocate(void *Function, MachineRelocation *MR, 81148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng unsigned NumRelocs, unsigned char* GOTBase); 8225e04788bfddc54dde7bed65302146b46089a166Evan Cheng 83bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach /// hasCustomConstantPool - Allows a target to specify that constant 84bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach /// pool address resolution is handled by the target. 85bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach virtual bool hasCustomConstantPool() const { return true; } 86bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach 874df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// hasCustomJumpTables - Allows a target to specify that jumptables 884df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// are emitted by the target. 894df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng virtual bool hasCustomJumpTables() const { return true; } 904df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng 91b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng /// allocateSeparateGVMemory - If true, globals should be placed in 92b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng /// separately allocated heap memory rather than in the same 93a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes /// code memory allocated by JITCodeEmitter. 94b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng virtual bool allocateSeparateGVMemory() const { 95b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#ifdef __APPLE__ 96b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng return true; 97b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#else 98b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng return false; 99b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng#endif 100b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng } 101b0b53491ef32b85bd90c8590faeb8a3fb4b17a95Evan Cheng 1023cc8223a3c062daee763d6db272415a76de38a78Evan Cheng /// Initialize - Initialize internal stage for the function being JITted. 1033cc8223a3c062daee763d6db272415a76de38a78Evan Cheng /// Resize constant pool ids to CONSTPOOL_ENTRY addresses map; resize 1043cc8223a3c062daee763d6db272415a76de38a78Evan Cheng /// jump table ids to jump table bases map; remember if codegen relocation 1053cc8223a3c062daee763d6db272415a76de38a78Evan Cheng /// model is PIC. 1063cc8223a3c062daee763d6db272415a76de38a78Evan Cheng void Initialize(const MachineFunction &MF, bool isPIC) { 107f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng const ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); 1085de5d4b6d0eb3fd379fa571d82f6fa764460b3b8Evan Cheng ConstPoolId2AddrMap.resize(AFI->getNumPICLabels()); 109f1bbb9577a42cf7dc3079412f1dd7683e3a03665Evan Cheng JumpTableId2AddrMap.resize(AFI->getNumJumpTables()); 1103cc8223a3c062daee763d6db272415a76de38a78Evan Cheng IsPIC = isPIC; 111938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng } 112938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng 1130f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng /// getConstantPoolEntryAddr - The ARM target puts all constant 1144df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// pool entries into constant islands. This returns the address of the 1154df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// constant pool entry of the specified index. 116938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng intptr_t getConstantPoolEntryAddr(unsigned CPI) const { 117938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng assert(CPI < ConstPoolId2AddrMap.size()); 118938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng return ConstPoolId2AddrMap[CPI]; 1190f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng } 120bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach 1214df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// addConstantPoolEntryAddr - Map a Constant Pool Index to the address 122bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach /// where its associated value is stored. When relocations are processed, 123bc6d876adf01b368c6bdd5984d9dac32589d356eJim Grosbach /// this value will be used to resolve references to the constant. 124938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng void addConstantPoolEntryAddr(unsigned CPI, intptr_t Addr) { 125938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng assert(CPI < ConstPoolId2AddrMap.size()); 126938b9d8ef78e83926437f8a331dd1e7645e28e4eEvan Cheng ConstPoolId2AddrMap[CPI] = Addr; 1270f282439be688babbbf6d54151ddf9a7ebbf3637Evan Cheng } 12825e04788bfddc54dde7bed65302146b46089a166Evan Cheng 1294df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// getJumpTableBaseAddr - The ARM target inline all jump tables within 1304df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// text section of the function. This returns the address of the base of 1314df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// the jump table of the specified index. 1324df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng intptr_t getJumpTableBaseAddr(unsigned JTI) const { 1334df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng assert(JTI < JumpTableId2AddrMap.size()); 1344df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng return JumpTableId2AddrMap[JTI]; 1354df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng } 1364df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng 1374df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// addJumpTableBaseAddr - Map a jump table index to the address where 1384df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// the corresponding inline jump table is emitted. When relocations are 1394df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// processed, this value will be used to resolve references to the 1404df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// jump table. 1414df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng void addJumpTableBaseAddr(unsigned JTI, intptr_t Addr) { 1424df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng assert(JTI < JumpTableId2AddrMap.size()); 1434df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng JumpTableId2AddrMap[JTI] = Addr; 1444df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng } 1454df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng 14618f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach /// getPCLabelAddr - Retrieve the address of the PC label of the 14718f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach /// specified id. 14825e04788bfddc54dde7bed65302146b46089a166Evan Cheng intptr_t getPCLabelAddr(unsigned Id) const { 14925e04788bfddc54dde7bed65302146b46089a166Evan Cheng DenseMap<unsigned, intptr_t>::const_iterator I = PCLabelMap.find(Id); 15025e04788bfddc54dde7bed65302146b46089a166Evan Cheng assert(I != PCLabelMap.end()); 15125e04788bfddc54dde7bed65302146b46089a166Evan Cheng return I->second; 15225e04788bfddc54dde7bed65302146b46089a166Evan Cheng } 15325e04788bfddc54dde7bed65302146b46089a166Evan Cheng 15425e04788bfddc54dde7bed65302146b46089a166Evan Cheng /// addPCLabelAddr - Remember the address of the specified PC label. 15525e04788bfddc54dde7bed65302146b46089a166Evan Cheng void addPCLabelAddr(unsigned Id, intptr_t Addr) { 15625e04788bfddc54dde7bed65302146b46089a166Evan Cheng PCLabelMap.insert(std::make_pair(Id, Addr)); 15725e04788bfddc54dde7bed65302146b46089a166Evan Cheng } 15825e04788bfddc54dde7bed65302146b46089a166Evan Cheng 159588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng /// getIndirectSymAddr - Retrieve the address of the indirect symbol of the 160588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng /// specified symbol located at address. Returns 0 if the indirect symbol 161588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng /// has not been emitted. 162588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng intptr_t getIndirectSymAddr(void *Addr) const { 163588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng DenseMap<void*,intptr_t>::const_iterator I= Sym2IndirectSymMap.find(Addr); 164588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng if (I != Sym2IndirectSymMap.end()) 165588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng return I->second; 166588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng return 0; 167588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng } 168588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng 169588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng /// addIndirectSymAddr - Add a mapping from address of an emitted symbol to 170588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng /// its indirect symbol address. 171588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng void addIndirectSymAddr(void *SymAddr, intptr_t IndSymAddr) { 172588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng Sym2IndirectSymMap.insert(std::make_pair(SymAddr, IndSymAddr)); 173588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng } 174588920b9a5f7004e330e3597872908b4d57e9355Evan Cheng 17525e04788bfddc54dde7bed65302146b46089a166Evan Cheng private: 1764df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng /// resolveRelocDestAddr - Resolve the resulting address of the relocation 17725e04788bfddc54dde7bed65302146b46089a166Evan Cheng /// if it's not already solved. Constantpool entries must be resolved by 17825e04788bfddc54dde7bed65302146b46089a166Evan Cheng /// ARM target. 1794df60f5491ff35c8a48c2cf14e18a33c9793b3bbEvan Cheng intptr_t resolveRelocDestAddr(MachineRelocation *MR) const; 180148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng }; 181148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng} 182148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng 183148b6a419fbb20e2224a1b92c499d51513b9bc27Evan Cheng#endif 184