1166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner//===-- JITEmitter.cpp - Write machine code to executable memory ----------===// 2f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 3b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// The LLVM Compiler Infrastructure 4b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman// 8b576c94c15af9a440f69d9d03c2afead7971118cJohn Criswell//===----------------------------------------------------------------------===// 9bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 105be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner// This file defines a MachineCodeEmitter object that is used by the JIT to 115be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner// write machine code to memory and remember where relocatable values are. 12bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner// 13bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner//===----------------------------------------------------------------------===// 14bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 153785fad56eb90284d4e930d40e9306391630deb1Chris Lattner#define DEBUG_TYPE "jit" 164d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner#include "JIT.h" 17afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#include "JITDwarfEmitter.h" 18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/DenseMap.h" 192763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid Kleckner#include "llvm/ADT/OwningPtr.h" 20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallPtrSet.h" 21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SmallVector.h" 22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/Statistic.h" 23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/ValueMap.h" 24a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes#include "llvm/CodeGen/JITCodeEmitter.h" 2547639fc5be0b8f4873d076a9ed24b9a3c0682b15Bill Wendling#include "llvm/CodeGen/MachineCodeInfo.h" 261cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner#include "llvm/CodeGen/MachineConstantPool.h" 27d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/CodeGen/MachineFunction.h" 2837efe6764568a3829fee26aba532283131d1a104Nate Begeman#include "llvm/CodeGen/MachineJumpTableInfo.h" 29afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#include "llvm/CodeGen/MachineModuleInfo.h" 305be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner#include "llvm/CodeGen/MachineRelocation.h" 31d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/DebugInfo.h" 32dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen#include "llvm/ExecutionEngine/GenericValue.h" 33df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin#include "llvm/ExecutionEngine/JITEventListener.h" 34df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin#include "llvm/ExecutionEngine/JITMemoryManager.h" 350b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Constants.h" 360b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 370b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DerivedTypes.h" 380b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 39551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 40d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Disassembler.h" 417d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/ErrorHandling.h" 4240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin#include "llvm/Support/ManagedStatic.h" 43d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/Memory.h" 44e7fd553b3be8b95dc0946cd3267bc2db859cd3d8Chris Lattner#include "llvm/Support/MutexGuard.h" 45848b3142addffe24abc775c5a11d5fff8ff73132Nick Lewycky#include "llvm/Support/ValueHandle.h" 467d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin#include "llvm/Support/raw_ostream.h" 47d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetInstrInfo.h" 48d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetJITInfo.h" 49d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetMachine.h" 50d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Target/TargetOptions.h" 51a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth#include <algorithm> 52a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#ifndef NDEBUG 53a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#include <iomanip> 54a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#endif 55c19aadee66b744311afe6e420847e80822a765f2Chris Lattnerusing namespace llvm; 56d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 5736343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumBytes, "Number of bytes of machine code compiled"); 5836343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumRelos, "Number of relocations applied"); 5910b4fc552f984dc978298d50c09c97c0764962fcReid KlecknerSTATISTIC(NumRetries, "Number of retries with more memory"); 60bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 61a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth 62c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin// A declaration may stop being a declaration once it's fully read from bitcode. 63c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin// This function returns true if F is fully read and is still a declaration. 64c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskinstatic bool isNonGhostDeclaration(const Function *F) { 65f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin return F->isDeclaration() && !F->isMaterializable(); 66c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin} 67c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin 685426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//===----------------------------------------------------------------------===// 695426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// JIT lazy compilation code. 705426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// 715426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnernamespace { 72e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin class JITEmitter; 7323e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin class JITResolverState; 7423e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin 7523e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin template<typename ValueTy> 7623e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin struct NoRAUWValueMapConfig : public ValueMapConfig<ValueTy> { 7723e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin typedef JITResolverState *ExtraData; 7823e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin static void onRAUW(JITResolverState *, Value *Old, Value *New) { 79858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable("The JIT doesn't know how to handle a" 80858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper " RAUW on a value it has emitted."); 8123e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin } 8223e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin }; 8323e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin 8423e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin struct CallSiteValueMapConfig : public NoRAUWValueMapConfig<Function*> { 8523e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin typedef JITResolverState *ExtraData; 8623e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin static void onDelete(JITResolverState *JRS, Function *F); 8723e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin }; 8823e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin 89ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer class JITResolverState { 90e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky public: 9123e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin typedef ValueMap<Function*, void*, NoRAUWValueMapConfig<Function*> > 92108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin FunctionToLazyStubMapTy; 93ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin typedef std::map<void*, AssertingVH<Function> > CallSiteToFunctionMapTy; 9423e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin typedef ValueMap<Function *, SmallPtrSet<void*, 1>, 9523e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin CallSiteValueMapConfig> FunctionToCallSitesMapTy; 96e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky typedef std::map<AssertingVH<GlobalValue>, void*> GlobalToIndirectSymMapTy; 97ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer private: 98108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// FunctionToLazyStubMap - Keep track of the lazy stub created for a 99108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// particular function so that we can reuse them if necessary. 100108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin FunctionToLazyStubMapTy FunctionToLazyStubMap; 101ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 102ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin /// CallSiteToFunctionMap - Keep track of the function that each lazy call 103ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin /// site corresponds to, and vice versa. 104ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin CallSiteToFunctionMapTy CallSiteToFunctionMap; 105ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin FunctionToCallSitesMapTy FunctionToCallSitesMap; 10600b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 1075594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng /// GlobalToIndirectSymMap - Keep track of the indirect symbol created for a 108be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng /// particular GlobalVariable so that we can reuse them if necessary. 109e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky GlobalToIndirectSymMapTy GlobalToIndirectSymMap; 110be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 111e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer#ifndef NDEBUG 11240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Instance of the JIT this ResolverState serves. 11340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JIT *TheJIT; 114e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer#endif 11540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 116ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer public: 11740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JITResolverState(JIT *jit) : FunctionToLazyStubMap(this), 118e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer FunctionToCallSitesMap(this) { 119e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer#ifndef NDEBUG 120e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer TheJIT = jit; 121e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer#endif 122e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer } 12323e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin 124108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin FunctionToLazyStubMapTy& getFunctionToLazyStubMap( 125108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin const MutexGuard& locked) { 126ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer assert(locked.holds(TheJIT->lock)); 127108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return FunctionToLazyStubMap; 128ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer } 12900b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 130124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& lck) { 131124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach assert(lck.holds(TheJIT->lock)); 132ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin return GlobalToIndirectSymMap; 133ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer } 134be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 1355b24017ca8204fc256e57605b2742b38ab77da8eJay Foad std::pair<void *, Function *> LookupFunctionFromCallSite( 136ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin const MutexGuard &locked, void *CallSite) const { 137be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng assert(locked.holds(TheJIT->lock)); 138ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin 139124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach // The address given to us for the stub may not be exactly right, it 140124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach // might be a little bit after the stub. As such, use upper_bound to 141124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach // find it. 142ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin CallSiteToFunctionMapTy::const_iterator I = 143ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin CallSiteToFunctionMap.upper_bound(CallSite); 144ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin assert(I != CallSiteToFunctionMap.begin() && 145ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin "This is not a known call site!"); 146ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin --I; 147ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin return *I; 148ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin } 149ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin 150ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin void AddCallSite(const MutexGuard &locked, void *CallSite, Function *F) { 151ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin assert(locked.holds(TheJIT->lock)); 152ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin 15323e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin bool Inserted = CallSiteToFunctionMap.insert( 15423e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin std::make_pair(CallSite, F)).second; 15523e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin (void)Inserted; 15623e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin assert(Inserted && "Pair was already in CallSiteToFunctionMap"); 157ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin FunctionToCallSitesMap[F].insert(CallSite); 158ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin } 159ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin 1608e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin void EraseAllCallSitesForPrelocked(Function *F); 1618e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 1628e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // Erases _all_ call sites regardless of their function. This is used to 1638e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // unregister the stub addresses from the StubToResolverMap in 1648e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // ~JITResolver(). 1658e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin void EraseAllCallSitesPrelocked(); 166ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer }; 16700b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 1685426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// JITResolver - Keep track of, and resolve, call sites for functions that 1695426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// have not yet been compiled. 1705426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner class JITResolver { 171108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin typedef JITResolverState::FunctionToLazyStubMapTy FunctionToLazyStubMapTy; 172ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin typedef JITResolverState::CallSiteToFunctionMapTy CallSiteToFunctionMapTy; 173e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy; 174e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky 1755e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// LazyResolverFn - The target lazy resolver function that we actually 1765e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// rewrite instructions to use. 1775e225588530f641d6627becadffdd7d285bfcdbaChris Lattner TargetJITInfo::LazyResolverFn LazyResolverFn; 1785e225588530f641d6627becadffdd7d285bfcdbaChris Lattner 179ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer JITResolverState state; 1805426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 181108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// ExternalFnToStubMap - This is the equivalent of FunctionToLazyStubMap 182108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// for external functions. TODO: Of course, external functions don't need 183108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// a lazy stub. It's actually here to make it more likely that far calls 184108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// succeed, but no single stub can guarantee that. I'll remove this in a 185108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// subsequent checkin when I actually fix far calls. 186d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner std::map<void*, void*> ExternalFnToStubMap; 1876a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 1881606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng /// revGOTMap - map addresses to indexes in the GOT 1896a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth std::map<void*, unsigned> revGOTMap; 1906a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth unsigned nextGOTIndex; 1916a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 192e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITEmitter &JE; 193e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 19440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Instance of JIT corresponding to this Resolver. 19540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JIT *TheJIT; 196e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner 19740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin public: 19840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin explicit JITResolver(JIT &jit, JITEmitter &je) 199e04690e092fdc4d27a8642775892293f4ae6ede3Benjamin Kramer : state(&jit), nextGOTIndex(0), JE(je), TheJIT(&jit) { 200e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn); 2015e225588530f641d6627becadffdd7d285bfcdbaChris Lattner } 2025426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 2038e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin ~JITResolver(); 2048e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 205108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// getLazyFunctionStubIfAvailable - This returns a pointer to a function's 206108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// lazy-compilation stub if it has already been created. 207108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *getLazyFunctionStubIfAvailable(Function *F); 208704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng 209108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// getLazyFunctionStub - This returns a pointer to a function's 210108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin /// lazy-compilation stub, creating one on demand as needed. 211108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *getLazyFunctionStub(Function *F); 2125426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 213d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// getExternalFunctionStub - Return a stub for the function at the 214d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// specified address, created lazily on demand. 215d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner void *getExternalFunctionStub(void *FnAddr); 216d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 2175594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng /// getGlobalValueIndirectSym - Return an indirect symbol containing the 218c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng /// specified GV address. 2195594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng void *getGlobalValueIndirectSym(GlobalValue *V, void *GVAddress); 220be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 2216a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth /// getGOTIndexForAddress - Return a new or existing index in the GOT for 2228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// an address. This function only manages slots, it does not manage the 2236a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth /// contents of the slots or the memory associated with the GOT. 2248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned getGOTIndexForAddr(void *addr); 2256a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 2265426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// JITCompilerFn - This function is called to resolve a stub to a compiled 2275426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// address. If the LLVM Function corresponding to the stub has not yet 2285426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// been compiled, this function compiles it first. 2295426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner static void *JITCompilerFn(void *Stub); 2305426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner }; 231e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 23240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin class StubToResolverMapTy { 23340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Map a stub address to a specific instance of a JITResolver so that 23440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// lazily-compiled functions can find the right resolver to use. 23540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// 23640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Guarded by Lock. 23740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin std::map<void*, JITResolver*> Map; 23840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 23940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Guards Map from concurrent accesses. 24040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin mutable sys::Mutex Lock; 24140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 24240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin public: 24340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Registers a Stub to be resolved by Resolver. 24440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void RegisterStubResolver(void *Stub, JITResolver *Resolver) { 24540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 24640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin Map.insert(std::make_pair(Stub, Resolver)); 24740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 24840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Unregisters the Stub when it's invalidated. 24940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void UnregisterStubResolver(void *Stub) { 25040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 25140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin Map.erase(Stub); 25240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 25340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Returns the JITResolver instance that owns the Stub. 25440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JITResolver *getResolverFromStub(void *Stub) const { 25540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard guard(Lock); 25640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // The address given to us for the stub may not be exactly right, it might 25740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // be a little bit after the stub. As such, use upper_bound to find it. 25840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // This is the same trick as in LookupFunctionFromCallSite from 25940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin // JITResolverState. 26040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin std::map<void*, JITResolver*>::const_iterator I = Map.upper_bound(Stub); 26140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin assert(I != Map.begin() && "This is not a known stub!"); 26240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin --I; 26340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin return I->second; 26440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin } 2658e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin /// True if any stubs refer to the given resolver. Only used in an assert(). 2668e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin /// O(N) 2678e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin bool ResolverHasStubs(JITResolver* Resolver) const { 2688e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin MutexGuard guard(Lock); 2698e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin for (std::map<void*, JITResolver*>::const_iterator I = Map.begin(), 2708e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin E = Map.end(); I != E; ++I) { 2718e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin if (I->second == Resolver) 2728e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin return true; 2738e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } 2748e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin return false; 2758e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } 27640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin }; 27740966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// This needs to be static so that a lazy call stub can access it with no 27840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// context except the address of the stub. 27940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin ManagedStatic<StubToResolverMapTy> StubToResolverMap; 28040966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 281e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is 282e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// used to output functions to memory for execution. 283e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin class JITEmitter : public JITCodeEmitter { 284e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITMemoryManager *MemMgr; 285e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 28632d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin // When outputting a function stub in the context of some other function, we 28732d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin // save BufferBegin/BufferEnd/CurBufferPtr here. 28832d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin uint8_t *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; 28932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin 290e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin // When reattempting to JIT a function after running out of space, we store 291e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin // the estimated size of the function we're trying to JIT here, so we can 292e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin // ask the memory manager for at least this much space. When we 293e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin // successfully emit the function, we reset this back to zero. 294e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin uintptr_t SizeEstimate; 295e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 296e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// Relocations - These are the relocations that the function needs, as 297e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// emitted. 298e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin std::vector<MachineRelocation> Relocations; 299116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 300e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// MBBLocations - This vector is a mapping from MBB ID's to their address. 301e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// It is filled in by the StartMachineBasicBlock callback and queried by 302e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// the getMachineBasicBlockAddress callback. 303e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin std::vector<uintptr_t> MBBLocations; 304e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 305e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// ConstantPool - The constant pool for the current function. 306e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// 307e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MachineConstantPool *ConstantPool; 308e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 309e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// ConstantPoolBase - A pointer to the first entry in the constant pool. 310e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// 311e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void *ConstantPoolBase; 312e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 313e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// ConstPoolAddresses - Addresses of individual constant pool entries. 314e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// 315e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin SmallVector<uintptr_t, 8> ConstPoolAddresses; 316e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 317e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// JumpTable - The jump tables for the current function. 318e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// 319e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MachineJumpTableInfo *JumpTable; 320116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 321e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// JumpTableBase - A pointer to the first entry in the jump table. 322e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// 323e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void *JumpTableBase; 324e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 325e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// Resolver - This contains info about the currently resolved functions. 326e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITResolver Resolver; 327e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 328e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// DE - The dwarf emitter for the jit. 329e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin OwningPtr<JITDwarfEmitter> DE; 330e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 331116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher /// LabelLocations - This vector is a mapping from Label ID's to their 332e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// address. 3331611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner DenseMap<MCSymbol*, uintptr_t> LabelLocations; 334e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 335e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// MMI - Machine module info for exception informations 336e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MachineModuleInfo* MMI; 337e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 338116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher // CurFn - The llvm function being emitted. Only valid during 339e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin // finishFunction(). 340e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin const Function *CurFn; 341e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 342e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// Information about emitted code, which is passed to the 343e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// JITEventListeners. This is reset in startFunction and used in 344e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// finishFunction. 345e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITEvent_EmittedFunctionDetails EmissionDetails; 346e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 347e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin struct EmittedCode { 348e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void *FunctionBody; // Beginning of the function's allocation. 349e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void *Code; // The address the function's code actually starts at. 350e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void *ExceptionTable; 351e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin EmittedCode() : FunctionBody(0), Code(0), ExceptionTable(0) {} 352e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin }; 353e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin struct EmittedFunctionConfig : public ValueMapConfig<const Function*> { 354e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin typedef JITEmitter *ExtraData; 355e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin static void onDelete(JITEmitter *, const Function*); 356e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin static void onRAUW(JITEmitter *, const Function*, const Function*); 357e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin }; 358e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin ValueMap<const Function *, EmittedCode, 359e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin EmittedFunctionConfig> EmittedFunctions; 360e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 3614eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray DebugLoc PrevDL; 362e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 36340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin /// Instance of the JIT 36440966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JIT *TheJIT; 36540966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin 3668a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky bool JITExceptionHandling; 3678a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky 368e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin public: 369e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITEmitter(JIT &jit, JITMemoryManager *JMM, TargetMachine &TM) 370e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin : SizeEstimate(0), Resolver(jit, *this), MMI(0), CurFn(0), 3718a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky EmittedFunctions(this), TheJIT(&jit), 372611caf5f91c4abe934480259043fcbb30ea07e3aRafael Espindola JITExceptionHandling(TM.Options.JITExceptionHandling) { 373e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 374e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin if (jit.getJITInfo().needsGOT()) { 375e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MemMgr->AllocateGOT(); 376c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT is managing a GOT\n"); 377e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 378e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 379611caf5f91c4abe934480259043fcbb30ea07e3aRafael Espindola if (JITExceptionHandling) { 380e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin DE.reset(new JITDwarfEmitter(jit)); 381e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 382e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 383116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher ~JITEmitter() { 384e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin delete MemMgr; 385e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 386e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 387e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JITResolver &getJITResolver() { return Resolver; } 388e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 389e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void startFunction(MachineFunction &F); 390e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual bool finishFunction(MachineFunction &F); 391116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 392e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void emitConstantPool(MachineConstantPool *MCP); 393e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void initJumpTableInfo(MachineJumpTableInfo *MJTI); 394e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void emitJumpTableInfo(MachineJumpTableInfo *MJTI); 395116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 39632d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin void startGVStub(const GlobalValue* GV, 39732d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin unsigned StubSize, unsigned Alignment = 1); 39832d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin void startGVStub(void *Buffer, unsigned StubSize); 39932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin void finishGVStub(); 40032d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin virtual void *allocIndirectGV(const GlobalValue *GV, 40132d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin const uint8_t *Buffer, size_t Size, 40232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin unsigned Alignment); 403e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 404e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// allocateSpace - Reserves space in the current block if any, or 405e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// allocate a new one of the given size. 406e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void *allocateSpace(uintptr_t Size, unsigned Alignment); 407e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 408e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// allocateGlobal - Allocate memory for a global. Unlike allocateSpace, 409e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// this method does not allocate memory in the current output buffer, 410e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// because a global may live longer than the current function. 411e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void *allocateGlobal(uintptr_t Size, unsigned Alignment); 412e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 413e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void addRelocation(const MachineRelocation &MR) { 414e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin Relocations.push_back(MR); 415e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 416116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 417e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { 418e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin if (MBBLocations.size() <= (unsigned)MBB->getNumber()) 419e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MBBLocations.resize((MBB->getNumber()+1)*2); 420e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MBBLocations[MBB->getNumber()] = getCurrentPCValue(); 42168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner if (MBB->hasAddressTaken()) 42268feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner TheJIT->addPointerToBasicBlock(MBB->getBasicBlock(), 42368feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner (void*)getCurrentPCValue()); 424c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Emitting BB" << MBB->getNumber() << " at [" 425e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin << (void*) getCurrentPCValue() << "]\n"); 426e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 427e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 428e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const; 429e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const; 430e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 43168feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const{ 432116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 433e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MBBLocations[MBB->getNumber()] && "MBB not emitted!"); 434e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin return MBBLocations[MBB->getNumber()]; 435e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 436e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 437e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// retryWithMoreMemory - Log a retry and deallocate all memory for the 438e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// given function. Increase the minimum allocation size so that we get 439e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// more memory next time. 440e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void retryWithMoreMemory(MachineFunction &F); 441e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 442e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// deallocateMemForFunction - Deallocate all memory for the specified 443e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin /// function body. 444e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin void deallocateMemForFunction(const Function *F); 445e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 446e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void processDebugLoc(DebugLoc DL, bool BeforePrintingInsn); 447e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 4481611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner virtual void emitLabel(MCSymbol *Label) { 4491611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner LabelLocations[Label] = getCurrentPCValue(); 450e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 451e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 45247639fc5be0b8f4873d076a9ed24b9a3c0682b15Bill Wendling virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { 45347639fc5be0b8f4873d076a9ed24b9a3c0682b15Bill Wendling return &LabelLocations; 45447639fc5be0b8f4873d076a9ed24b9a3c0682b15Bill Wendling } 45547639fc5be0b8f4873d076a9ed24b9a3c0682b15Bill Wendling 4561611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner virtual uintptr_t getLabelAddress(MCSymbol *Label) const { 4571611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner assert(LabelLocations.count(Label) && "Label not emitted!"); 4581611273351d75b5cbe2a67485bb9831d5916fe26Chris Lattner return LabelLocations.find(Label)->second; 459e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 460116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 461e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin virtual void setModuleInfo(MachineModuleInfo* Info) { 462e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin MMI = Info; 463e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin if (DE.get()) DE->setModuleInfo(Info); 464e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin } 465e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin 466e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin private: 4672d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin void *getPointerToGlobal(GlobalValue *GV, void *Reference, 4682d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin bool MayNeedFarStub); 4692d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference); 470e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin }; 4715426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 4725426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 47323e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskinvoid CallSiteValueMapConfig::onDelete(JITResolverState *JRS, Function *F) { 4748e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin JRS->EraseAllCallSitesForPrelocked(F); 4758e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin} 4768e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 4778e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskinvoid JITResolverState::EraseAllCallSitesForPrelocked(Function *F) { 4788e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin FunctionToCallSitesMapTy::iterator F2C = FunctionToCallSitesMap.find(F); 4798e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin if (F2C == FunctionToCallSitesMap.end()) 4808e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin return; 4818e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin StubToResolverMapTy &S2RMap = *StubToResolverMap; 4828e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin for (SmallPtrSet<void*, 1>::const_iterator I = F2C->second.begin(), 4838e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin E = F2C->second.end(); I != E; ++I) { 4848e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin S2RMap.UnregisterStubResolver(*I); 4858e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin bool Erased = CallSiteToFunctionMap.erase(*I); 4868e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin (void)Erased; 4878e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin assert(Erased && "Missing call site->function mapping"); 4888e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } 4898e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin FunctionToCallSitesMap.erase(F2C); 4908e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin} 4918e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 4928e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskinvoid JITResolverState::EraseAllCallSitesPrelocked() { 4938e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin StubToResolverMapTy &S2RMap = *StubToResolverMap; 4948e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin for (CallSiteToFunctionMapTy::const_iterator 4958e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin I = CallSiteToFunctionMap.begin(), 4968e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin E = CallSiteToFunctionMap.end(); I != E; ++I) { 4978e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin S2RMap.UnregisterStubResolver(I->first); 4988e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } 4998e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin CallSiteToFunctionMap.clear(); 5008e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin FunctionToCallSitesMap.clear(); 5018e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin} 5028e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 5038e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey YasskinJITResolver::~JITResolver() { 5048e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // No need to lock because we're in the destructor, and state isn't shared. 5058e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin state.EraseAllCallSitesPrelocked(); 5068e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin assert(!StubToResolverMap->ResolverHasStubs(this) && 5078e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin "Resolver destroyed with stubs still alive."); 50823e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin} 50923e5fcfec4640955fec41dc8348f467adf1a3e56Jeffrey Yasskin 510108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin/// getLazyFunctionStubIfAvailable - This returns a pointer to a function stub 511704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng/// if it has already been created. 512108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskinvoid *JITResolver::getLazyFunctionStubIfAvailable(Function *F) { 513704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng MutexGuard locked(TheJIT->lock); 514704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng 515704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng // If we already have a stub for this function, recycle it. 516108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return state.getFunctionToLazyStubMap(locked).lookup(F); 517704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng} 518704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng 5195426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// getFunctionStub - This returns a pointer to a function stub, creating 5205426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// one on demand as needed. 521108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskinvoid *JITResolver::getLazyFunctionStub(Function *F) { 522ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(TheJIT->lock); 523ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 524108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // If we already have a lazy stub for this function, recycle it. 525108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *&Stub = state.getFunctionToLazyStubMap(locked)[F]; 5265426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner if (Stub) return Stub; 5275426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 528dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin // Call the lazy resolver function if we are JIT'ing lazily. Otherwise we 529dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin // must resolve the symbol now. 530dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin void *Actual = TheJIT->isCompilingLazily() 531dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin ? (void *)(intptr_t)LazyResolverFn : (void *)0; 532dc85724f703bddf6988b6b3f20203beab775f32bJeffrey Yasskin 533b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman // If this is an external declaration, attempt to resolve the address now 534b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman // to place in the stub. 535c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) { 536b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner Actual = TheJIT->getPointerToFunction(F); 537f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman 53869f9378675b23135043d93aa58300fed3ec41cbfDan Gohman // If we resolved the symbol to a null address (eg. a weak external) 5396f348e458660063a40052b208bab96895c822877Jeffrey Yasskin // don't emit a stub. Return a null pointer to the application. 5406f348e458660063a40052b208bab96895c822877Jeffrey Yasskin if (!Actual) return 0; 54169f9378675b23135043d93aa58300fed3ec41cbfDan Gohman } 54269f9378675b23135043d93aa58300fed3ec41cbfDan Gohman 543108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); 54432d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE.startGVStub(F, SL.Size, SL.Alignment); 545b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman // Codegen a new stub, calling the lazy resolver or the actual address of the 546b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman // external function, if it was resolved. 547e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, JE); 54832d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE.finishGVStub(); 549b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner 550870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner if (Actual != (void*)(intptr_t)LazyResolverFn) { 551b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // If we are getting the stub for an external function, we really want the 552b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // address of the stub in the GlobalAddressMap for the JIT, not the address 553b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // of the external function. 554b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner TheJIT->updateGlobalMapping(F, Stub); 555b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner } 5565426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 557c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Lazy stub emitted at [" << Stub << "] for function '" 558ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << F->getName() << "'\n"); 559cb47941556800369216c062dcee8dcab7cd39ee9Chris Lattner 5608e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin if (TheJIT->isCompilingLazily()) { 5618e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // Register this JITResolver as the one corresponding to this call site so 5628e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // JITCompilerFn will be able to find it. 5638e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin StubToResolverMap->RegisterStubResolver(Stub, this); 5648e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin 5658e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // Finally, keep track of the stub-to-Function mapping so that the 5668e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // JITCompilerFn knows which function to compile! 5678e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin state.AddCallSite(locked, Stub, F); 5688e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } else if (!Actual) { 5698e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // If we are JIT'ing non-lazily but need to call a function that does not 5708e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // exist yet, add it to the JIT's work list so that we can fill in the 5718e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin // stub address later. 5728e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin assert(!isNonGhostDeclaration(F) && !F->hasAvailableExternallyLinkage() && 5738e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin "'Actual' should have been set above."); 5748e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin TheJIT->addPendingFunction(F); 5758e98d1299dcd9a725e9244457568ff43b153b1a9Jeffrey Yasskin } 576e5f879825f5e6746144addd93a852cdd5896e9c1Jeffrey Yasskin 5775426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return Stub; 5785426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 5795426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 5805594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng/// getGlobalValueIndirectSym - Return a lazy pointer containing the specified 581be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng/// GV address. 5825594f120b8880f7c514b0376c4adac1267a0b2b6Evan Chengvoid *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) { 583be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng MutexGuard locked(TheJIT->lock); 584be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 585be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng // If we already have a stub for this global variable, recycle it. 5865594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV]; 5875594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng if (IndirectSym) return IndirectSym; 588be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 589e4d783d584d22d7fcb4cba2a24e0f45f62ed8153Evan Cheng // Otherwise, codegen a new indirect symbol. 5905594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress, 591e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin JE); 592be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 593c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Indirect symbol emitted at [" << IndirectSym 594ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << "] for GV '" << GV->getName() << "'\n"); 595be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 5965594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng return IndirectSym; 597be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng} 598be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 599d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// getExternalFunctionStub - Return a stub for the function at the 600d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// specified address, created lazily on demand. 601d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattnervoid *JITResolver::getExternalFunctionStub(void *FnAddr) { 602d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner // If we already have a stub for this function, recycle it. 603d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner void *&Stub = ExternalFnToStubMap[FnAddr]; 604d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner if (Stub) return Stub; 605d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 606108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin TargetJITInfo::StubLayout SL = TheJIT->getJITInfo().getStubLayout(); 60732d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE.startGVStub(0, SL.Size, SL.Alignment); 608e637c195fda4002da0f9ae822e9c5c54e676a61fJeffrey Yasskin Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, JE); 60932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE.finishGVStub(); 61055fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 611c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Stub emitted at [" << Stub 612bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << "] for external function at '" << FnAddr << "'\n"); 613d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner return Stub; 614d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner} 615d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 6166a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharthunsigned JITResolver::getGOTIndexForAddr(void* addr) { 6176a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth unsigned idx = revGOTMap[addr]; 6186a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth if (!idx) { 6196a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth idx = ++nextGOTIndex; 6206a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth revGOTMap[addr] = idx; 621c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Adding GOT entry " << idx << " for addr [" 622bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << addr << "]\n"); 6236a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 6246a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth return idx; 6256a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth} 626d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 6275426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// JITCompilerFn - This function is called when a lazy compilation stub has 6285426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// been entered. It looks up which function this stub corresponds to, compiles 6295426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// it if necessary, then returns the resultant function pointer. 6305426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnervoid *JITResolver::JITCompilerFn(void *Stub) { 63140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JITResolver *JR = StubToResolverMap->getResolverFromStub(Stub); 63240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin assert(JR && "Unable to find the corresponding JITResolver to the call site"); 633116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 634dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray Function* F = 0; 635dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray void* ActualPtr = 0; 636dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 637dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray { 638dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // Only lock for getting the Function. The call getPointerToFunction made 639dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // in this function might trigger function materializing, which requires 640dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // JIT lock to be unlocked. 64140966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard locked(JR->TheJIT->lock); 642dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 643ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // The address given to us for the stub may not be exactly right, it might 644ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // be a little bit after the stub. As such, use upper_bound to find it. 6455b24017ca8204fc256e57605b2742b38ab77da8eJay Foad std::pair<void*, Function*> I = 64640966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JR->state.LookupFunctionFromCallSite(locked, Stub); 647ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin F = I.second; 648ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin ActualPtr = I.first; 649dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray } 6505426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 6519da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // If we have already code generated the function, just return the address. 65240966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin void *Result = JR->TheJIT->getPointerToGlobalIfAvailable(F); 653116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 6549da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng if (!Result) { 6559da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // Otherwise we don't have it, do lazy compilation now. 656116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 6579da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // If lazy compilation is disabled, emit a useful error message and abort. 65840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin if (!JR->TheJIT->isCompilingLazily()) { 659124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach report_fatal_error("LLVM JIT requested to do lazy compilation of" 660124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach " function '" 6617d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin + F->getName() + "' when lazy compiles are disabled!"); 6629da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng } 663116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 664c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Lazily resolving function '" << F->getName() 665ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << "' In stub ptr = " << Stub << " actual ptr = " 666ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << ActualPtr << "\n"); 6671f6a329f79b3568d379142f921f59c4143ddaa14Duncan Sands (void)ActualPtr; 6689da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng 66940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin Result = JR->TheJIT->getPointerToFunction(F); 6709da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng } 671ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin 672ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // Reacquire the lock to update the GOT map. 67340966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin MutexGuard locked(JR->TheJIT->lock); 6745426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 675ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // We might like to remove the call site from the CallSiteToFunction map, but 676ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // we can't do that! Multiple threads could be stuck, waiting to acquire the 677ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // lock above. As soon as the 1st function finishes compiling the function, 678ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // the next one will be released, and needs to be able to find the function it 679ebbcef945d33af5252486c1655ec6afdba4f97a7Jeffrey Yasskin // needs to call. 6805426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 6815426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // FIXME: We could rewrite all references to this stub if we knew them. 6826a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 683d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen // What we will do is set the compiled function address to map to the 684d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen // same GOT entry as the stub so that later clients may update the GOT 6856a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // if they see it still using the stub address. 6866a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // Note: this is done so the Resolver doesn't have to manage GOT memory 6876a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // Do this without allocating map space if the target isn't using a GOT 68840966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin if(JR->revGOTMap.find(Stub) != JR->revGOTMap.end()) 68940966a7c6847c102fbf466da3e8726c59c3dbb1eJeffrey Yasskin JR->revGOTMap[Result] = JR->revGOTMap[Stub]; 6906a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 6915426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return Result; 6925426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 6935426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 6948ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner//===----------------------------------------------------------------------===// 695166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner// JITEmitter code. 6965426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// 697166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, 6982d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin bool MayNeedFarStub) { 699d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) 7005426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return TheJIT->getOrEmitGlobalVariable(GV); 701d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 70218e045983757a7d2bae482d2abe444a5bb3ed134Chris Lattner if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) 70319e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikov return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false)); 7045426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 7055426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // If we have already compiled the function, return a pointer to its body. 7065426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner Function *F = cast<Function>(V); 707116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 708108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *FnStub = Resolver.getLazyFunctionStubIfAvailable(F); 709116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher if (FnStub) { 710108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // Return the function stub if it's already created. We do this first so 711108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // that we're returning the same address for the function as any previous 712108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // call. TODO: Yes, this is wrong. The lazy stub isn't guaranteed to be 713108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin // close enough to call. 714116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher return FnStub; 71550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman } 716116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 717e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin // If we know the target can handle arbitrary-distance calls, try to 718e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin // return a direct pointer. 719e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin if (!MayNeedFarStub) { 720e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin // If we have code, go ahead and return that. 721e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F); 722e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin if (ResultPtr) return ResultPtr; 723e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin 724e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin // If this is an external function pointer, we can force the JIT to 725e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin // 'compile' it, which really just adds it to the map. 726c5818fb83750259f23f70e91ee9fb9b11d67160dJeffrey Yasskin if (isNonGhostDeclaration(F) || F->hasAvailableExternallyLinkage()) 727e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin return TheJIT->getPointerToFunction(F); 728e03a39b09620d4efc5ee4a76859a99ff0e095ae0Jeffrey Yasskin } 729d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 73039c75f2e907c577a4f922daccf1f7d04acc9438eJeffrey Yasskin // Otherwise, we may need a to emit a stub, and, conservatively, we always do 73139c75f2e907c577a4f922daccf1f7d04acc9438eJeffrey Yasskin // so. Note that it's possible to return null from getLazyFunctionStub in the 73239c75f2e907c577a4f922daccf1f7d04acc9438eJeffrey Yasskin // case of a weak extern that fails to resolve. 73339c75f2e907c577a4f922daccf1f7d04acc9438eJeffrey Yasskin return Resolver.getLazyFunctionStub(F); 7345426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 7355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 7362d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskinvoid *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference) { 73750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman // Make sure GV is emitted first, and create a stub containing the fully 73850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman // resolved address. 7392d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin void *GVAddress = getPointerToGlobal(V, Reference, false); 74050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman void *StubAddr = Resolver.getGlobalValueIndirectSym(V, GVAddress); 74150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman return StubAddr; 74250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman} 74350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman 74402c04237d01ffe7170be746ceed5f10487e0ca0cDevang Patelvoid JITEmitter::processDebugLoc(DebugLoc DL, bool BeforePrintingInsn) { 745de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (DL.isUnknown()) return; 746de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner if (!BeforePrintingInsn) return; 747124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 748134d8eec8789184c7a7290ee101ca3d6f62f384aChris Lattner const LLVMContext &Context = EmissionDetails.MF->getFunction()->getContext(); 7494eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray 7504eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray if (DL.getScope(Context) != 0 && PrevDL != DL) { 751de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner JITEvent_EmittedFunctionDetails::LineStart NextLine; 752de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner NextLine.Address = getCurrentPCValue(); 753de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner NextLine.Loc = DL; 754de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner EmissionDetails.LineStarts.push_back(NextLine); 75532360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin } 756de4845c163a5847c82d7ce10ed0c320098bce6e0Chris Lattner 7574eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray PrevDL = DL; 75832360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin} 75932360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin 7601606e8e4cd937e6de6681f686c266cf61722d972Evan Chengstatic unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP, 7613574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow const DataLayout *TD) { 762dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 763dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray if (Constants.empty()) return 0; 764dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 7651606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Size = 0; 7661606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 7671606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng MachineConstantPoolEntry CPE = Constants[i]; 7681606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned AlignMask = CPE.getAlignment() - 1; 7691606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng Size = (Size + AlignMask) & ~AlignMask; 770db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = CPE.getType(); 771777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands Size += TD->getTypeAllocSize(Ty); 7721606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng } 773dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray return Size; 774dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray} 775dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 776166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::startFunction(MachineFunction &F) { 777c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Starting CodeGen of Function " 77896601ca332ab388754ca4673be8973396fea2dddCraig Topper << F.getName() << "\n"); 779eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng 780dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray uintptr_t ActualSize = 0; 781cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach // Set the memory writable, if it's not already 782cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach MemMgr->setMemoryWritable(); 783124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 784134d8eec8789184c7a7290ee101ca3d6f62f384aChris Lattner if (SizeEstimate > 0) { 78510b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // SizeEstimate will be non-zero on reallocation attempts. 78610b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner ActualSize = SizeEstimate; 787dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray } 788dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 7898907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), 7908907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ActualSize); 791e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner BufferEnd = BufferBegin+ActualSize; 7921e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin EmittedFunctions[F.getFunction()].FunctionBody = BufferBegin; 7931e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin 7949a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng // Ensure the constant pool/jump table info is at least 4-byte aligned. 7959a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng emitAlignment(16); 7969a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng 797f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner emitConstantPool(F.getConstantPool()); 798071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) 799071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner initJumpTableInfo(MJTI); 800f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 801f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner // About to start emitting the machine code for the function. 8020eb4d6b52e1b5db9a4c86e5a954356ae3507a287Chris Lattner emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); 803f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); 8047a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin EmittedFunctions[F.getFunction()].Code = CurBufferPtr; 80555fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 806b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner MBBLocations.clear(); 80732360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin 80832360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin EmissionDetails.MF = &F; 80932360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin EmissionDetails.LineStarts.clear(); 810bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 811bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 81243b429b05989075b60693d57395c99b0ad789f8dChris Lattnerbool JITEmitter::finishFunction(MachineFunction &F) { 813e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner if (CurBufferPtr == BufferEnd) { 81410b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // We must call endFunctionBody before retrying, because 81510b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // deallocateMemForFunction requires it. 81610b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 81710b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner retryWithMoreMemory(F); 81810b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner return true; 819e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner } 82010b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner 821071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner if (MachineJumpTableInfo *MJTI = F.getJumpTableInfo()) 822071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner emitJumpTableInfo(MJTI); 82310b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner 824a827953c32e420740c281b4a38a056d15b180932Chris Lattner // FnStart is the start of the text, not the start of the constant pool and 825a827953c32e420740c281b4a38a056d15b180932Chris Lattner // other per-function data. 826186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes uint8_t *FnStart = 827186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes (uint8_t *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); 828bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 82919fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis // FnEnd is the end of the function's machine code. 830186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes uint8_t *FnEnd = CurBufferPtr; 83119fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis 8325be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner if (!Relocations.empty()) { 83350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman CurFn = F.getFunction(); 834e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner NumRelos += Relocations.size(); 835e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner 8365be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner // Resolve the relocations to concrete pointers. 8375be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { 8385be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner MachineRelocation &MR = Relocations[i]; 8399200605cd5f6db50be20efb7df926dc5a0d19a4dEvan Cheng void *ResultPtr = 0; 840ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng if (!MR.letTargetResolve()) { 841d7398c9b699cae3a109e9808401f7d0b2fc7e686Evan Cheng if (MR.isExternalSymbol()) { 84269f9378675b23135043d93aa58300fed3ec41cbfDan Gohman ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(), 84369f9378675b23135043d93aa58300fed3ec41cbfDan Gohman false); 844c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Map \'" << MR.getExternalSymbol() << "\' to [" 845116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher << ResultPtr << "]\n"); 846ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng 847ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng // If the target REALLY wants a stub for this function, emit it now. 8482d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin if (MR.mayNeedFarStub()) { 8496f348e458660063a40052b208bab96895c822877Jeffrey Yasskin ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); 850841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman } 851ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isGlobalValue()) { 852ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = getPointerToGlobal(MR.getGlobalValue(), 853ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng BufferBegin+MR.getMachineCodeOffset(), 8542d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin MR.mayNeedFarStub()); 8555594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng } else if (MR.isIndirectSymbol()) { 8562d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin ResultPtr = getPointerToGVIndirectSym( 8572d274412ed9aab277e070690c574714ec544cf94Jeffrey Yasskin MR.getGlobalValue(), BufferBegin+MR.getMachineCodeOffset()); 858ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isBasicBlock()) { 859ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); 860ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isConstantPoolIndex()) { 861124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach ResultPtr = 862124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); 863ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else { 864ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng assert(MR.isJumpTableIndex()); 865ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex()); 866ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } 86700b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 868ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng MR.setResultPointer(ResultPtr); 869ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } 87016ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth 8716a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // if we are managing the GOT and the relocation wants an index, 8726a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // give it one 8738907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { 874e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); 8756a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth MR.setGOTIndex(idx); 8768907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { 877c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: GOT was out of date for " << ResultPtr 878bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 879bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << "\n"); 8808907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; 8816a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 88216ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth } 8835be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner } 8845be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner 88550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman CurFn = 0; 88643b429b05989075b60693d57395c99b0ad789f8dChris Lattner TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], 8878907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Relocations.size(), MemMgr->getGOTBase()); 8885be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner } 8895be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner 890d2d5c76753b132c34c71248db2f136b38531bc6dChris Lattner // Update the GOT entry for F to point to the new code. 8918907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (MemMgr->isManagingGOT()) { 892e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); 8938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { 894c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: GOT was out of date for " << (void*)BufferBegin 895bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 896bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << "\n"); 8978907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; 8986a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 8996a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 9006a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 90119fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for 90219fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis // global variables that were referenced in the relocations. 90319fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr); 9045788d1a169db3346a612a13113348d2709bdd15bEvan Cheng 9055788d1a169db3346a612a13113348d2709bdd15bEvan Cheng if (CurBufferPtr == BufferEnd) { 90610b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner retryWithMoreMemory(F); 90710b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner return true; 90810b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner } else { 90910b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // Now that we've succeeded in emitting the function, reset the 91010b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // SizeEstimate back down to zero. 91110b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner SizeEstimate = 0; 9125788d1a169db3346a612a13113348d2709bdd15bEvan Cheng } 9135788d1a169db3346a612a13113348d2709bdd15bEvan Cheng 914cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferBegin = CurBufferPtr = 0; 915cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes NumBytes += FnEnd-FnStart; 916cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 91755fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng // Invalidate the icache if necessary. 918bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); 919df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin 920df5a7daff9c7664bff8b713e8ed5155319bc6041Jeffrey Yasskin TheJIT->NotifyFunctionEmitted(*F.getFunction(), FnStart, FnEnd-FnStart, 92132360a7e21a4454aa7014992213823fb4319905aJeffrey Yasskin EmissionDetails); 92255fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 9234eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray // Reset the previous debug location. 9244eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray PrevDL = DebugLoc(); 9254eb373988e3211b0a481dee60ecdc3d12821b7b9Nicolas Geoffray 926c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Finished CodeGen of [" << (void*)FnStart 92796601ca332ab388754ca4673be8973396fea2dddCraig Topper << "] Function: " << F.getName() 928ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << ": " << (FnEnd-FnStart) << " bytes of text, " 929ce63ffb52f249b62cdf2d250c128007b13f27e71Daniel Dunbar << Relocations.size() << " relocations\n"); 930b3a847db0b991d3210706a2580428fdc2b6bf037Argyrios Kyrtzidis 9315be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner Relocations.clear(); 9321606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng ConstPoolAddresses.clear(); 9338cd4c3e6534a14566bf163301fd45bca34e655c1Anton Korobeynikov 934bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng // Mark code region readable and executable if it's not so already. 935cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach MemMgr->setMemoryExecutable(); 936bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng 93769c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling DEBUG({ 93869c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (sys::hasDisassembler()) { 93969c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << "JIT: Disassembled code:\n"; 94069c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << sys::disassembleBuffer(FnStart, FnEnd-FnStart, 94169c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling (uintptr_t)FnStart); 94269c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling } else { 94369c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << "JIT: Binary code:\n"; 94469c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling uint8_t* q = FnStart; 94569c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling for (int i = 0; q < FnEnd; q += 4, ++i) { 94669c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (i == 4) 94769c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling i = 0; 94869c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (i == 0) 94969c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << "JIT: " << (long)(q - FnStart) << ": "; 95069c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling bool Done = false; 95169c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling for (int j = 3; j >= 0; --j) { 95269c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (q + j >= FnEnd) 95369c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling Done = true; 95469c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling else 95569c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << (unsigned short)q[j]; 95669c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling } 95769c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (Done) 95869c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling break; 95969c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << ' '; 96069c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling if (i == 3) 96169c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs() << '\n'; 962e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng } 96369c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling dbgs()<< '\n'; 964a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng } 96569c128f19d04ce7337591d2edbb6701d470c18a4Bill Wendling }); 966bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner 967611caf5f91c4abe934480259043fcbb30ea07e3aRafael Espindola if (JITExceptionHandling) { 968dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray uintptr_t ActualSize = 0; 96932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferBegin = BufferBegin; 97032d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferEnd = BufferEnd; 97132d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedCurBufferPtr = CurBufferPtr; 972dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky uint8_t *FrameRegister; 973dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky 974dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky while (true) { 975dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 976dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky ActualSize); 977dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky BufferEnd = BufferBegin+ActualSize; 978dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky EmittedFunctions[F.getFunction()].ExceptionTable = BufferBegin; 979dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky uint8_t *EhStart; 980dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd, EhStart); 981dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky 982dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky // If the buffer was large enough to hold the table then we are done. 983dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky if (CurBufferPtr != BufferEnd) 984dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky break; 985dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky 986dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky // Try again with twice as much space. 987dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky ActualSize = (CurBufferPtr - BufferBegin) * 2; 988dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky MemMgr->deallocateExceptionTable(BufferBegin); 989dced3cdb0408f0802db332453a1e9c69c5fea70cEli Bendersky } 9900fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 9910fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner FrameRegister); 99232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin BufferBegin = SavedBufferBegin; 99332d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin BufferEnd = SavedBufferEnd; 99432d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin CurBufferPtr = SavedCurBufferPtr; 995afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 99657b6e9eb6ccb757b74beeb377c7c16d08468d3e8Duncan Sands if (JITExceptionHandling) { 997515c67ee77f8d9c417efc0fe04615d269bfb70e4Eric Christopher TheJIT->RegisterTable(F.getFunction(), FrameRegister); 9982763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid Kleckner } 999afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 1000252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng 1001252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng if (MMI) 1002252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng MMI->EndFunction(); 1003116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 100443b429b05989075b60693d57395c99b0ad789f8dChris Lattner return false; 1005bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 1006bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 100710b4fc552f984dc978298d50c09c97c0764962fcReid Klecknervoid JITEmitter::retryWithMoreMemory(MachineFunction &F) { 1008c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Ran out of space for native code. Reattempting.\n"); 100910b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner Relocations.clear(); // Clear the old relocations or we'll reapply them. 101010b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner ConstPoolAddresses.clear(); 101110b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner ++NumRetries; 101210b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner deallocateMemForFunction(F.getFunction()); 101310b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner // Try again with at least twice as much free space. 101410b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner SizeEstimate = (uintptr_t)(2 * (BufferEnd - BufferBegin)); 101568feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner 101668feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner for (MachineFunction::iterator MBB = F.begin(), E = F.end(); MBB != E; ++MBB){ 101768feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner if (MBB->hasAddressTaken()) 101868feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner TheJIT->clearPointerToBasicBlock(MBB->getBasicBlock()); 101968feb22ad8e7e3b5cd97312ef105505b3c554d40Chris Lattner } 102010b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner} 102110b4fc552f984dc978298d50c09c97c0764962fcReid Kleckner 102250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman/// deallocateMemForFunction - Deallocate all memory for the specified 102350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman/// function body. Also drop any references the function has to stubs. 10247a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin/// May be called while the Function is being destroyed inside ~Value(). 102510b4fc552f984dc978298d50c09c97c0764962fcReid Klecknervoid JITEmitter::deallocateMemForFunction(const Function *F) { 10267a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin ValueMap<const Function *, EmittedCode, EmittedFunctionConfig>::iterator 10277a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin Emitted = EmittedFunctions.find(F); 10281e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin if (Emitted != EmittedFunctions.end()) { 10291e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin MemMgr->deallocateFunctionBody(Emitted->second.FunctionBody); 10301e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin MemMgr->deallocateExceptionTable(Emitted->second.ExceptionTable); 10317a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin TheJIT->NotifyFreeingMachineCode(Emitted->second.Code); 10327a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin 10331e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin EmittedFunctions.erase(Emitted); 10341e8613212286a8066001c8a3f516da89d250e05dJeffrey Yasskin } 103550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman 10368a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewycky if (JITExceptionHandling) { 1037515c67ee77f8d9c417efc0fe04615d269bfb70e4Eric Christopher TheJIT->DeregisterTable(F); 1038515c67ee77f8d9c417efc0fe04615d269bfb70e4Eric Christopher } 103950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman} 104050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman 104150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman 10428a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewyckyvoid *JITEmitter::allocateSpace(uintptr_t Size, unsigned Alignment) { 1043cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes if (BufferBegin) 1044a3f99f90338d89354384ca25f53ca4450a1a9d18Bruno Cardoso Lopes return JITCodeEmitter::allocateSpace(Size, Alignment); 1045cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 1046cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // create a new memory block if there is no active one. 1047cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // care must be taken so that BufferBegin is invalidated when a 1048cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // block is trimmed 1049cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); 1050cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferEnd = BufferBegin+Size; 1051cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes return CurBufferPtr; 1052cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes} 1053cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 10548a8d479214745c82ef00f08d4e4f1c173b5f9ce2Nick Lewyckyvoid *JITEmitter::allocateGlobal(uintptr_t Size, unsigned Alignment) { 1055489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin // Delegate this call through the memory manager. 1056489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin return MemMgr->allocateGlobal(Size, Alignment); 1057489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin} 1058489393d7b92107cc3de17d8dbe7dd11ab7395fdcJeffrey Yasskin 1059166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::emitConstantPool(MachineConstantPool *MCP) { 106047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomConstantPool()) 10618fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach return; 106247c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 1063fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 10642c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner if (Constants.empty()) return; 10652c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner 10663574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getDataLayout()); 10671606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Align = MCP->getConstantPoolAlignment(); 106897b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng ConstantPoolBase = allocateSpace(Size, Align); 1069239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner ConstantPool = MCP; 1070f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 1071f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner if (ConstantPoolBase == 0) return; // Buffer overflow. 1072f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 1073c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: Emitted constant pool at [" << ConstantPoolBase 1074bbbfa99d3d18fe9f20265305e833666645ada528Chris Lattner << "] (size: " << Size << ", alignment: " << Align << ")\n"); 107597b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng 1076239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner // Initialize the memory for all of the constant pool entries. 10771606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Offset = 0; 10783029f920519e0871a5aad5d7c592281093953733Chris Lattner for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 10791606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng MachineConstantPoolEntry CPE = Constants[i]; 10801606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned AlignMask = CPE.getAlignment() - 1; 10811606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng Offset = (Offset + AlignMask) & ~AlignMask; 10821606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 10831606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset; 10841606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng ConstPoolAddresses.push_back(CAddr); 10851606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng if (CPE.isMachineConstantPoolEntry()) { 1086cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng // FIXME: add support to lower machine constant pool values into bytes! 108775361b69f3f327842b9dad69fa7f28ae3b688412Chris Lattner report_fatal_error("Initialize memory with machine specific constant pool" 10887d696d80409aad20bb5da0fc4eccab941dd371d4Torok Edwin "entry has not been implemented!"); 1089cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng } 10901606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr); 1091c9ec9931d834cb3b9774429fae96fb8db2736993David Greene DEBUG(dbgs() << "JIT: CP" << i << " at [0x"; 1092c9ec9931d834cb3b9774429fae96fb8db2736993David Greene dbgs().write_hex(CAddr) << "]\n"); 10931606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng 1094db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = CPE.Val.ConstVal->getType(); 10953574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow Offset += TheJIT->getDataLayout()->getTypeAllocSize(Ty); 10961cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner } 10971cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner} 10981cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner 109937efe6764568a3829fee26aba532283131d1a104Nate Begemanvoid JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { 110047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomJumpTables()) 110147c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng return; 110295da605e15a6f108b551ecc6772823ea53de3007Richard Osborne if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) 110395da605e15a6f108b551ecc6772823ea53de3007Richard Osborne return; 110447c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 110537efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 110637efe6764568a3829fee26aba532283131d1a104Nate Begeman if (JT.empty()) return; 1107116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1108f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner unsigned NumEntries = 0; 110937efe6764568a3829fee26aba532283131d1a104Nate Begeman for (unsigned i = 0, e = JT.size(); i != e; ++i) 1110f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner NumEntries += JT[i].MBBs.size(); 1111f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 11123574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow unsigned EntrySize = MJTI->getEntrySize(*TheJIT->getDataLayout()); 1113f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 111437efe6764568a3829fee26aba532283131d1a104Nate Begeman // Just allocate space for all the jump tables now. We will fix up the actual 111537efe6764568a3829fee26aba532283131d1a104Nate Begeman // MBB entries in the tables after we emit the code for each block, since then 111637efe6764568a3829fee26aba532283131d1a104Nate Begeman // we will know the final locations of the MBBs in memory. 111737efe6764568a3829fee26aba532283131d1a104Nate Begeman JumpTable = MJTI; 1118071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner JumpTableBase = allocateSpace(NumEntries * EntrySize, 11193574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow MJTI->getEntryAlignment(*TheJIT->getDataLayout())); 112037efe6764568a3829fee26aba532283131d1a104Nate Begeman} 112137efe6764568a3829fee26aba532283131d1a104Nate Begeman 1122b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskeyvoid JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { 112347c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomJumpTables()) 112447c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng return; 112547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 112637efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 1127f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner if (JT.empty() || JumpTableBase == 0) return; 1128116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1129124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 113013af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner switch (MJTI->getEntryKind()) { 113195da605e15a6f108b551ecc6772823ea53de3007Richard Osborne case MachineJumpTableInfo::EK_Inline: 113295da605e15a6f108b551ecc6772823ea53de3007Richard Osborne return; 113313af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner case MachineJumpTableInfo::EK_BlockAddress: { 113413af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // EK_BlockAddress - Each entry is a plain address of block, e.g.: 113513af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // .word LBB123 11363574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow assert(MJTI->getEntrySize(*TheJIT->getDataLayout()) == sizeof(void*) && 113713af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner "Cross JIT'ing?"); 1138124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 113913af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // For each jump table, map each target in the jump table to the address of 114013af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // an emitted MachineBasicBlock. 114113af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner intptr_t *SlotPtr = (intptr_t*)JumpTableBase; 1142124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 114313af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner for (unsigned i = 0, e = JT.size(); i != e; ++i) { 114413af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 114513af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // Store the address of the basic block for this jump table slot in the 114613af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner // memory we allocated for the jump table in 'initJumpTableInfo' 114713af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) 114813af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); 114913af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner } 115013af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner break; 115113af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner } 1152124d0332dbf79ae44a61968c7c2d379552cc715dJim Grosbach 115385fe07866a3b240d9facef3b2f2ea81a0a8db018Chris Lattner case MachineJumpTableInfo::EK_Custom32: 115413af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner case MachineJumpTableInfo::EK_GPRel32BlockAddress: 115513af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner case MachineJumpTableInfo::EK_LabelDifference32: { 11563574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow assert(MJTI->getEntrySize(*TheJIT->getDataLayout()) == 4&&"Cross JIT'ing?"); 1157acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // For each jump table, place the offset from the beginning of the table 1158acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // to the target address. 1159acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey int *SlotPtr = (int*)JumpTableBase; 1160acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1161acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey for (unsigned i = 0, e = JT.size(); i != e; ++i) { 1162acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 1163acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // Store the offset of the basic block for this jump table slot in the 1164acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // memory we allocated for the jump table in 'initJumpTableInfo' 11655788d1a169db3346a612a13113348d2709bdd15bEvan Cheng uintptr_t Base = (uintptr_t)SlotPtr; 11662a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { 11675788d1a169db3346a612a13113348d2709bdd15bEvan Cheng uintptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); 116813af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner /// FIXME: USe EntryKind instead of magic "getPICJumpTableEntry" hook. 11692a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base); 11702a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng } 1171acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey } 117213af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner break; 117313af11acbf23664d61f73ddac54bc05a9733c051Chris Lattner } 11746c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka case MachineJumpTableInfo::EK_GPRel64BlockAddress: 1175858143816d43e58b17bfd11cb1b57afbd7f0f893Craig Topper llvm_unreachable( 11766c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka "JT Info emission not implemented for GPRel64BlockAddress yet."); 117737efe6764568a3829fee26aba532283131d1a104Nate Begeman } 117837efe6764568a3829fee26aba532283131d1a104Nate Begeman} 117937efe6764568a3829fee26aba532283131d1a104Nate Begeman 118032d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskinvoid JITEmitter::startGVStub(const GlobalValue* GV, 11810261d795f83a45dd53d82e511ae672d6d1f4e298Jeffrey Yasskin unsigned StubSize, unsigned Alignment) { 118232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferBegin = BufferBegin; 118332d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferEnd = BufferEnd; 118432d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedCurBufferPtr = CurBufferPtr; 1185116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1186ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Cheng BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment); 118743b429b05989075b60693d57395c99b0ad789f8dChris Lattner BufferEnd = BufferBegin+StubSize+1; 11886125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner} 11896125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner 119032d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskinvoid JITEmitter::startGVStub(void *Buffer, unsigned StubSize) { 119132d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferBegin = BufferBegin; 119232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedBufferEnd = BufferEnd; 119332d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin SavedCurBufferPtr = CurBufferPtr; 1194116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1195186c670e15828327960d05a652ec43ae768c9b8eBruno Cardoso Lopes BufferBegin = CurBufferPtr = (uint8_t *)Buffer; 1196d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman BufferEnd = BufferBegin+StubSize+1; 1197d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman} 1198d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 119932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskinvoid JITEmitter::finishGVStub() { 1200108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin assert(CurBufferPtr != BufferEnd && "Stub overflowed allocated space."); 120143b429b05989075b60693d57395c99b0ad789f8dChris Lattner NumBytes += getCurrentPCOffset(); 120232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin BufferBegin = SavedBufferBegin; 120332d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin BufferEnd = SavedBufferEnd; 120432d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin CurBufferPtr = SavedCurBufferPtr; 120532d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin} 120632d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin 120732d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskinvoid *JITEmitter::allocIndirectGV(const GlobalValue *GV, 120832d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin const uint8_t *Buffer, size_t Size, 120932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin unsigned Alignment) { 121032d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin uint8_t *IndGV = MemMgr->allocateStub(GV, Size, Alignment); 121132d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin memcpy(IndGV, Buffer, Size); 121232d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin return IndGV; 1213bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner} 1214bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 1215bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry 1216bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// in the constant pool that was last emitted with the 'emitConstantPool' 1217bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// method. 1218bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// 12195788d1a169db3346a612a13113348d2709bdd15bEvan Chenguintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { 1220239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner assert(ConstantNum < ConstantPool->getConstants().size() && 12213c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman "Invalid ConstantPoolIndex!"); 12221606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng return ConstPoolAddresses[ConstantNum]; 1223bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner} 1224bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 122537efe6764568a3829fee26aba532283131d1a104Nate Begeman// getJumpTableEntryAddress - Return the address of the JumpTable with index 122637efe6764568a3829fee26aba532283131d1a104Nate Begeman// 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' 122737efe6764568a3829fee26aba532283131d1a104Nate Begeman// 12285788d1a169db3346a612a13113348d2709bdd15bEvan Chenguintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { 122937efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables(); 123037efe6764568a3829fee26aba532283131d1a104Nate Begeman assert(Index < JT.size() && "Invalid jump table index!"); 1231116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 12323574eca1b02600bac4e625297f4ecf745f4c4f32Micah Villmow unsigned EntrySize = JumpTable->getEntrySize(*TheJIT->getDataLayout()); 1233116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1234071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned Offset = 0; 123537efe6764568a3829fee26aba532283131d1a104Nate Begeman for (unsigned i = 0; i < Index; ++i) 1236acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey Offset += JT[i].MBBs.size(); 1237116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1238acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey Offset *= EntrySize; 1239116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 12405788d1a169db3346a612a13113348d2709bdd15bEvan Cheng return (uintptr_t)((char *)JumpTableBase + Offset); 124137efe6764568a3829fee26aba532283131d1a104Nate Begeman} 124237efe6764568a3829fee26aba532283131d1a104Nate Begeman 12437a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskinvoid JITEmitter::EmittedFunctionConfig::onDelete( 12447a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin JITEmitter *Emitter, const Function *F) { 12457a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin Emitter->deallocateMemForFunction(F); 12467a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin} 12477a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskinvoid JITEmitter::EmittedFunctionConfig::onRAUW( 12487a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin JITEmitter *, const Function*, const Function*) { 12497a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin llvm_unreachable("The JIT doesn't know how to handle a" 12507a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin " RAUW on a value it has emitted."); 12517a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin} 12527a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin 12537a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin 1254e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===// 1255e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// Public interface to this file 1256e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===// 1257e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 12582763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid KlecknerJITCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM, 12592763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid Kleckner TargetMachine &tm) { 12602763217fbd2f1c54a7a25fd3ae9e997ea6ece0cbReid Kleckner return new JITEmitter(jit, JMM, tm); 1261e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1262e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1263e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// getPointerToFunctionOrStub - If the specified function has been 1264e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// code-gen'd, return a pointer to the function. If not, compile it, or use 1265e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// a stub to implement lazy compilation if available. 1266e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// 1267e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid *JIT::getPointerToFunctionOrStub(Function *F) { 1268e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // If we have already code generated the function, just return the address. 1269e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner if (void *Addr = getPointerToGlobalIfAvailable(F)) 1270e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner return Addr; 1271116664a697f9c2cdccc0df46c53f65c9f6bb22feEric Christopher 1272e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner // Get a stub if the target supports it. 12738ac1995456d6938b68f232995f49c86369dd121dSean Silva JITEmitter *JE = static_cast<JITEmitter*>(getCodeEmitter()); 1274108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin return JE->getJITResolver().getLazyFunctionStub(F); 1275e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1276e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1277d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JIT::updateFunctionStub(Function *F) { 1278d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // Get the empty stub we generated earlier. 12798ac1995456d6938b68f232995f49c86369dd121dSean Silva JITEmitter *JE = static_cast<JITEmitter*>(getCodeEmitter()); 1280108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Stub = JE->getJITResolver().getLazyFunctionStub(F); 1281108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin void *Addr = getPointerToGlobalIfAvailable(F); 1282aad0d52c5bc088e6182f83becee29846bb00d592Jeffrey Yasskin assert(Addr != Stub && "Function must have non-stub address to be updated."); 1283d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 1284d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // Tell the target jit info to rewrite the stub at the specified address, 1285d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman // rather than creating a new one. 1286108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin TargetJITInfo::StubLayout layout = getJITInfo().getStubLayout(); 128732d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE->startGVStub(Stub, layout.Size); 1288108c838093704650378b194fe9afc5ebb9e91455Jeffrey Yasskin getJITInfo().emitFunctionStub(F, Addr, *getCodeEmitter()); 128932d7e6ebde29faeea75ecb718b4281414b0eea0bJeffrey Yasskin JE->finishGVStub(); 1290d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman} 1291d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman 1292e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner/// freeMachineCodeForFunction - release machine code memory for given Function. 1293e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner/// 1294e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid JIT::freeMachineCodeForFunction(Function *F) { 1295e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // Delete translation for this from the ExecutionEngine, so it will get 1296e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // retranslated next time it is used. 12977a9034c4db248fe8b8cb82762881b51b221988d3Jeffrey Yasskin updateGlobalMapping(F, 0); 1298e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1299e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // Free the actual memory for the function body and related stuff. 13008ac1995456d6938b68f232995f49c86369dd121dSean Silva static_cast<JITEmitter*>(JCE)->deallocateMemForFunction(F); 1301e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1302