JITEmitter.cpp revision ca66b08bc6c3cf899459e642a5297df8b9ccdb0d
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" 18dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen#include "llvm/Constants.h" 192c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner#include "llvm/Module.h" 20dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen#include "llvm/DerivedTypes.h" 21bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "llvm/CodeGen/MachineCodeEmitter.h" 22bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner#include "llvm/CodeGen/MachineFunction.h" 231cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner#include "llvm/CodeGen/MachineConstantPool.h" 2437efe6764568a3829fee26aba532283131d1a104Nate Begeman#include "llvm/CodeGen/MachineJumpTableInfo.h" 25afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#include "llvm/CodeGen/MachineModuleInfo.h" 265be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner#include "llvm/CodeGen/MachineRelocation.h" 278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner#include "llvm/ExecutionEngine/JITMemoryManager.h" 28dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen#include "llvm/ExecutionEngine/GenericValue.h" 291cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner#include "llvm/Target/TargetData.h" 305be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner#include "llvm/Target/TargetJITInfo.h" 31acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey#include "llvm/Target/TargetMachine.h" 32afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray#include "llvm/Target/TargetOptions.h" 33551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/Debug.h" 34e7fd553b3be8b95dc0946cd3267bc2db859cd3d8Chris Lattner#include "llvm/Support/MutexGuard.h" 35fd58e6e2ecebe92804869586d65b27085110f336Anton Korobeynikov#include "llvm/System/Disassembler.h" 36bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner#include "llvm/System/Memory.h" 37dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray#include "llvm/Target/TargetInstrInfo.h" 3847c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng#include "llvm/ADT/SmallPtrSet.h" 39551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/Statistic.h" 40a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth#include <algorithm> 41a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#ifndef NDEBUG 42a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#include <iomanip> 43a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#endif 44c19aadee66b744311afe6e420847e80822a765f2Chris Lattnerusing namespace llvm; 45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 4636343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumBytes, "Number of bytes of machine code compiled"); 4736343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumRelos, "Number of relocations applied"); 4836343735cb23680c8f8675deafbbf825d46fd868Chris Lattnerstatic JIT *TheJIT = 0; 49bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 50a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth 515426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//===----------------------------------------------------------------------===// 525426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// JIT lazy compilation code. 535426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// 545426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnernamespace { 55ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer class JITResolverState { 56ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer private: 57ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer /// FunctionToStubMap - Keep track of the stub created for a particular 58ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer /// function so that we can reuse them if necessary. 59ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer std::map<Function*, void*> FunctionToStubMap; 60ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 61ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer /// StubToFunctionMap - Keep track of the function that each stub 62ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer /// corresponds to. 63ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer std::map<void*, Function*> StubToFunctionMap; 6400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 65c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng /// GlobalToNonLazyPtrMap - Keep track of the lazy pointer created for a 66be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng /// particular GlobalVariable so that we can reuse them if necessary. 67c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng std::map<GlobalValue*, void*> GlobalToNonLazyPtrMap; 68be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 69ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer public: 70ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) { 71ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer assert(locked.holds(TheJIT->lock)); 72ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer return FunctionToStubMap; 73ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer } 7400b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 75ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer std::map<void*, Function*>& getStubToFunctionMap(const MutexGuard& locked) { 76ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer assert(locked.holds(TheJIT->lock)); 77ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer return StubToFunctionMap; 78ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer } 79be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 80be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng std::map<GlobalValue*, void*>& 81c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng getGlobalToNonLazyPtrMap(const MutexGuard& locked) { 82be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng assert(locked.holds(TheJIT->lock)); 83c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng return GlobalToNonLazyPtrMap; 84be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng } 85ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer }; 8600b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 875426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// JITResolver - Keep track of, and resolve, call sites for functions that 885426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// have not yet been compiled. 895426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner class JITResolver { 905e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// LazyResolverFn - The target lazy resolver function that we actually 915e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// rewrite instructions to use. 925e225588530f641d6627becadffdd7d285bfcdbaChris Lattner TargetJITInfo::LazyResolverFn LazyResolverFn; 935e225588530f641d6627becadffdd7d285bfcdbaChris Lattner 94ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer JITResolverState state; 955426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 96d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for 97d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// external functions. 98d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner std::map<void*, void*> ExternalFnToStubMap; 996a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 1006a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth //map addresses to indexes in the GOT 1016a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth std::map<void*, unsigned> revGOTMap; 1026a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth unsigned nextGOTIndex; 1036a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 104e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner static JITResolver *TheJITResolver; 1055426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner public: 106950a4c40b823cd4f09dc71be635229246dfd6cacDan Gohman explicit JITResolver(JIT &jit) : nextGOTIndex(0) { 107e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner TheJIT = &jit; 108e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner 109e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn); 110e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner assert(TheJITResolver == 0 && "Multiple JIT resolvers?"); 111e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner TheJITResolver = this; 112e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner } 113e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner 114e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner ~JITResolver() { 115e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner TheJITResolver = 0; 1165e225588530f641d6627becadffdd7d285bfcdbaChris Lattner } 1175426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 1185426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// getFunctionStub - This returns a pointer to a function stub, creating 1195426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// one on demand as needed. 1205426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner void *getFunctionStub(Function *F); 1215426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 122d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// getExternalFunctionStub - Return a stub for the function at the 123d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner /// specified address, created lazily on demand. 124d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner void *getExternalFunctionStub(void *FnAddr); 125d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 126c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng /// getGlobalValueNonLazyPtr - Return a non-lazy pointer containing the 127c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng /// specified GV address. 128c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng void *getGlobalValueNonLazyPtr(GlobalValue *V, void *GVAddress); 129be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 1305e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// AddCallbackAtLocation - If the target is capable of rewriting an 1315e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// instruction without the use of a stub, record the location of the use so 1325e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// we know which function is being used at the location. 1335e225588530f641d6627becadffdd7d285bfcdbaChris Lattner void *AddCallbackAtLocation(Function *F, void *Location) { 134ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(TheJIT->lock); 1355e225588530f641d6627becadffdd7d285bfcdbaChris Lattner /// Get the target-specific JIT resolver function. 136ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer state.getStubToFunctionMap(locked)[Location] = F; 137870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner return (void*)(intptr_t)LazyResolverFn; 1385e225588530f641d6627becadffdd7d285bfcdbaChris Lattner } 1395e225588530f641d6627becadffdd7d285bfcdbaChris Lattner 1406a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth /// getGOTIndexForAddress - Return a new or existing index in the GOT for 1418907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner /// an address. This function only manages slots, it does not manage the 1426a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth /// contents of the slots or the memory associated with the GOT. 1438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner unsigned getGOTIndexForAddr(void *addr); 1446a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 1455426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// JITCompilerFn - This function is called to resolve a stub to a compiled 1465426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// address. If the LLVM Function corresponding to the stub has not yet 1475426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// been compiled, this function compiles it first. 1485426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner static void *JITCompilerFn(void *Stub); 1495426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner }; 1505426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 1515426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 152e748401b180d7041738e14d3896ac61ca4bdfcbaChris LattnerJITResolver *JITResolver::TheJITResolver = 0; 1535426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 1545426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// getFunctionStub - This returns a pointer to a function stub, creating 1555426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// one on demand as needed. 1565426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnervoid *JITResolver::getFunctionStub(Function *F) { 157ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer MutexGuard locked(TheJIT->lock); 158ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer 1595426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // If we already have a stub for this function, recycle it. 160ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer void *&Stub = state.getFunctionToStubMap(locked)[F]; 1615426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner if (Stub) return Stub; 1625426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 163b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // Call the lazy resolver function unless we already KNOW it is an external 164b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // function, in which case we just skip the lazy resolution step. 165870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner void *Actual = (void*)(intptr_t)LazyResolverFn; 166a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) 167b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner Actual = TheJIT->getPointerToFunction(F); 168f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman 1695426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // Otherwise, codegen a new stub. For now, the stub will call the lazy 1705426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // resolver function. 17151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual, 172e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner *TheJIT->getCodeEmitter()); 173b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner 174870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner if (Actual != (void*)(intptr_t)LazyResolverFn) { 175b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // If we are getting the stub for an external function, we really want the 176b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // address of the stub in the GlobalAddressMap for the JIT, not the address 177b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner // of the external function. 178b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner TheJIT->updateGlobalMapping(F, Stub); 179b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner } 1805426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 181832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling DOUT << "JIT: Stub emitted at [" << Stub << "] for function '" 182832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << F->getName() << "'\n"; 183cb47941556800369216c062dcee8dcab7cd39ee9Chris Lattner 1845426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // Finally, keep track of the stub-to-Function mapping so that the 1855426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // JITCompilerFn knows which function to compile! 186ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer state.getStubToFunctionMap(locked)[Stub] = F; 1875426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return Stub; 1885426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 1895426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 190c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng/// getGlobalValueNonLazyPtr - Return a lazy pointer containing the specified 191be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng/// GV address. 192c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Chengvoid *JITResolver::getGlobalValueNonLazyPtr(GlobalValue *GV, void *GVAddress) { 193be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng MutexGuard locked(TheJIT->lock); 194be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 195be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng // If we already have a stub for this global variable, recycle it. 196c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng void *&NonLazyPtr = state.getGlobalToNonLazyPtrMap(locked)[GV]; 197c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng if (NonLazyPtr) return NonLazyPtr; 198be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 199be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng // Otherwise, codegen a new lazy pointer. 200c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng NonLazyPtr = TheJIT->getJITInfo().emitGlobalValueNonLazyPtr(GV, GVAddress, 201c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng *TheJIT->getCodeEmitter()); 202be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 203c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng DOUT << "JIT: Stub emitted at [" << NonLazyPtr << "] for GV '" 204be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng << GV->getName() << "'\n"; 205be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 206c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng return NonLazyPtr; 207be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng} 208be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 209d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// getExternalFunctionStub - Return a stub for the function at the 210d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// specified address, created lazily on demand. 211d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattnervoid *JITResolver::getExternalFunctionStub(void *FnAddr) { 212d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner // If we already have a stub for this function, recycle it. 213d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner void *&Stub = ExternalFnToStubMap[FnAddr]; 214d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner if (Stub) return Stub; 215d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 21651cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr, 217e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner *TheJIT->getCodeEmitter()); 21855fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 219832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling DOUT << "JIT: Stub emitted at [" << Stub 220832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << "] for external function at '" << FnAddr << "'\n"; 221d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner return Stub; 222d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner} 223d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 2246a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharthunsigned JITResolver::getGOTIndexForAddr(void* addr) { 2256a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth unsigned idx = revGOTMap[addr]; 2266a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth if (!idx) { 2276a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth idx = ++nextGOTIndex; 2286a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth revGOTMap[addr] = idx; 229366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n"; 2306a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 2316a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth return idx; 2326a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth} 233d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner 2345426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// JITCompilerFn - This function is called when a lazy compilation stub has 2355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// been entered. It looks up which function this stub corresponds to, compiles 2365426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// it if necessary, then returns the resultant function pointer. 2375426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnervoid *JITResolver::JITCompilerFn(void *Stub) { 238e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner JITResolver &JR = *TheJITResolver; 239dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 240dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray Function* F = 0; 241dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray void* ActualPtr = 0; 242dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 243dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray { 244dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // Only lock for getting the Function. The call getPointerToFunction made 245dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // in this function might trigger function materializing, which requires 246dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // JIT lock to be unlocked. 247dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray MutexGuard locked(TheJIT->lock); 248dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 249dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // The address given to us for the stub may not be exactly right, it might be 250dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // a little bit after the stub. As such, use upper_bound to find it. 251dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray std::map<void*, Function*>::iterator I = 252dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray JR.state.getStubToFunctionMap(locked).upper_bound(Stub); 253dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray assert(I != JR.state.getStubToFunctionMap(locked).begin() && 254dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray "This is not a known stub!"); 255dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray F = (--I)->second; 256dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray ActualPtr = I->first; 257dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray } 2585426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 2599da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // If we have already code generated the function, just return the address. 2609da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng void *Result = TheJIT->getPointerToGlobalIfAvailable(F); 2619da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng 2629da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng if (!Result) { 2639da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // Otherwise we don't have it, do lazy compilation now. 2649da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng 2659da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // If lazy compilation is disabled, emit a useful error message and abort. 2669da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng if (TheJIT->isLazyCompilationDisabled()) { 2679da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng cerr << "LLVM JIT requested to do lazy compilation of function '" 2689da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng << F->getName() << "' when lazy compiles are disabled!\n"; 2699da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng abort(); 2709da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng } 2719cab56d59e2ed6af5fb5137a6e50d4bf915eaccfChris Lattner 2729da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // We might like to remove the stub from the StubToFunction map. 2739da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // We can't do that! Multiple threads could be stuck, waiting to acquire the 2749da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // lock above. As soon as the 1st function finishes compiling the function, 2759da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // the next one will be released, and needs to be able to find the function 2769da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng // it needs to call. 2779da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng //JR.state.getStubToFunctionMap(locked).erase(I); 2789da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng 2799da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng DOUT << "JIT: Lazily resolving function '" << F->getName() 2809da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng << "' In stub ptr = " << Stub << " actual ptr = " 281dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray << ActualPtr << "\n"; 2829da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng 2839da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng Result = TheJIT->getPointerToFunction(F); 2849da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng } 285dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray 286dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray // Reacquire the lock to erase the stub in the map. 287dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray MutexGuard locked(TheJIT->lock); 2885426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 2895426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // We don't need to reuse this stub in the future, as F is now compiled. 290ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer JR.state.getFunctionToStubMap(locked).erase(F); 2915426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 2925426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // FIXME: We could rewrite all references to this stub if we knew them. 2936a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 294d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen // What we will do is set the compiled function address to map to the 295d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen // same GOT entry as the stub so that later clients may update the GOT 2966a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // if they see it still using the stub address. 2976a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // Note: this is done so the Resolver doesn't have to manage GOT memory 2986a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // Do this without allocating map space if the target isn't using a GOT 2996a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth if(JR.revGOTMap.find(Stub) != JR.revGOTMap.end()) 3006a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth JR.revGOTMap[Result] = JR.revGOTMap[Stub]; 3016a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 3025426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return Result; 3035426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 3045426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 3058ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner//===----------------------------------------------------------------------===// 3068ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// Function Index Support 3078ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3088ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// On MacOS we generate an index of currently JIT'd functions so that 3098ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// performance tools can determine a symbol name and accurate code range for a 3108ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// PC value. Because performance tools are generally asynchronous, the code 3118ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// below is written with the hope that it could be interrupted at any time and 3128ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// have useful answers. However, we don't go crazy with atomic operations, we 3138ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// just do a "reasonable effort". 3148ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#ifdef __APPLE__ 315bdb6ca178cfbe2490a058deabce7847a05f55db7Evan Cheng#define ENABLE_JIT_SYMBOL_TABLE 0 3168ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif 3178ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3188ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// JitSymbolEntry - Each function that is JIT compiled results in one of these 3198ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// being added to an array of symbols. This indicates the name of the function 3208ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// as well as the address range it occupies. This allows the client to map 3218ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// from a PC value to the name of the function. 3228ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstruct JitSymbolEntry { 3238ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner const char *FnName; // FnName - a strdup'd string. 3248ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner void *FnStart; 3258ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner intptr_t FnSize; 3268ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner}; 3278ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3288ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3298ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstruct JitSymbolTable { 3308ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// NextPtr - This forms a linked list of JitSymbolTable entries. This 3318ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// pointer is not used right now, but might be used in the future. Consider 3328ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// it reserved for future use. 3338ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable *NextPtr; 3348ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3358ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// Symbols - This is an array of JitSymbolEntry entries. Only the first 3368ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// 'NumSymbols' symbols are valid. 3378ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolEntry *Symbols; 3388ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3398ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// NumSymbols - This indicates the number entries in the Symbols array that 3408ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// are valid. 3418ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner unsigned NumSymbols; 3428ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3438ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// NumAllocated - This indicates the amount of space we have in the Symbols 3448ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner /// array. This is a private field that should not be read by external tools. 3458ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner unsigned NumAllocated; 3468ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner}; 3478ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3488ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if ENABLE_JIT_SYMBOL_TABLE 3498ac66c122b099bc3eab858bfc18f3cb342efc818Chris LattnerJitSymbolTable *__jitSymbolTable; 3508ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif 3518ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3528ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstatic void AddFunctionToSymbolTable(const char *FnName, 3538ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner void *FnStart, intptr_t FnSize) { 3548ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner assert(FnName != 0 && FnStart != 0 && "Bad symbol to add"); 3558ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable **SymTabPtrPtr = 0; 3568ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if !ENABLE_JIT_SYMBOL_TABLE 3578ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner return; 3588ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#else 3598ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner SymTabPtrPtr = &__jitSymbolTable; 3608ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif 3618ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3628ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // If this is the first entry in the symbol table, add the JitSymbolTable 3638ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // index. 3648ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner if (*SymTabPtrPtr == 0) { 3658ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable *New = new JitSymbolTable(); 3668ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner New->NextPtr = 0; 3678ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner New->Symbols = 0; 3688ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner New->NumSymbols = 0; 3698ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner New->NumAllocated = 0; 3708ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner *SymTabPtrPtr = New; 3718ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner } 3728ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3738ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable *SymTabPtr = *SymTabPtrPtr; 3748ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3758ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // If we have space in the table, reallocate the table. 3768ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner if (SymTabPtr->NumSymbols >= SymTabPtr->NumAllocated) { 3778ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // If we don't have space, reallocate the table. 3783b374489041ac28153c84194dda45e182d8939fcChris Lattner unsigned NewSize = std::max(64U, SymTabPtr->NumAllocated*2); 3798ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolEntry *NewSymbols = new JitSymbolEntry[NewSize]; 3808ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolEntry *OldSymbols = SymTabPtr->Symbols; 3818ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3828ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Copy the old entries over. 3838ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner memcpy(NewSymbols, OldSymbols, 3843b374489041ac28153c84194dda45e182d8939fcChris Lattner SymTabPtr->NumSymbols*sizeof(OldSymbols[0])); 3858ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3868ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Swap the new symbols in, delete the old ones. 3878ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner SymTabPtr->Symbols = NewSymbols; 3883b374489041ac28153c84194dda45e182d8939fcChris Lattner SymTabPtr->NumAllocated = NewSize; 3898ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner delete [] OldSymbols; 3908ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner } 3918ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 3928ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Otherwise, we have enough space, just tack it onto the end of the array. 3938ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolEntry &Entry = SymTabPtr->Symbols[SymTabPtr->NumSymbols]; 3948ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner Entry.FnName = strdup(FnName); 3958ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner Entry.FnStart = FnStart; 3968ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner Entry.FnSize = FnSize; 3978ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner ++SymTabPtr->NumSymbols; 3988ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner} 3998ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4008ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstatic void RemoveFunctionFromSymbolTable(void *FnStart) { 4018ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner assert(FnStart && "Invalid function pointer"); 4028ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable **SymTabPtrPtr = 0; 4038ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if !ENABLE_JIT_SYMBOL_TABLE 4048ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner return; 4058ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#else 4068ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner SymTabPtrPtr = &__jitSymbolTable; 4078ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif 4088ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4098ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolTable *SymTabPtr = *SymTabPtrPtr; 4108ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner JitSymbolEntry *Symbols = SymTabPtr->Symbols; 4118ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4128ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Scan the table to find its index. The table is not sorted, so do a linear 4138ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // scan. 4148ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner unsigned Index; 4158ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner for (Index = 0; Symbols[Index].FnStart != FnStart; ++Index) 4168ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner assert(Index != SymTabPtr->NumSymbols && "Didn't find function!"); 4178ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4188ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Once we have an index, we know to nuke this entry, overwrite it with the 4198ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // entry at the end of the array, making the last entry redundant. 4208ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner const char *OldName = Symbols[Index].FnName; 4218ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner Symbols[Index] = Symbols[SymTabPtr->NumSymbols-1]; 4228ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner free((void*)OldName); 4238ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4248ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Drop the number of symbols in the table. 4258ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner --SymTabPtr->NumSymbols; 4268ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4278ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Finally, if we deleted the final symbol, deallocate the table itself. 428f44085a86a3f3cb743fb8822108d8360dd094539Nate Begeman if (SymTabPtr->NumSymbols != 0) 4298ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner return; 4308ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 4318ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner *SymTabPtrPtr = 0; 4328ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner delete [] Symbols; 4338ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner delete SymTabPtr; 4348ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner} 4355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 4365426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//===----------------------------------------------------------------------===// 437166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner// JITEmitter code. 4385426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// 439688506de24f04682f9d8563a7d20ab15ab85340bChris Lattnernamespace { 440166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is 441166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner /// used to output functions to memory for execution. 442166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner class JITEmitter : public MachineCodeEmitter { 4438907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner JITMemoryManager *MemMgr; 444688506de24f04682f9d8563a7d20ab15ab85340bChris Lattner 4456125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner // When outputting a function stub in the context of some other function, we 44643b429b05989075b60693d57395c99b0ad789f8dChris Lattner // save BufferBegin/BufferEnd/CurBufferPtr here. 44743b429b05989075b60693d57395c99b0ad789f8dChris Lattner unsigned char *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr; 448bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 4495be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner /// Relocations - These are the relocations that the function needs, as 4505be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner /// emitted. 4515be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner std::vector<MachineRelocation> Relocations; 452b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner 453b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner /// MBBLocations - This vector is a mapping from MBB ID's to their address. 454b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner /// It is filled in by the StartMachineBasicBlock callback and queried by 455b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner /// the getMachineBasicBlockAddress callback. 456b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner std::vector<intptr_t> MBBLocations; 45716ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth 458239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner /// ConstantPool - The constant pool for the current function. 459239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner /// 460239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner MachineConstantPool *ConstantPool; 461239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner 462239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner /// ConstantPoolBase - A pointer to the first entry in the constant pool. 463239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner /// 464239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner void *ConstantPoolBase; 46537efe6764568a3829fee26aba532283131d1a104Nate Begeman 466019f851ab26511c089e41b61901f743e75f90714Nate Begeman /// JumpTable - The jump tables for the current function. 46737efe6764568a3829fee26aba532283131d1a104Nate Begeman /// 46837efe6764568a3829fee26aba532283131d1a104Nate Begeman MachineJumpTableInfo *JumpTable; 46937efe6764568a3829fee26aba532283131d1a104Nate Begeman 47037efe6764568a3829fee26aba532283131d1a104Nate Begeman /// JumpTableBase - A pointer to the first entry in the jump table. 47137efe6764568a3829fee26aba532283131d1a104Nate Begeman /// 47237efe6764568a3829fee26aba532283131d1a104Nate Begeman void *JumpTableBase; 4732a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng 474e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner /// Resolver - This contains info about the currently resolved functions. 475e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner JITResolver Resolver; 476afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 477afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// DE - The dwarf emitter for the jit. 478afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray JITDwarfEmitter *DE; 479afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 480afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// LabelLocations - This vector is a mapping from Label ID's to their 481afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// address. 482afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray std::vector<intptr_t> LabelLocations; 483afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 484afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray /// MMI - Machine module info for exception informations 485afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray MachineModuleInfo* MMI; 486afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 487dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // GVSet - a set to keep track of which globals have been seen 48847c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng SmallPtrSet<const GlobalVariable*, 8> GVSet; 489dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 490e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner public: 4919f2f142d255bc96f109dd5c6524a485937b1f3a1Chris Lattner JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit) { 4929f2f142d255bc96f109dd5c6524a485937b1f3a1Chris Lattner MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager(); 4938907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (jit.getJITInfo().needsGOT()) { 4948907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemMgr->AllocateGOT(); 4958907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner DOUT << "JIT is managing a GOT\n"; 4968907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 497afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 498afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (ExceptionHandling) DE = new JITDwarfEmitter(jit); 4998907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner } 5008907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ~JITEmitter() { 5018907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner delete MemMgr; 502afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (ExceptionHandling) delete DE; 50316ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth } 504a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng 505a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng /// classof - Methods for support type inquiry through isa, cast, and 506a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng /// dyn_cast: 507a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng /// 508a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng static inline bool classof(const JITEmitter*) { return true; } 509a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng static inline bool classof(const MachineCodeEmitter*) { return true; } 510e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner 511e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner JITResolver &getJITResolver() { return Resolver; } 512bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 513bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner virtual void startFunction(MachineFunction &F); 51443b429b05989075b60693d57395c99b0ad789f8dChris Lattner virtual bool finishFunction(MachineFunction &F); 515f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 516f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner void emitConstantPool(MachineConstantPool *MCP); 517f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner void initJumpTableInfo(MachineJumpTableInfo *MJTI); 518b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey void emitJumpTableInfo(MachineJumpTableInfo *MJTI); 519f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 52051cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray virtual void startFunctionStub(const GlobalValue* F, unsigned StubSize, 52151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray unsigned Alignment = 1); 52251cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray virtual void* finishFunctionStub(const GlobalValue *F); 523bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 524cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes /// allocateSpace - Reserves space in the current block if any, or 525cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes /// allocate a new one of the given size. 526cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes virtual void *allocateSpace(intptr_t Size, unsigned Alignment); 527cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 5285be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner virtual void addRelocation(const MachineRelocation &MR) { 5295be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner Relocations.push_back(MR); 5305be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner } 531b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner 532b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { 533b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner if (MBBLocations.size() <= (unsigned)MBB->getNumber()) 534b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner MBBLocations.resize((MBB->getNumber()+1)*2); 535b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner MBBLocations[MBB->getNumber()] = getCurrentPCValue(); 536366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng DOUT << "JIT: Emitting BB" << MBB->getNumber() << " at [" 537366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng << (void*) getCurrentPCValue() << "]\n"; 538b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner } 539b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner 540b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const; 541b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const; 5422a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng 543b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { 544b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner assert(MBBLocations.size() > (unsigned)MBB->getNumber() && 545b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner MBBLocations[MBB->getNumber()] && "MBB not emitted!"); 546b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner return MBBLocations[MBB->getNumber()]; 547b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner } 5485be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner 549e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner /// deallocateMemForFunction - Deallocate all memory for the specified 550e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner /// function body. 551e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner void deallocateMemForFunction(Function *F) { 5528907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner MemMgr->deallocateMemForFunction(F); 553e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner } 554afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 555afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray virtual void emitLabel(uint64_t LabelID) { 556afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (LabelLocations.size() <= LabelID) 557afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray LabelLocations.resize((LabelID+1)*2); 558afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray LabelLocations[LabelID] = getCurrentPCValue(); 559afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 560afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 561afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray virtual intptr_t getLabelAddress(uint64_t LabelID) const { 562afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray assert(LabelLocations.size() > (unsigned)LabelID && 563afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray LabelLocations[LabelID] && "Label not emitted!"); 564afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray return LabelLocations[LabelID]; 565afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 566afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 567afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray virtual void setModuleInfo(MachineModuleInfo* Info) { 568afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray MMI = Info; 569afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (ExceptionHandling) DE->setModuleInfo(Info); 570afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 571afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 572cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach void setMemoryExecutable(void) { 573cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach MemMgr->setMemoryExecutable(); 574cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach } 575cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach 5765426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner private: 5775e225588530f641d6627becadffdd7d285bfcdbaChris Lattner void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); 578c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng void *getPointerToGVNonLazyPtr(GlobalValue *V, void *Reference, 579c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng bool NoNeedStub); 580dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size); 581dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size); 582dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size); 583dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF); 584bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner }; 585bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 586bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 587166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference, 588166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner bool DoesntNeedStub) { 5895426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) { 5905426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// FIXME: If we straightened things out, this could actually emit the 5915426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner /// global immediately instead of queuing it for codegen later! 5925426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner return TheJIT->getOrEmitGlobalVariable(GV); 5935426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner } 59418e045983757a7d2bae482d2abe444a5bb3ed134Chris Lattner if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V)) 59519e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikov return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false)); 5965426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 5975426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // If we have already compiled the function, return a pointer to its body. 5985426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner Function *F = cast<Function>(V); 5995426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F); 6005426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner if (ResultPtr) return ResultPtr; 6015426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 602a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) { 6035426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // If this is an external function pointer, we can force the JIT to 6045426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // 'compile' it, which really just adds it to the map. 605b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner if (DoesntNeedStub) 606b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner return TheJIT->getPointerToFunction(F); 607b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner 608e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner return Resolver.getFunctionStub(F); 6095426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner } 6105426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 6115e225588530f641d6627becadffdd7d285bfcdbaChris Lattner // Okay, the function has not been compiled yet, if the target callback 6125e225588530f641d6627becadffdd7d285bfcdbaChris Lattner // mechanism is capable of rewriting the instruction directly, prefer to do 6135e225588530f641d6627becadffdd7d285bfcdbaChris Lattner // that instead of emitting a stub. 6145e225588530f641d6627becadffdd7d285bfcdbaChris Lattner if (DoesntNeedStub) 615e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner return Resolver.AddCallbackAtLocation(F, Reference); 6165e225588530f641d6627becadffdd7d285bfcdbaChris Lattner 6175426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner // Otherwise, we have to emit a lazy resolving stub. 618e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner return Resolver.getFunctionStub(F); 6195426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner} 6205426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner 621c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Chengvoid *JITEmitter::getPointerToGVNonLazyPtr(GlobalValue *V, void *Reference, 622be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng bool DoesntNeedStub) { 623be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng // Make sure GV is emitted first. 624be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng // FIXME: For now, if the GV is an external function we force the JIT to 625c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng // compile it so the non-lazy pointer will contain the fully resolved address. 626be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng void *GVAddress = getPointerToGlobal(V, Reference, true); 627c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng return Resolver.getGlobalValueNonLazyPtr(V, GVAddress); 628be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng} 629be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 630dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffraystatic unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP) { 631dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 632dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray if (Constants.empty()) return 0; 633dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 634dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray MachineConstantPoolEntry CPE = Constants.back(); 635dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray unsigned Size = CPE.Offset; 636dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray const Type *Ty = CPE.isMachineConstantPoolEntry() 637dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType(); 638dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray Size += TheJIT->getTargetData()->getABITypeSize(Ty); 639dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray return Size; 640dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray} 641dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 642dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffraystatic unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) { 643dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 644dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray if (JT.empty()) return 0; 645dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 646dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray unsigned NumEntries = 0; 647dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray for (unsigned i = 0, e = JT.size(); i != e; ++i) 648dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray NumEntries += JT[i].MBBs.size(); 649dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 650dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray unsigned EntrySize = MJTI->getEntrySize(); 651dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 652dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray return NumEntries * EntrySize; 653dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray} 654dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 655580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffraystatic uintptr_t RoundUpToAlign(uintptr_t Size, unsigned Alignment) { 656dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray if (Alignment == 0) Alignment = 1; 657580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray // Since we do not know where the buffer will be allocated, be pessimistic. 658580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray return Size + Alignment; 659dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray} 660be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng 661dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGlobal - add the size of the global (plus any alignment padding) 662dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// into the running total Size. 663dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 664dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) { 665dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const Type *ElTy = GV->getType()->getElementType(); 666dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen size_t GVSize = (size_t)TheJIT->getTargetData()->getABITypeSize(ElTy); 667dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen size_t GVAlign = 668dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV); 669eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign; 670dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen DEBUG(GV->dump()); 671dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // Assume code section ends with worst possible alignment, so first 672dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // variable needs maximal padding. 673dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (Size==0) 674dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = 1; 675dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = ((Size+GVAlign-1)/GVAlign)*GVAlign; 676dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size += GVSize; 677dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen return Size; 678dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen} 679dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 680dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGlobalsInConstantVal - find any globals that we haven't seen yet 681dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// but are referenced from the constant; put them in GVSet and add their 682dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// size into the running total Size. 683dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 684dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C, 685dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned Size) { 686dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // If its undefined, return the garbage. 687dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (isa<UndefValue>(C)) 688dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen return Size; 689dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 690dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // If the value is a ConstantExpr 691dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { 692dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Constant *Op0 = CE->getOperand(0); 693dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen switch (CE->getOpcode()) { 694dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::GetElementPtr: 695dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Trunc: 696dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::ZExt: 697dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::SExt: 698dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::FPTrunc: 699dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::FPExt: 700dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::UIToFP: 701dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::SIToFP: 702dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::FPToUI: 703dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::FPToSI: 704dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::PtrToInt: 705dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::IntToPtr: 706dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::BitCast: { 707dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobalsInConstantVal(Op0, Size); 708dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen break; 709dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 710dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Add: 711dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Sub: 712dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Mul: 713dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::UDiv: 714dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::SDiv: 715dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::URem: 716dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::SRem: 717dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::And: 718dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Or: 719dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen case Instruction::Xor: { 720dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobalsInConstantVal(Op0, Size); 721dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size); 722dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen break; 723dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 724dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen default: { 725dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen cerr << "ConstantExpr not handled: " << *CE << "\n"; 726dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen abort(); 727dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 728dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 729dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 730dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 731dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (C->getType()->getTypeID() == Type::PointerTyID) 732dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C)) 73347c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (GVSet.insert(GV)) 734dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobal(GV, Size); 735dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 736dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen return Size; 737dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen} 738dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 739dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGLobalsInInitializer - handle any globals that we haven't seen yet 740dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// but are referenced from the given initializer. 741dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 742dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant *Init, 743dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned Size) { 744dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (!isa<UndefValue>(Init) && 745dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen !isa<ConstantVector>(Init) && 746dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen !isa<ConstantAggregateZero>(Init) && 747dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen !isa<ConstantArray>(Init) && 748dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen !isa<ConstantStruct>(Init) && 749dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Init->getType()->isFirstClassType()) 750dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobalsInConstantVal(Init, Size); 751dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen return Size; 752dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen} 753dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 754dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// GetSizeOfGlobalsInBytes - walk the code for the function, looking for 755dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// globals; then walk the initializers of those globals looking for more. 756dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// If their size has not been considered yet, add it into the running total 757dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// Size. 758dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 759dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) { 760dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned Size = 0; 761dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen GVSet.clear(); 762dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 763dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen for (MachineFunction::iterator MBB = MF.begin(), E = MF.end(); 764dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen MBB != E; ++MBB) { 765dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end(); 766dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen I != E; ++I) { 767dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const TargetInstrDesc &Desc = I->getDesc(); 768dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const MachineInstr &MI = *I; 769dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen unsigned NumOps = Desc.getNumOperands(); 770dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen for (unsigned CurOp = 0; CurOp < NumOps; CurOp++) { 771dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const MachineOperand &MO = MI.getOperand(CurOp); 772d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman if (MO.isGlobal()) { 773dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen GlobalValue* V = MO.getGlobal(); 774dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const GlobalVariable *GV = dyn_cast<const GlobalVariable>(V); 775dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (!GV) 776dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen continue; 777dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // If seen in previous function, it will have an entry here. 778dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (TheJIT->getPointerToGlobalIfAvailable(GV)) 779dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen continue; 780dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // If seen earlier in this function, it will have an entry here. 781dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // FIXME: it should be possible to combine these tables, by 782dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // assuming the addresses of the new globals in this module 783dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // start at 0 (or something) and adjusting them after codegen 784dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // complete. Another possibility is to grab a marker bit in GV. 78547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (GVSet.insert(GV)) 786dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // A variable as yet unseen. Add in its size. 787dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobal(GV, Size); 788dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 789dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 790dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 791dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 792eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: About to look through initializers\n"; 793dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // Look for more globals that are referenced only from initializers. 794dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // GVSet.end is computed each time because the set can grow as we go. 79547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin(); 796dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen I != GVSet.end(); I++) { 797dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen const GlobalVariable* GV = *I; 798dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen if (GV->hasInitializer()) 799dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size); 800dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen } 801dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 802dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen return Size; 803dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen} 804dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 805166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::startFunction(MachineFunction &F) { 806eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: Starting CodeGen of Function " 807eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng << F.getFunction()->getName() << "\n"; 808eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng 809dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray uintptr_t ActualSize = 0; 810cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach // Set the memory writable, if it's not already 811cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach MemMgr->setMemoryWritable(); 8125913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray if (MemMgr->NeedsExactSize()) { 813eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: ExactSize\n"; 814dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray const TargetInstrInfo* TII = F.getTarget().getInstrInfo(); 815dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray MachineJumpTableInfo *MJTI = F.getJumpTableInfo(); 816dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray MachineConstantPool *MCP = F.getConstantPool(); 817dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 818dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Ensure the constant pool/jump table info is at least 4-byte aligned. 819580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray ActualSize = RoundUpToAlign(ActualSize, 16); 820dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 821dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the alignment of the constant pool 822580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray ActualSize = RoundUpToAlign(ActualSize, 823580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray 1 << MCP->getConstantPoolAlignment()); 824dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 825dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the constant pool size 826dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray ActualSize += GetConstantPoolSizeInBytes(MCP); 827dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 828dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the aligment of the jump table info 829580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment()); 830dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 831dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the jump table size 832dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray ActualSize += GetJumpTableSizeInBytes(MJTI); 833dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 834dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the alignment for the function 835580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray ActualSize = RoundUpToAlign(ActualSize, 836580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray std::max(F.getFunction()->getAlignment(), 8U)); 837dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 838dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray // Add the function size 839dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray ActualSize += TII->GetFunctionSizeInBytes(F); 840dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 841eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: ActualSize before globals " << ActualSize << "\n"; 842dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // Add the size of the globals that will be allocated after this function. 843dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // These are all the ones referenced from this function that were not 844dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen // previously allocated. 845dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen ActualSize += GetSizeOfGlobalsInBytes(F); 846eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: ActualSize after globals " << ActualSize << "\n"; 847dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray } 848dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 8498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(), 8508907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ActualSize); 851e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner BufferEnd = BufferBegin+ActualSize; 852f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 8539a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng // Ensure the constant pool/jump table info is at least 4-byte aligned. 8549a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng emitAlignment(16); 8559a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng 856f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner emitConstantPool(F.getConstantPool()); 857f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner initJumpTableInfo(F.getJumpTableInfo()); 858f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 859f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner // About to start emitting the machine code for the function. 8600eb4d6b52e1b5db9a4c86e5a954356ae3507a287Chris Lattner emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); 861f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); 86255fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 863b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner MBBLocations.clear(); 864bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 865bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 86643b429b05989075b60693d57395c99b0ad789f8dChris Lattnerbool JITEmitter::finishFunction(MachineFunction &F) { 867e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner if (CurBufferPtr == BufferEnd) { 868e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // FIXME: Allocate more space, then try again. 869832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling cerr << "JIT: Ran out of space for generated machine code!\n"; 870e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner abort(); 871e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner } 872e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 873b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey emitJumpTableInfo(F.getJumpTableInfo()); 874b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner 875a827953c32e420740c281b4a38a056d15b180932Chris Lattner // FnStart is the start of the text, not the start of the constant pool and 876a827953c32e420740c281b4a38a056d15b180932Chris Lattner // other per-function data. 877a827953c32e420740c281b4a38a056d15b180932Chris Lattner unsigned char *FnStart = 878a827953c32e420740c281b4a38a056d15b180932Chris Lattner (unsigned char *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction()); 879bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 8805be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner if (!Relocations.empty()) { 881e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner NumRelos += Relocations.size(); 882e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner 8835be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner // Resolve the relocations to concrete pointers. 8845be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner for (unsigned i = 0, e = Relocations.size(); i != e; ++i) { 8855be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner MachineRelocation &MR = Relocations[i]; 8869200605cd5f6db50be20efb7df926dc5a0d19a4dEvan Cheng void *ResultPtr = 0; 887ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng if (!MR.letTargetResolve()) { 888ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng if (MR.isString()) { 889ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = TheJIT->getPointerToNamedFunction(MR.getString()); 890ca66b08bc6c3cf899459e642a5297df8b9ccdb0dEvan Cheng DOUT << "JIT: Map \'" << MR.getString() << "\' to [" 891ca66b08bc6c3cf899459e642a5297df8b9ccdb0dEvan Cheng << ResultPtr << "]\n"; 892ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng 893ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng // If the target REALLY wants a stub for this function, emit it now. 894ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng if (!MR.doesntNeedStub()) 895ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = Resolver.getExternalFunctionStub(ResultPtr); 896ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isGlobalValue()) { 897ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = getPointerToGlobal(MR.getGlobalValue(), 898ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng BufferBegin+MR.getMachineCodeOffset(), 899ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng MR.doesntNeedStub()); 900c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng } else if (MR.isGlobalValueNonLazyPtr()) { 901c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng ResultPtr = getPointerToGVNonLazyPtr(MR.getGlobalValue(), 902be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng BufferBegin+MR.getMachineCodeOffset(), 903be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng MR.doesntNeedStub()); 904ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isBasicBlock()) { 905ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock()); 906ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else if (MR.isConstantPoolIndex()) { 907ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr = (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex()); 908ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } else { 909ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng assert(MR.isJumpTableIndex()); 910ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex()); 911ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } 91200b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen 913ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng MR.setResultPointer(ResultPtr); 914ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng } 91516ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth 9166a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // if we are managing the GOT and the relocation wants an index, 9176a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth // give it one 9188907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (MR.isGOTRelative() && MemMgr->isManagingGOT()) { 919e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr); 9206a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth MR.setGOTIndex(idx); 9218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) { 922eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: GOT was out of date for " << ResultPtr 9238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] 924832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << "\n"; 9258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ((void**)MemMgr->getGOTBase())[idx] = ResultPtr; 9266a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 92716ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth } 9285be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner } 9295be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner 93043b429b05989075b60693d57395c99b0ad789f8dChris Lattner TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0], 9318907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner Relocations.size(), MemMgr->getGOTBase()); 9325be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner } 9335be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner 934d2d5c76753b132c34c71248db2f136b38531bc6dChris Lattner // Update the GOT entry for F to point to the new code. 9358907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (MemMgr->isManagingGOT()) { 936e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin); 9378907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) { 938eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: GOT was out of date for " << (void*)BufferBegin 9398907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n"; 9408907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin; 9416a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 9426a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth } 9436a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth 944cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes unsigned char *FnEnd = CurBufferPtr; 945cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 946cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes MemMgr->endFunctionBody(F.getFunction(), BufferBegin, FnEnd); 947cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferBegin = CurBufferPtr = 0; 948cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes NumBytes += FnEnd-FnStart; 949cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 95055fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng // Invalidate the icache if necessary. 951bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart); 9528ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 9538ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner // Add it to the JIT symbol table if the host wants it. 9548ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner AddFunctionToSymbolTable(F.getFunction()->getNameStart(), 9558ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner FnStart, FnEnd-FnStart); 95655fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng 957832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling DOUT << "JIT: Finished CodeGen of [" << (void*)FnStart 958832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << "] Function: " << F.getFunction()->getName() 959832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << ": " << (FnEnd-FnStart) << " bytes of text, " 960832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << Relocations.size() << " relocations\n"; 9615be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner Relocations.clear(); 9628cd4c3e6534a14566bf163301fd45bca34e655c1Anton Korobeynikov 963bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng // Mark code region readable and executable if it's not so already. 964cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach MemMgr->setMemoryExecutable(); 965bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng 966c5633c235e94f69c6a77e894bcc84d8ba71106f0Chris Lattner#ifndef NDEBUG 967a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng { 968eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: Disassembled code:\n"; 969a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng if (sys::hasDisassembler()) 970eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart); 971a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng else { 972a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng DOUT << std::hex; 973a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng int i; 974a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng unsigned char* q = FnStart; 975a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng for (i=1; q!=FnEnd; q++, i++) { 976a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng if (i%8==1) 977eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng DOUT << "JIT: 0x" << (long)q << ": "; 978a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng DOUT<< std::setw(2) << std::setfill('0') << (unsigned short)*q << " "; 979a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng if (i%8==0) 9806863fb033a9079e04edc7a568e34098bcf5b9ebeEvan Cheng DOUT << '\n'; 981a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng } 982a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng DOUT << std::dec; 9836863fb033a9079e04edc7a568e34098bcf5b9ebeEvan Cheng DOUT<< '\n'; 984a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng } 985a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng } 986c5633c235e94f69c6a77e894bcc84d8ba71106f0Chris Lattner#endif 987afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray if (ExceptionHandling) { 988dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray uintptr_t ActualSize = 0; 989afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray SavedBufferBegin = BufferBegin; 990afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray SavedBufferEnd = BufferEnd; 991afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray SavedCurBufferPtr = CurBufferPtr; 992dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray 9935913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray if (MemMgr->NeedsExactSize()) { 9945913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd); 995dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray } 996afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 997afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(), 998afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray ActualSize); 999afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray BufferEnd = BufferBegin+ActualSize; 1000afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd); 10010fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr, 10020fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner FrameRegister); 1003afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray BufferBegin = SavedBufferBegin; 1004afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray BufferEnd = SavedBufferEnd; 1005afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray CurBufferPtr = SavedCurBufferPtr; 1006afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 1007afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray TheJIT->RegisterTable(FrameRegister); 1008afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray } 1009252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng 1010252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng if (MMI) 1011252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng MMI->EndFunction(); 1012afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray 101343b429b05989075b60693d57395c99b0ad789f8dChris Lattner return false; 1014bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner} 1015bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner 1016cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopesvoid* JITEmitter::allocateSpace(intptr_t Size, unsigned Alignment) { 1017cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes if (BufferBegin) 1018cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes return MachineCodeEmitter::allocateSpace(Size, Alignment); 1019cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 1020cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // create a new memory block if there is no active one. 1021cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // care must be taken so that BufferBegin is invalidated when a 1022cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes // block is trimmed 1023cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment); 1024cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes BufferEnd = BufferBegin+Size; 1025cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes return CurBufferPtr; 1026cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes} 1027cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes 1028166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::emitConstantPool(MachineConstantPool *MCP) { 102947c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomConstantPool()) 10308fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach return; 103147c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 1032fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants(); 10332c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner if (Constants.empty()) return; 10342c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner 1035cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng MachineConstantPoolEntry CPE = Constants.back(); 1036cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng unsigned Size = CPE.Offset; 1037cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng const Type *Ty = CPE.isMachineConstantPoolEntry() 10388a650095fcecaf5270231bd376e49ed46249da95Chris Lattner ? CPE.Val.MachineCPVal->getType() : CPE.Val.ConstVal->getType(); 1039514ab348fddcdffa8367685dc608b2f8d5de986dDuncan Sands Size += TheJIT->getTargetData()->getABITypeSize(Ty); 10403029f920519e0871a5aad5d7c592281093953733Chris Lattner 104197b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng unsigned Align = 1 << MCP->getConstantPoolAlignment(); 104297b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng ConstantPoolBase = allocateSpace(Size, Align); 1043239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner ConstantPool = MCP; 1044f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 1045f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner if (ConstantPoolBase == 0) return; // Buffer overflow. 1046f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 104797b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng DOUT << "JIT: Emitted constant pool at [" << ConstantPoolBase 104897b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng << "] (size: " << Size << ", alignment: " << Align << ")\n"; 104997b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng 1050239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner // Initialize the memory for all of the constant pool entries. 10513029f920519e0871a5aad5d7c592281093953733Chris Lattner for (unsigned i = 0, e = Constants.size(); i != e; ++i) { 1052239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner void *CAddr = (char*)ConstantPoolBase+Constants[i].Offset; 1053cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng if (Constants[i].isMachineConstantPoolEntry()) { 1054cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng // FIXME: add support to lower machine constant pool values into bytes! 1055832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling cerr << "Initialize memory with machine specific constant pool entry" 1056832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling << " has not been implemented!\n"; 1057cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng abort(); 1058cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng } 1059cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng TheJIT->InitializeMemory(Constants[i].Val.ConstVal, CAddr); 106097b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng DOUT << "JIT: CP" << i << " at [" << CAddr << "]\n"; 10611cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner } 10621cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner} 10631cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner 106437efe6764568a3829fee26aba532283131d1a104Nate Begemanvoid JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { 106547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomJumpTables()) 106647c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng return; 106747c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 106837efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 106937efe6764568a3829fee26aba532283131d1a104Nate Begeman if (JT.empty()) return; 107037efe6764568a3829fee26aba532283131d1a104Nate Begeman 1071f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner unsigned NumEntries = 0; 107237efe6764568a3829fee26aba532283131d1a104Nate Begeman for (unsigned i = 0, e = JT.size(); i != e; ++i) 1073f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner NumEntries += JT[i].MBBs.size(); 1074f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 1075f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner unsigned EntrySize = MJTI->getEntrySize(); 1076f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner 107737efe6764568a3829fee26aba532283131d1a104Nate Begeman // Just allocate space for all the jump tables now. We will fix up the actual 107837efe6764568a3829fee26aba532283131d1a104Nate Begeman // MBB entries in the tables after we emit the code for each block, since then 107937efe6764568a3829fee26aba532283131d1a104Nate Begeman // we will know the final locations of the MBBs in memory. 108037efe6764568a3829fee26aba532283131d1a104Nate Begeman JumpTable = MJTI; 1081f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment()); 108237efe6764568a3829fee26aba532283131d1a104Nate Begeman} 108337efe6764568a3829fee26aba532283131d1a104Nate Begeman 1084b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskeyvoid JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { 108547c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng if (TheJIT->getJITInfo().hasCustomJumpTables()) 108647c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng return; 108747c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng 108837efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); 1089f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner if (JT.empty() || JumpTableBase == 0) return; 109037efe6764568a3829fee26aba532283131d1a104Nate Begeman 1091b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey if (TargetMachine::getRelocationModel() == Reloc::PIC_) { 1092acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?"); 1093acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // For each jump table, place the offset from the beginning of the table 1094acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // to the target address. 1095acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey int *SlotPtr = (int*)JumpTableBase; 1096acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1097acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey for (unsigned i = 0, e = JT.size(); i != e; ++i) { 1098acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 1099acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // Store the offset of the basic block for this jump table slot in the 1100acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // memory we allocated for the jump table in 'initJumpTableInfo' 1101acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey intptr_t Base = (intptr_t)SlotPtr; 11022a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { 11032a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng intptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); 11042a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base); 11052a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng } 1106acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey } 1107acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey } else { 1108acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?"); 1109acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1110acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // For each jump table, map each target in the jump table to the address of 1111acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // an emitted MachineBasicBlock. 1112acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey intptr_t *SlotPtr = (intptr_t*)JumpTableBase; 1113acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1114acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey for (unsigned i = 0, e = JT.size(); i != e; ++i) { 1115acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs; 1116acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // Store the address of the basic block for this jump table slot in the 1117acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey // memory we allocated for the jump table in 'initJumpTableInfo' 1118acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) 1119acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); 1120acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey } 112137efe6764568a3829fee26aba532283131d1a104Nate Begeman } 112237efe6764568a3829fee26aba532283131d1a104Nate Begeman} 112337efe6764568a3829fee26aba532283131d1a104Nate Begeman 112451cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid JITEmitter::startFunctionStub(const GlobalValue* F, unsigned StubSize, 112551cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray unsigned Alignment) { 112643b429b05989075b60693d57395c99b0ad789f8dChris Lattner SavedBufferBegin = BufferBegin; 112743b429b05989075b60693d57395c99b0ad789f8dChris Lattner SavedBufferEnd = BufferEnd; 112843b429b05989075b60693d57395c99b0ad789f8dChris Lattner SavedCurBufferPtr = CurBufferPtr; 112943b429b05989075b60693d57395c99b0ad789f8dChris Lattner 113051cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray BufferBegin = CurBufferPtr = MemMgr->allocateStub(F, StubSize, Alignment); 113143b429b05989075b60693d57395c99b0ad789f8dChris Lattner BufferEnd = BufferBegin+StubSize+1; 11326125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner} 11336125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner 113451cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffrayvoid *JITEmitter::finishFunctionStub(const GlobalValue* F) { 113543b429b05989075b60693d57395c99b0ad789f8dChris Lattner NumBytes += getCurrentPCOffset(); 1136cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach 1137cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach // Invalidate the icache if necessary. 1138cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach sys::Memory::InvalidateInstructionCache(BufferBegin, NumBytes); 1139cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach 114043b429b05989075b60693d57395c99b0ad789f8dChris Lattner std::swap(SavedBufferBegin, BufferBegin); 114143b429b05989075b60693d57395c99b0ad789f8dChris Lattner BufferEnd = SavedBufferEnd; 114243b429b05989075b60693d57395c99b0ad789f8dChris Lattner CurBufferPtr = SavedCurBufferPtr; 114343b429b05989075b60693d57395c99b0ad789f8dChris Lattner return SavedBufferBegin; 1144bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner} 1145bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 1146bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry 1147bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// in the constant pool that was last emitted with the 'emitConstantPool' 1148bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// method. 1149bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// 1150b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattnerintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { 1151239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner assert(ConstantNum < ConstantPool->getConstants().size() && 11523c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman "Invalid ConstantPoolIndex!"); 1153239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner return (intptr_t)ConstantPoolBase + 1154239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner ConstantPool->getConstants()[ConstantNum].Offset; 1155bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner} 1156bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner 115737efe6764568a3829fee26aba532283131d1a104Nate Begeman// getJumpTableEntryAddress - Return the address of the JumpTable with index 115837efe6764568a3829fee26aba532283131d1a104Nate Begeman// 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' 115937efe6764568a3829fee26aba532283131d1a104Nate Begeman// 1160b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattnerintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { 116137efe6764568a3829fee26aba532283131d1a104Nate Begeman const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables(); 116237efe6764568a3829fee26aba532283131d1a104Nate Begeman assert(Index < JT.size() && "Invalid jump table index!"); 116337efe6764568a3829fee26aba532283131d1a104Nate Begeman 116437efe6764568a3829fee26aba532283131d1a104Nate Begeman unsigned Offset = 0; 116537efe6764568a3829fee26aba532283131d1a104Nate Begeman unsigned EntrySize = JumpTable->getEntrySize(); 116637efe6764568a3829fee26aba532283131d1a104Nate Begeman 116737efe6764568a3829fee26aba532283131d1a104Nate Begeman for (unsigned i = 0; i < Index; ++i) 1168acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey Offset += JT[i].MBBs.size(); 1169acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1170acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey Offset *= EntrySize; 117137efe6764568a3829fee26aba532283131d1a104Nate Begeman 1172c34b22716be8394cd205e31dfeeb94c6033fb34dNate Begeman return (intptr_t)((char *)JumpTableBase + Offset); 117337efe6764568a3829fee26aba532283131d1a104Nate Begeman} 117437efe6764568a3829fee26aba532283131d1a104Nate Begeman 1175e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===// 1176e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// Public interface to this file 1177e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===// 1178e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 11799f2f142d255bc96f109dd5c6524a485937b1f3a1Chris LattnerMachineCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) { 11809f2f142d255bc96f109dd5c6524a485937b1f3a1Chris Lattner return new JITEmitter(jit, JMM); 1181e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1182e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1183d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// getPointerToNamedFunction - This function is used as a global wrapper to 11844d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner// JIT::getPointerToNamedFunction for the purpose of resolving symbols when 1185d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// bugpoint is debugging the JIT. In that scenario, we are loading an .so and 1186d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// need to resolve function(s) that are being mis-codegenerated, so we need to 1187d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// resolve their addresses at runtime, and this is the way to do it. 1188d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukmanextern "C" { 1189d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman void *getPointerToNamedFunction(const char *Name) { 1190fe854034677f59baca1e38075e71f6efca247a03Chris Lattner if (Function *F = TheJIT->FindFunctionNamed(Name)) 11914d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner return TheJIT->getPointerToFunction(F); 11924d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner return TheJIT->getPointerToNamedFunction(Name); 1193d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman } 1194d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman} 1195e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1196e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// getPointerToFunctionOrStub - If the specified function has been 1197e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// code-gen'd, return a pointer to the function. If not, compile it, or use 1198e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// a stub to implement lazy compilation if available. 1199e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// 1200e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid *JIT::getPointerToFunctionOrStub(Function *F) { 1201e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // If we have already code generated the function, just return the address. 1202e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner if (void *Addr = getPointerToGlobalIfAvailable(F)) 1203e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner return Addr; 1204e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1205e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner // Get a stub if the target supports it. 1206a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng assert(isa<JITEmitter>(MCE) && "Unexpected MCE?"); 1207a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng JITEmitter *JE = cast<JITEmitter>(getCodeEmitter()); 1208e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner return JE->getJITResolver().getFunctionStub(F); 1209e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1210e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1211e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner/// freeMachineCodeForFunction - release machine code memory for given Function. 1212e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner/// 1213e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid JIT::freeMachineCodeForFunction(Function *F) { 1214dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen 1215e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // Delete translation for this from the ExecutionEngine, so it will get 1216e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // retranslated next time it is used. 12178ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner void *OldPtr = updateGlobalMapping(F, 0); 12188ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner 12198ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner if (OldPtr) 12208ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner RemoveFunctionFromSymbolTable(OldPtr); 1221e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1222e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner // Free the actual memory for the function body and related stuff. 1223a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng assert(isa<JITEmitter>(MCE) && "Unexpected MCE?"); 1224a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng cast<JITEmitter>(MCE)->deallocateMemForFunction(F); 1225e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner} 1226e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner 1227