JITEmitter.cpp revision 777d2306b36816a53bc1ae1244c0dc7d998ae691
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"
35848b3142addffe24abc775c5a11d5fff8ff73132Nick Lewycky#include "llvm/Support/ValueHandle.h"
36fd58e6e2ecebe92804869586d65b27085110f336Anton Korobeynikov#include "llvm/System/Disassembler.h"
37bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner#include "llvm/System/Memory.h"
38dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray#include "llvm/Target/TargetInstrInfo.h"
3947c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng#include "llvm/ADT/SmallPtrSet.h"
40d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman#include "llvm/ADT/SmallVector.h"
41551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/ADT/Statistic.h"
42a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth#include <algorithm>
43a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#ifndef NDEBUG
44a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#include <iomanip>
45a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng#endif
46c19aadee66b744311afe6e420847e80822a765f2Chris Lattnerusing namespace llvm;
47d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
4836343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumBytes, "Number of bytes of machine code compiled");
4936343735cb23680c8f8675deafbbf825d46fd868Chris LattnerSTATISTIC(NumRelos, "Number of relocations applied");
5036343735cb23680c8f8675deafbbf825d46fd868Chris Lattnerstatic JIT *TheJIT = 0;
51bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
52a00269bc3e97d4e53ed196325ef02e6d1f3d70dcAndrew Lenharth
535426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//===----------------------------------------------------------------------===//
545426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner// JIT lazy compilation code.
555426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//
565426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnernamespace {
57ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  class JITResolverState {
58e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  public:
59e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef std::map<AssertingVH<Function>, void*> FunctionToStubMapTy;
60e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef std::map<void*, Function*> StubToFunctionMapTy;
61e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef std::map<AssertingVH<GlobalValue>, void*> GlobalToIndirectSymMapTy;
62ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  private:
63ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    /// FunctionToStubMap - Keep track of the stub created for a particular
64ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    /// function so that we can reuse them if necessary.
65e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    FunctionToStubMapTy FunctionToStubMap;
66ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer
67ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    /// StubToFunctionMap - Keep track of the function that each stub
68ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    /// corresponds to.
69e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    StubToFunctionMapTy StubToFunctionMap;
7000b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen
715594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng    /// GlobalToIndirectSymMap - Keep track of the indirect symbol created for a
72be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng    /// particular GlobalVariable so that we can reuse them if necessary.
73e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    GlobalToIndirectSymMapTy GlobalToIndirectSymMap;
74be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
75ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  public:
76e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    FunctionToStubMapTy& getFunctionToStubMap(const MutexGuard& locked) {
77ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      assert(locked.holds(TheJIT->lock));
78ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      return FunctionToStubMap;
79ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    }
8000b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen
81e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    StubToFunctionMapTy& getStubToFunctionMap(const MutexGuard& locked) {
82ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      assert(locked.holds(TheJIT->lock));
83ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      return StubToFunctionMap;
84ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    }
85be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
86e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    GlobalToIndirectSymMapTy& getGlobalToIndirectSymMap(const MutexGuard& locked) {
87be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng      assert(locked.holds(TheJIT->lock));
885594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng      return GlobalToIndirectSymMap;
89be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng    }
90ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  };
9100b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen
925426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  /// JITResolver - Keep track of, and resolve, call sites for functions that
935426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  /// have not yet been compiled.
945426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  class JITResolver {
95e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef JITResolverState::FunctionToStubMapTy FunctionToStubMapTy;
96e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef JITResolverState::StubToFunctionMapTy StubToFunctionMapTy;
97e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    typedef JITResolverState::GlobalToIndirectSymMapTy GlobalToIndirectSymMapTy;
98e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky
995e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    /// LazyResolverFn - The target lazy resolver function that we actually
1005e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    /// rewrite instructions to use.
1015e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    TargetJITInfo::LazyResolverFn LazyResolverFn;
1025e225588530f641d6627becadffdd7d285bfcdbaChris Lattner
103ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer    JITResolverState state;
1045426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
105d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    /// ExternalFnToStubMap - This is the equivalent of FunctionToStubMap for
106d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    /// external functions.
107d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    std::map<void*, void*> ExternalFnToStubMap;
1086a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
1091606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    /// revGOTMap - map addresses to indexes in the GOT
1106a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    std::map<void*, unsigned> revGOTMap;
1116a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    unsigned nextGOTIndex;
1126a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
113e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    static JITResolver *TheJITResolver;
1145426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  public:
115950a4c40b823cd4f09dc71be635229246dfd6cacDan Gohman    explicit JITResolver(JIT &jit) : nextGOTIndex(0) {
116e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner      TheJIT = &jit;
117e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner
118e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner      LazyResolverFn = jit.getJITInfo().getLazyResolverFunction(JITCompilerFn);
119e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner      assert(TheJITResolver == 0 && "Multiple JIT resolvers?");
120e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner      TheJITResolver = this;
121e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    }
122e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner
123e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    ~JITResolver() {
124e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner      TheJITResolver = 0;
1255e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    }
1265426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
127704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    /// getFunctionStubIfAvailable - This returns a pointer to a function stub
128704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    /// if it has already been created.
129704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    void *getFunctionStubIfAvailable(Function *F);
130704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng
1315426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    /// getFunctionStub - This returns a pointer to a function stub, creating
132d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    /// one on demand as needed.  If empty is true, create a function stub
133d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    /// pointing at address 0, to be filled in later.
134b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    void *getFunctionStub(Function *F);
1355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
136d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    /// getExternalFunctionStub - Return a stub for the function at the
137d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    /// specified address, created lazily on demand.
138d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner    void *getExternalFunctionStub(void *FnAddr);
139d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner
1405594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng    /// getGlobalValueIndirectSym - Return an indirect symbol containing the
141c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng    /// specified GV address.
1425594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng    void *getGlobalValueIndirectSym(GlobalValue *V, void *GVAddress);
143be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
1445e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    /// AddCallbackAtLocation - If the target is capable of rewriting an
1455e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    /// instruction without the use of a stub, record the location of the use so
1465e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    /// we know which function is being used at the location.
1475e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    void *AddCallbackAtLocation(Function *F, void *Location) {
148ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      MutexGuard locked(TheJIT->lock);
1495e225588530f641d6627becadffdd7d285bfcdbaChris Lattner      /// Get the target-specific JIT resolver function.
150ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer      state.getStubToFunctionMap(locked)[Location] = F;
151870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner      return (void*)(intptr_t)LazyResolverFn;
1525e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    }
153d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
154d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    void getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
15550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman                           SmallVectorImpl<void*> &Ptrs);
15650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
15750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    GlobalValue *invalidateStub(void *Stub);
1585e225588530f641d6627becadffdd7d285bfcdbaChris Lattner
1596a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    /// getGOTIndexForAddress - Return a new or existing index in the GOT for
1608907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    /// an address.  This function only manages slots, it does not manage the
1616a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    /// contents of the slots or the memory associated with the GOT.
1628907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    unsigned getGOTIndexForAddr(void *addr);
1636a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
1645426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    /// JITCompilerFn - This function is called to resolve a stub to a compiled
1655426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    /// address.  If the LLVM Function corresponding to the stub has not yet
1665426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    /// been compiled, this function compiles it first.
1675426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    static void *JITCompilerFn(void *Stub);
1685426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  };
1695426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner}
1705426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
171e748401b180d7041738e14d3896ac61ca4bdfcbaChris LattnerJITResolver *JITResolver::TheJITResolver = 0;
1725426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
173704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng/// getFunctionStubIfAvailable - This returns a pointer to a function stub
174704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng/// if it has already been created.
175704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Chengvoid *JITResolver::getFunctionStubIfAvailable(Function *F) {
176704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng  MutexGuard locked(TheJIT->lock);
177704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng
178704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng  // If we already have a stub for this function, recycle it.
179704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng  void *&Stub = state.getFunctionToStubMap(locked)[F];
180704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng  return Stub;
181704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng}
182704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng
1835426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// getFunctionStub - This returns a pointer to a function stub, creating
1845426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// one on demand as needed.
185b9c6c9bfe410bbea357503872ce662d6838026ceNate Begemanvoid *JITResolver::getFunctionStub(Function *F) {
186ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  MutexGuard locked(TheJIT->lock);
187ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer
1885426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // If we already have a stub for this function, recycle it.
189ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  void *&Stub = state.getFunctionToStubMap(locked)[F];
1905426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  if (Stub) return Stub;
1915426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
192b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // Call the lazy resolver function unless we are JIT'ing non-lazily, in which
193b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // case we must resolve the symbol now.
194b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  void *Actual =  TheJIT->isLazyCompilationDisabled()
195b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    ? (void *)0 : (void *)(intptr_t)LazyResolverFn;
196b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman
197b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // If this is an external declaration, attempt to resolve the address now
198b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // to place in the stub.
19969f9378675b23135043d93aa58300fed3ec41cbfDan Gohman  if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) {
200b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner    Actual = TheJIT->getPointerToFunction(F);
201f976c856fcc5055f3fc7d9f070d72c2d027c1d9dMisha Brukman
20269f9378675b23135043d93aa58300fed3ec41cbfDan Gohman    // If we resolved the symbol to a null address (eg. a weak external)
203b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    // don't emit a stub. Return a null pointer to the application.  If dlsym
204b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    // stubs are enabled, not being able to resolve the address is not
205b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    // meaningful.
206b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    if (!Actual && !TheJIT->areDlsymStubsEnabled()) return 0;
20769f9378675b23135043d93aa58300fed3ec41cbfDan Gohman  }
20869f9378675b23135043d93aa58300fed3ec41cbfDan Gohman
209b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // Codegen a new stub, calling the lazy resolver or the actual address of the
210b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // external function, if it was resolved.
21151cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray  Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual,
212e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner                                               *TheJIT->getCodeEmitter());
213b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner
214870286aa33290c00e55ba479a60251c79f3a7911Chris Lattner  if (Actual != (void*)(intptr_t)LazyResolverFn) {
215b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner    // If we are getting the stub for an external function, we really want the
216b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner    // address of the stub in the GlobalAddressMap for the JIT, not the address
217b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner    // of the external function.
218b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner    TheJIT->updateGlobalMapping(F, Stub);
219b43dbdcb20245db6712b2a5a8b52e9b5d8220fedChris Lattner  }
2205426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
221be3ae8e479c02b3045eef8eb18c4dacbd3af14c2Chris Lattner  DOUT << "JIT: Stub emitted at [" << Stub << "] for function '"
222832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling       << F->getName() << "'\n";
223cb47941556800369216c062dcee8dcab7cd39ee9Chris Lattner
2245426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // Finally, keep track of the stub-to-Function mapping so that the
2255426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // JITCompilerFn knows which function to compile!
226ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  state.getStubToFunctionMap(locked)[Stub] = F;
227d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
228b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // If we are JIT'ing non-lazily but need to call a function that does not
229b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // exist yet, add it to the JIT's work list so that we can fill in the stub
230b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // address later.
231b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  if (!Actual && TheJIT->isLazyCompilationDisabled())
232b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode())
233b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman      TheJIT->addPendingFunction(F);
234d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
2355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  return Stub;
2365426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner}
2375426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
2385594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng/// getGlobalValueIndirectSym - Return a lazy pointer containing the specified
239be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng/// GV address.
2405594f120b8880f7c514b0376c4adac1267a0b2b6Evan Chengvoid *JITResolver::getGlobalValueIndirectSym(GlobalValue *GV, void *GVAddress) {
241be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng  MutexGuard locked(TheJIT->lock);
242be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
243be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng  // If we already have a stub for this global variable, recycle it.
2445594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng  void *&IndirectSym = state.getGlobalToIndirectSymMap(locked)[GV];
2455594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng  if (IndirectSym) return IndirectSym;
246be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
247e4d783d584d22d7fcb4cba2a24e0f45f62ed8153Evan Cheng  // Otherwise, codegen a new indirect symbol.
2485594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng  IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV, GVAddress,
249c96a8e7df1ffeebc5fb876f5eef380e8547ce14fEvan Cheng                                                     *TheJIT->getCodeEmitter());
250be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
2515594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng  DOUT << "JIT: Indirect symbol emitted at [" << IndirectSym << "] for GV '"
252be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng       << GV->getName() << "'\n";
253be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
2545594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng  return IndirectSym;
255be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng}
256be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
257d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// getExternalFunctionStub - Return a stub for the function at the
258d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner/// specified address, created lazily on demand.
259d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattnervoid *JITResolver::getExternalFunctionStub(void *FnAddr) {
260d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner  // If we already have a stub for this function, recycle it.
261d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner  void *&Stub = ExternalFnToStubMap[FnAddr];
262d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner  if (Stub) return Stub;
263d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner
26451cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray  Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr,
265e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner                                               *TheJIT->getCodeEmitter());
26655fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng
267832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling  DOUT << "JIT: Stub emitted at [" << Stub
268832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling       << "] for external function at '" << FnAddr << "'\n";
269d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner  return Stub;
270d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner}
271d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner
2726a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharthunsigned JITResolver::getGOTIndexForAddr(void* addr) {
2736a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  unsigned idx = revGOTMap[addr];
2746a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  if (!idx) {
2756a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    idx = ++nextGOTIndex;
2766a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    revGOTMap[addr] = idx;
277366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng    DOUT << "JIT: Adding GOT entry " << idx << " for addr [" << addr << "]\n";
2786a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  }
2796a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  return idx;
2806a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth}
281d91ff7cd3b08cfe30b731799da8358dd9f90558cChris Lattner
282d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
283d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman                                    SmallVectorImpl<void*> &Ptrs) {
284d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  MutexGuard locked(TheJIT->lock);
285d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
286e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
287e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
288d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
289e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  for (FunctionToStubMapTy::iterator i = FM.begin(), e = FM.end(); i != e; ++i){
290d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    Function *F = i->first;
291d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    if (F->isDeclaration() && F->hasExternalLinkage()) {
292d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman      GVs.push_back(i->first);
293d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman      Ptrs.push_back(i->second);
294d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    }
295d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  }
296e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  for (GlobalToIndirectSymMapTy::iterator i = GM.begin(), e = GM.end();
297d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman       i != e; ++i) {
298d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    GVs.push_back(i->first);
299d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    Ptrs.push_back(i->second);
300d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  }
301d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman}
302d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
30350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate BegemanGlobalValue *JITResolver::invalidateStub(void *Stub) {
30450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  MutexGuard locked(TheJIT->lock);
30550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
306e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
307e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  StubToFunctionMapTy &SM = state.getStubToFunctionMap(locked);
308e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap(locked);
30950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
31050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Look up the cheap way first, to see if it's a function stub we are
31150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // invalidating.  If so, remove it from both the forward and reverse maps.
31250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  if (SM.find(Stub) != SM.end()) {
31350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    Function *F = SM[Stub];
31450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    SM.erase(Stub);
31550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    FM.erase(F);
31650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    return F;
31750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  }
31850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
319841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  // Otherwise, it might be an indirect symbol stub.  Find it and remove it.
320e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky  for (GlobalToIndirectSymMapTy::iterator i = GM.begin(), e = GM.end();
32150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman       i != e; ++i) {
32250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    if (i->second != Stub)
32350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman      continue;
32450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    GlobalValue *GV = i->first;
32550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    GM.erase(i);
32650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    return GV;
32750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  }
32850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
329841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  // Lastly, check to see if it's in the ExternalFnToStubMap.
330841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  for (std::map<void *, void *>::iterator i = ExternalFnToStubMap.begin(),
331841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman       e = ExternalFnToStubMap.end(); i != e; ++i) {
332841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    if (i->second != Stub)
333841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      continue;
334841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    ExternalFnToStubMap.erase(i);
335841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    break;
336841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  }
337841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
33850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  return 0;
33950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman}
34050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
3415426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// JITCompilerFn - This function is called when a lazy compilation stub has
3425426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// been entered.  It looks up which function this stub corresponds to, compiles
3435426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner/// it if necessary, then returns the resultant function pointer.
3445426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattnervoid *JITResolver::JITCompilerFn(void *Stub) {
345e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner  JITResolver &JR = *TheJITResolver;
346dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray
347dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  Function* F = 0;
348dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  void* ActualPtr = 0;
349dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray
350dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  {
351dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    // Only lock for getting the Function. The call getPointerToFunction made
352dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    // in this function might trigger function materializing, which requires
353dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    // JIT lock to be unlocked.
354dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    MutexGuard locked(TheJIT->lock);
355dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray
356dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    // The address given to us for the stub may not be exactly right, it might be
357dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    // a little bit after the stub.  As such, use upper_bound to find it.
358e2bcf13be5e7b9b9ea103c5546dab51f5cac9cb0Nick Lewycky    StubToFunctionMapTy::iterator I =
359dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray      JR.state.getStubToFunctionMap(locked).upper_bound(Stub);
360dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    assert(I != JR.state.getStubToFunctionMap(locked).begin() &&
361dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray           "This is not a known stub!");
362dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    F = (--I)->second;
363dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray    ActualPtr = I->first;
364dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  }
3655426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
3669da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng  // If we have already code generated the function, just return the address.
3679da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng  void *Result = TheJIT->getPointerToGlobalIfAvailable(F);
3689da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng
3699da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng  if (!Result) {
3709da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // Otherwise we don't have it, do lazy compilation now.
3719da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng
3729da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // If lazy compilation is disabled, emit a useful error message and abort.
3739da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    if (TheJIT->isLazyCompilationDisabled()) {
3749da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng      cerr << "LLVM JIT requested to do lazy compilation of function '"
3759da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng      << F->getName() << "' when lazy compiles are disabled!\n";
3769da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng      abort();
3779da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    }
3789cab56d59e2ed6af5fb5137a6e50d4bf915eaccfChris Lattner
3799da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // We might like to remove the stub from the StubToFunction map.
3809da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // We can't do that! Multiple threads could be stuck, waiting to acquire the
3819da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // lock above. As soon as the 1st function finishes compiling the function,
3829da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // the next one will be released, and needs to be able to find the function
3839da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    // it needs to call.
3849da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    //JR.state.getStubToFunctionMap(locked).erase(I);
3859da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng
3869da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    DOUT << "JIT: Lazily resolving function '" << F->getName()
3879da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng         << "' In stub ptr = " << Stub << " actual ptr = "
388dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray         << ActualPtr << "\n";
3899da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng
3909da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng    Result = TheJIT->getPointerToFunction(F);
3919da60f92d916be01c23b8a9a0eeed448523a7c9bEvan Cheng  }
392dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray
393dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  // Reacquire the lock to erase the stub in the map.
394dcb31e179000193c65b3f09b7138ef273dc3ce63Nicolas Geoffray  MutexGuard locked(TheJIT->lock);
3955426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
3965426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // We don't need to reuse this stub in the future, as F is now compiled.
397ee448630bdf7eb6037fe2c50518d32010c433ca3Reid Spencer  JR.state.getFunctionToStubMap(locked).erase(F);
3985426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
3995426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // FIXME: We could rewrite all references to this stub if we knew them.
4006a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
401d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen  // What we will do is set the compiled function address to map to the
402d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen  // same GOT entry as the stub so that later clients may update the GOT
4036a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  // if they see it still using the stub address.
4046a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  // Note: this is done so the Resolver doesn't have to manage GOT memory
4056a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  // Do this without allocating map space if the target isn't using a GOT
4066a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  if(JR.revGOTMap.find(Stub) != JR.revGOTMap.end())
4076a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    JR.revGOTMap[Result] = JR.revGOTMap[Stub];
4086a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
4095426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  return Result;
4105426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner}
4115426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
4128ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner//===----------------------------------------------------------------------===//
4138ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// Function Index Support
4148ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4158ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// On MacOS we generate an index of currently JIT'd functions so that
4168ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// performance tools can determine a symbol name and accurate code range for a
4178ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// PC value.  Because performance tools are generally asynchronous, the code
4188ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// below is written with the hope that it could be interrupted at any time and
4198ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// have useful answers.  However, we don't go crazy with atomic operations, we
4208ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner// just do a "reasonable effort".
4218ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#ifdef __APPLE__
422bdb6ca178cfbe2490a058deabce7847a05f55db7Evan Cheng#define ENABLE_JIT_SYMBOL_TABLE 0
4238ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif
4248ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4258ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// JitSymbolEntry - Each function that is JIT compiled results in one of these
4268ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// being added to an array of symbols.  This indicates the name of the function
4278ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// as well as the address range it occupies.  This allows the client to map
4288ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner/// from a PC value to the name of the function.
4298ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstruct JitSymbolEntry {
4308ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  const char *FnName;   // FnName - a strdup'd string.
4318ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  void *FnStart;
4328ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  intptr_t FnSize;
4338ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner};
4348ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4358ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4368ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstruct JitSymbolTable {
4378ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// NextPtr - This forms a linked list of JitSymbolTable entries.  This
4388ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// pointer is not used right now, but might be used in the future.  Consider
4398ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// it reserved for future use.
4408ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolTable *NextPtr;
4418ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4428ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// Symbols - This is an array of JitSymbolEntry entries.  Only the first
4438ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// 'NumSymbols' symbols are valid.
4448ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolEntry *Symbols;
4458ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4468ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// NumSymbols - This indicates the number entries in the Symbols array that
4478ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// are valid.
4488ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  unsigned NumSymbols;
4498ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4508ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// NumAllocated - This indicates the amount of space we have in the Symbols
4518ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  /// array.  This is a private field that should not be read by external tools.
4528ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  unsigned NumAllocated;
4538ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner};
4548ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4558ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if ENABLE_JIT_SYMBOL_TABLE
4568ac66c122b099bc3eab858bfc18f3cb342efc818Chris LattnerJitSymbolTable *__jitSymbolTable;
4578ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif
4588ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4598ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstatic void AddFunctionToSymbolTable(const char *FnName,
4608ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner                                     void *FnStart, intptr_t FnSize) {
4618ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  assert(FnName != 0 && FnStart != 0 && "Bad symbol to add");
4628ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolTable **SymTabPtrPtr = 0;
4638ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if !ENABLE_JIT_SYMBOL_TABLE
4648ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  return;
4658ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#else
4668ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  SymTabPtrPtr = &__jitSymbolTable;
4678ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif
4688ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4698ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // If this is the first entry in the symbol table, add the JitSymbolTable
4708ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // index.
4718ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  if (*SymTabPtrPtr == 0) {
4728ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    JitSymbolTable *New = new JitSymbolTable();
4738ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    New->NextPtr = 0;
4748ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    New->Symbols = 0;
4758ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    New->NumSymbols = 0;
4768ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    New->NumAllocated = 0;
4778ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    *SymTabPtrPtr = New;
4788ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  }
4798ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4808ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolTable *SymTabPtr = *SymTabPtrPtr;
4818ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4828ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // If we have space in the table, reallocate the table.
4838ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  if (SymTabPtr->NumSymbols >= SymTabPtr->NumAllocated) {
4848ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    // If we don't have space, reallocate the table.
4853b374489041ac28153c84194dda45e182d8939fcChris Lattner    unsigned NewSize = std::max(64U, SymTabPtr->NumAllocated*2);
4868ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    JitSymbolEntry *NewSymbols = new JitSymbolEntry[NewSize];
4878ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    JitSymbolEntry *OldSymbols = SymTabPtr->Symbols;
4888ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4898ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    // Copy the old entries over.
490d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    memcpy(NewSymbols, OldSymbols, SymTabPtr->NumSymbols*sizeof(OldSymbols[0]));
4918ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4928ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    // Swap the new symbols in, delete the old ones.
4938ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    SymTabPtr->Symbols = NewSymbols;
4943b374489041ac28153c84194dda45e182d8939fcChris Lattner    SymTabPtr->NumAllocated = NewSize;
4958ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    delete [] OldSymbols;
4968ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  }
4978ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
4988ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Otherwise, we have enough space, just tack it onto the end of the array.
4998ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolEntry &Entry = SymTabPtr->Symbols[SymTabPtr->NumSymbols];
5008ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  Entry.FnName = strdup(FnName);
5018ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  Entry.FnStart = FnStart;
5028ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  Entry.FnSize = FnSize;
5038ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  ++SymTabPtr->NumSymbols;
5048ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner}
5058ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5068ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattnerstatic void RemoveFunctionFromSymbolTable(void *FnStart) {
5078ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  assert(FnStart && "Invalid function pointer");
5088ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolTable **SymTabPtrPtr = 0;
5098ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#if !ENABLE_JIT_SYMBOL_TABLE
5108ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  return;
5118ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#else
5128ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  SymTabPtrPtr = &__jitSymbolTable;
5138ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner#endif
5148ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5158ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolTable *SymTabPtr = *SymTabPtrPtr;
5168ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  JitSymbolEntry *Symbols = SymTabPtr->Symbols;
5178ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5188ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Scan the table to find its index.  The table is not sorted, so do a linear
5198ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // scan.
5208ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  unsigned Index;
5218ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  for (Index = 0; Symbols[Index].FnStart != FnStart; ++Index)
5228ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    assert(Index != SymTabPtr->NumSymbols && "Didn't find function!");
5238ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5248ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Once we have an index, we know to nuke this entry, overwrite it with the
5258ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // entry at the end of the array, making the last entry redundant.
5268ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  const char *OldName = Symbols[Index].FnName;
5278ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  Symbols[Index] = Symbols[SymTabPtr->NumSymbols-1];
5288ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  free((void*)OldName);
5298ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5308ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Drop the number of symbols in the table.
5318ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  --SymTabPtr->NumSymbols;
5328ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5338ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Finally, if we deleted the final symbol, deallocate the table itself.
534f44085a86a3f3cb743fb8822108d8360dd094539Nate Begeman  if (SymTabPtr->NumSymbols != 0)
5358ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    return;
5368ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
5378ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  *SymTabPtrPtr = 0;
5388ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  delete [] Symbols;
5398ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  delete SymTabPtr;
5408ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner}
5415426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
5425426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//===----------------------------------------------------------------------===//
543166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner// JITEmitter code.
5445426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner//
545688506de24f04682f9d8563a7d20ab15ab85340bChris Lattnernamespace {
546166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner  /// JITEmitter - The JIT implementation of the MachineCodeEmitter, which is
547166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner  /// used to output functions to memory for execution.
548166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner  class JITEmitter : public MachineCodeEmitter {
5498907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    JITMemoryManager *MemMgr;
550688506de24f04682f9d8563a7d20ab15ab85340bChris Lattner
5516125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner    // When outputting a function stub in the context of some other function, we
55243b429b05989075b60693d57395c99b0ad789f8dChris Lattner    // save BufferBegin/BufferEnd/CurBufferPtr here.
55343b429b05989075b60693d57395c99b0ad789f8dChris Lattner    unsigned char *SavedBufferBegin, *SavedBufferEnd, *SavedCurBufferPtr;
554bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner
5555be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    /// Relocations - These are the relocations that the function needs, as
5565be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    /// emitted.
5575be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    std::vector<MachineRelocation> Relocations;
558b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner
559b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    /// MBBLocations - This vector is a mapping from MBB ID's to their address.
560b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    /// It is filled in by the StartMachineBasicBlock callback and queried by
561b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    /// the getMachineBasicBlockAddress callback.
5625788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    std::vector<uintptr_t> MBBLocations;
56316ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth
564239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    /// ConstantPool - The constant pool for the current function.
565239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    ///
566239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    MachineConstantPool *ConstantPool;
567239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner
568239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    /// ConstantPoolBase - A pointer to the first entry in the constant pool.
569239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    ///
570239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner    void *ConstantPoolBase;
57137efe6764568a3829fee26aba532283131d1a104Nate Begeman
5721606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    /// ConstPoolAddresses - Addresses of individual constant pool entries.
5731606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    ///
5741606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    SmallVector<uintptr_t, 8> ConstPoolAddresses;
5751606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng
576019f851ab26511c089e41b61901f743e75f90714Nate Begeman    /// JumpTable - The jump tables for the current function.
57737efe6764568a3829fee26aba532283131d1a104Nate Begeman    ///
57837efe6764568a3829fee26aba532283131d1a104Nate Begeman    MachineJumpTableInfo *JumpTable;
57937efe6764568a3829fee26aba532283131d1a104Nate Begeman
58037efe6764568a3829fee26aba532283131d1a104Nate Begeman    /// JumpTableBase - A pointer to the first entry in the jump table.
58137efe6764568a3829fee26aba532283131d1a104Nate Begeman    ///
58237efe6764568a3829fee26aba532283131d1a104Nate Begeman    void *JumpTableBase;
5832a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng
584e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    /// Resolver - This contains info about the currently resolved functions.
585e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    JITResolver Resolver;
586afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
587afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    /// DE - The dwarf emitter for the jit.
588afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    JITDwarfEmitter *DE;
589afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
590afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    /// LabelLocations - This vector is a mapping from Label ID's to their
591afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    /// address.
5925788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    std::vector<uintptr_t> LabelLocations;
593afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
594afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    /// MMI - Machine module info for exception informations
595afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    MachineModuleInfo* MMI;
596afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
597dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    // GVSet - a set to keep track of which globals have been seen
59847c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    SmallPtrSet<const GlobalVariable*, 8> GVSet;
599dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
60050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // CurFn - The llvm function being emitted.  Only valid during
60150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // finishFunction().
60250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    const Function *CurFn;
60350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
60450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // CurFnStubUses - For a given Function, a vector of stubs that it
60550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // references.  This facilitates the JIT detecting that a stub is no
60650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // longer used, so that it may be deallocated.
60750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    DenseMap<const Function *, SmallVector<void*, 1> > CurFnStubUses;
60850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
60950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // StubFnRefs - For a given pointer to a stub, a set of Functions which
61050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // reference the stub.  When the count of a stub's references drops to zero,
61150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // the stub is unused.
61250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
61350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
614841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    // ExtFnStubs - A map of external function names to stubs which have entries
615841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    // in the JITResolver's ExternalFnToStubMap.
616841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    StringMap<void *> ExtFnStubs;
617841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
618e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner  public:
61950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    JITEmitter(JIT &jit, JITMemoryManager *JMM) : Resolver(jit), CurFn(0) {
6209f2f142d255bc96f109dd5c6524a485937b1f3a1Chris Lattner      MemMgr = JMM ? JMM : JITMemoryManager::CreateDefaultMemManager();
6218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner      if (jit.getJITInfo().needsGOT()) {
6228907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner        MemMgr->AllocateGOT();
6238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner        DOUT << "JIT is managing a GOT\n";
6248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner      }
625afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
626afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      if (ExceptionHandling) DE = new JITDwarfEmitter(jit);
6278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    }
6288907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    ~JITEmitter() {
6298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner      delete MemMgr;
630afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      if (ExceptionHandling) delete DE;
63116ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth    }
632a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng
633a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng    /// classof - Methods for support type inquiry through isa, cast, and
634a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng    /// dyn_cast:
635a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng    ///
636a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng    static inline bool classof(const JITEmitter*) { return true; }
637a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng    static inline bool classof(const MachineCodeEmitter*) { return true; }
638e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner
639e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    JITResolver &getJITResolver() { return Resolver; }
640bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
641bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner    virtual void startFunction(MachineFunction &F);
64243b429b05989075b60693d57395c99b0ad789f8dChris Lattner    virtual bool finishFunction(MachineFunction &F);
643f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
644f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner    void emitConstantPool(MachineConstantPool *MCP);
645f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner    void initJumpTableInfo(MachineJumpTableInfo *MJTI);
646b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey    void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
647f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
648ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Cheng    virtual void startGVStub(const GlobalValue* GV, unsigned StubSize,
64951cc3c13eac78da242f0518fc42580e48dd5304fNicolas Geoffray                                   unsigned Alignment = 1);
650d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    virtual void startGVStub(const GlobalValue* GV, void *Buffer,
651d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman                             unsigned StubSize);
652ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Cheng    virtual void* finishGVStub(const GlobalValue *GV);
653bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner
654cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes    /// allocateSpace - Reserves space in the current block if any, or
655cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes    /// allocate a new one of the given size.
6565788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual void *allocateSpace(uintptr_t Size, unsigned Alignment);
657cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes
6585be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    virtual void addRelocation(const MachineRelocation &MR) {
6595be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner      Relocations.push_back(MR);
6605be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    }
661b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner
662b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
663b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner      if (MBBLocations.size() <= (unsigned)MBB->getNumber())
664b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner        MBBLocations.resize((MBB->getNumber()+1)*2);
665b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner      MBBLocations[MBB->getNumber()] = getCurrentPCValue();
666366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng      DOUT << "JIT: Emitting BB" << MBB->getNumber() << " at ["
667366cf29ca537057341ecbad03ab8f9bc52f731e7Evan Cheng           << (void*) getCurrentPCValue() << "]\n";
668b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    }
669b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner
6705788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual uintptr_t getConstantPoolEntryAddress(unsigned Entry) const;
6715788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const;
6722a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng
6735788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const {
674b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner      assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
675b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner             MBBLocations[MBB->getNumber()] && "MBB not emitted!");
676b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner      return MBBLocations[MBB->getNumber()];
677b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner    }
6785be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner
679e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner    /// deallocateMemForFunction - Deallocate all memory for the specified
680e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner    /// function body.
68150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    void deallocateMemForFunction(Function *F);
682841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
683841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    /// AddStubToCurrentFunction - Mark the current function being JIT'd as
684841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    /// using the stub at the specified address. Allows
685841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    /// deallocateMemForFunction to also remove stubs no longer referenced.
686841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    void AddStubToCurrentFunction(void *Stub);
687841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
688841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    /// getExternalFnStubs - Accessor for the JIT to find stubs emitted for
689841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    /// MachineRelocations that reference external functions by name.
690841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    const StringMap<void*> &getExternalFnStubs() const { return ExtFnStubs; }
691afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
692afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    virtual void emitLabel(uint64_t LabelID) {
693afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      if (LabelLocations.size() <= LabelID)
694afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray        LabelLocations.resize((LabelID+1)*2);
695afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      LabelLocations[LabelID] = getCurrentPCValue();
696afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    }
697afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
6985788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
699afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      assert(LabelLocations.size() > (unsigned)LabelID &&
700afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray             LabelLocations[LabelID] && "Label not emitted!");
701afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      return LabelLocations[LabelID];
702afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    }
703afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
704afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    virtual void setModuleInfo(MachineModuleInfo* Info) {
705afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      MMI = Info;
706afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray      if (ExceptionHandling) DE->setModuleInfo(Info);
707afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    }
708afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
709cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach    void setMemoryExecutable(void) {
710cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach      MemMgr->setMemoryExecutable();
711cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach    }
712d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
713d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    JITMemoryManager *getMemMgr(void) const { return MemMgr; }
714cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach
7155426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  private:
7165e225588530f641d6627becadffdd7d285bfcdbaChris Lattner    void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
7175594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng    void *getPointerToGVIndirectSym(GlobalValue *V, void *Reference,
718e4d783d584d22d7fcb4cba2a24e0f45f62ed8153Evan Cheng                                    bool NoNeedStub);
719dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    unsigned addSizeOfGlobal(const GlobalVariable *GV, unsigned Size);
720dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    unsigned addSizeOfGlobalsInConstantVal(const Constant *C, unsigned Size);
721dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    unsigned addSizeOfGlobalsInInitializer(const Constant *Init, unsigned Size);
722dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    unsigned GetSizeOfGlobalsInBytes(MachineFunction &MF);
723bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner  };
724bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
725bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
726166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid *JITEmitter::getPointerToGlobal(GlobalValue *V, void *Reference,
727166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattner                                     bool DoesntNeedStub) {
728d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
7295426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner    return TheJIT->getOrEmitGlobalVariable(GV);
730d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
73118e045983757a7d2bae482d2abe444a5bb3ed134Chris Lattner  if (GlobalAlias *GA = dyn_cast<GlobalAlias>(V))
73219e861a4ffb896f16a691d5ac869e894df3cd464Anton Korobeynikov    return TheJIT->getPointerToGlobal(GA->resolveAliasedGlobal(false));
7335426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
7345426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  // If we have already compiled the function, return a pointer to its body.
7355426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  Function *F = cast<Function>(V);
736704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng  void *ResultPtr;
73750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  if (!DoesntNeedStub && !TheJIT->isLazyCompilationDisabled()) {
738704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    // Return the function stub if it's already created.
739704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    ResultPtr = Resolver.getFunctionStubIfAvailable(F);
74050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    if (ResultPtr)
74150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman      AddStubToCurrentFunction(ResultPtr);
74250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  } else {
743704bff9e6cf0070924eb11d9e81e5ba6962ae4efEvan Cheng    ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
74450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  }
7455426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner  if (ResultPtr) return ResultPtr;
7465426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
747d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // If this is an external function pointer, we can force the JIT to
748b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // 'compile' it, which really just adds it to the map.  In dlsym mode,
749b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // external functions are forced through a stub, regardless of reloc type.
750b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode() &&
751b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman      DoesntNeedStub && !TheJIT->areDlsymStubsEnabled())
752d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    return TheJIT->getPointerToFunction(F);
753d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
7545e225588530f641d6627becadffdd7d285bfcdbaChris Lattner  // Okay, the function has not been compiled yet, if the target callback
7555e225588530f641d6627becadffdd7d285bfcdbaChris Lattner  // mechanism is capable of rewriting the instruction directly, prefer to do
756b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // that instead of emitting a stub.  This uses the lazy resolver, so is not
757b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // legal if lazy compilation is disabled.
758b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  if (DoesntNeedStub && !TheJIT->isLazyCompilationDisabled())
759e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    return Resolver.AddCallbackAtLocation(F, Reference);
7605e225588530f641d6627becadffdd7d285bfcdbaChris Lattner
761b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // Otherwise, we have to emit a stub.
76250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  void *StubAddr = Resolver.getFunctionStub(F);
76350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
76450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Add the stub to the current function's list of referenced stubs, so we can
765b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // deallocate them if the current function is ever freed.  It's possible to
766b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // return null from getFunctionStub in the case of a weak extern that fails
767b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  // to resolve.
768b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman  if (StubAddr)
769b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman    AddStubToCurrentFunction(StubAddr);
770b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman
77150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  return StubAddr;
7725426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner}
7735426652c25a5d960bdd3272aa3b90fc8203a5a66Chris Lattner
7745594f120b8880f7c514b0376c4adac1267a0b2b6Evan Chengvoid *JITEmitter::getPointerToGVIndirectSym(GlobalValue *V, void *Reference,
775e4d783d584d22d7fcb4cba2a24e0f45f62ed8153Evan Cheng                                            bool NoNeedStub) {
77650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Make sure GV is emitted first, and create a stub containing the fully
77750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // resolved address.
778be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng  void *GVAddress = getPointerToGlobal(V, Reference, true);
77950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  void *StubAddr = Resolver.getGlobalValueIndirectSym(V, GVAddress);
78050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
78150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Add the stub to the current function's list of referenced stubs, so we can
78250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // deallocate them if the current function is ever freed.
78350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  AddStubToCurrentFunction(StubAddr);
78450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
78550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  return StubAddr;
78650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman}
78750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
78850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begemanvoid JITEmitter::AddStubToCurrentFunction(void *StubAddr) {
78950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  if (!TheJIT->areDlsymStubsEnabled())
79050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    return;
79150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
79250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  assert(CurFn && "Stub added to current function, but current function is 0!");
79350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
79450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  SmallVectorImpl<void*> &StubsUsed = CurFnStubUses[CurFn];
79550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  StubsUsed.push_back(StubAddr);
79650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
79750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[StubAddr];
79850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  FnRefs.insert(CurFn);
799be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng}
800be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
8011606e8e4cd937e6de6681f686c266cf61722d972Evan Chengstatic unsigned GetConstantPoolSizeInBytes(MachineConstantPool *MCP,
8021606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng                                           const TargetData *TD) {
803dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
804dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  if (Constants.empty()) return 0;
805dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
8061606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned Size = 0;
8071606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
8081606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    MachineConstantPoolEntry CPE = Constants[i];
8091606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    unsigned AlignMask = CPE.getAlignment() - 1;
8101606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    Size = (Size + AlignMask) & ~AlignMask;
8111606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    const Type *Ty = CPE.getType();
812777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands    Size += TD->getTypeAllocSize(Ty);
8131606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  }
814dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  return Size;
815dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray}
816dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
817dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffraystatic unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo *MJTI) {
818dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
819dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  if (JT.empty()) return 0;
820dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
821dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  unsigned NumEntries = 0;
822dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  for (unsigned i = 0, e = JT.size(); i != e; ++i)
823dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    NumEntries += JT[i].MBBs.size();
824dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
825dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  unsigned EntrySize = MJTI->getEntrySize();
826dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
827dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  return NumEntries * EntrySize;
828dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray}
829dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
830580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffraystatic uintptr_t RoundUpToAlign(uintptr_t Size, unsigned Alignment) {
831dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  if (Alignment == 0) Alignment = 1;
832580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray  // Since we do not know where the buffer will be allocated, be pessimistic.
833580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray  return Size + Alignment;
834dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray}
835be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng
836dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGlobal - add the size of the global (plus any alignment padding)
837dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// into the running total Size.
838dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
839dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV, unsigned Size) {
840dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  const Type *ElTy = GV->getType()->getElementType();
841777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands  size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize(ElTy);
842dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  size_t GVAlign =
843dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV);
844eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng  DOUT << "JIT: Adding in size " << GVSize << " alignment " << GVAlign;
845dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  DEBUG(GV->dump());
846dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // Assume code section ends with worst possible alignment, so first
847dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // variable needs maximal padding.
848dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  if (Size==0)
849dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    Size = 1;
850dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  Size = ((Size+GVAlign-1)/GVAlign)*GVAlign;
851dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  Size += GVSize;
852dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  return Size;
853dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen}
854dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
855dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGlobalsInConstantVal - find any globals that we haven't seen yet
856dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// but are referenced from the constant; put them in GVSet and add their
857dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// size into the running total Size.
858dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
859dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant *C,
860dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen                                              unsigned Size) {
861dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // If its undefined, return the garbage.
862dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  if (isa<UndefValue>(C))
863dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    return Size;
864dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
865dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // If the value is a ConstantExpr
866dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
867dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    Constant *Op0 = CE->getOperand(0);
868dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    switch (CE->getOpcode()) {
869dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::GetElementPtr:
870dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Trunc:
871dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::ZExt:
872dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::SExt:
873dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::FPTrunc:
874dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::FPExt:
875dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::UIToFP:
876dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::SIToFP:
877dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::FPToUI:
878dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::FPToSI:
879dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::PtrToInt:
880dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::IntToPtr:
881dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::BitCast: {
882dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      Size = addSizeOfGlobalsInConstantVal(Op0, Size);
883dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      break;
884dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    }
885dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Add:
886dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Sub:
887dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Mul:
888dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::UDiv:
889dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::SDiv:
890dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::URem:
891dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::SRem:
892dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::And:
893dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Or:
894dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    case Instruction::Xor: {
895dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      Size = addSizeOfGlobalsInConstantVal(Op0, Size);
896dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      Size = addSizeOfGlobalsInConstantVal(CE->getOperand(1), Size);
897dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      break;
898dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    }
899dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    default: {
900dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen       cerr << "ConstantExpr not handled: " << *CE << "\n";
901dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      abort();
902dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    }
903dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    }
904dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  }
905dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
906dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  if (C->getType()->getTypeID() == Type::PointerTyID)
907dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    if (const GlobalVariable* GV = dyn_cast<GlobalVariable>(C))
90847c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng      if (GVSet.insert(GV))
909dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen        Size = addSizeOfGlobal(GV, Size);
910dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
911dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  return Size;
912dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen}
913dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
914dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// addSizeOfGLobalsInInitializer - handle any globals that we haven't seen yet
915dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// but are referenced from the given initializer.
916dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
917dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant *Init,
918dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen                                              unsigned Size) {
919dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  if (!isa<UndefValue>(Init) &&
920dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      !isa<ConstantVector>(Init) &&
921dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      !isa<ConstantAggregateZero>(Init) &&
922dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      !isa<ConstantArray>(Init) &&
923dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      !isa<ConstantStruct>(Init) &&
924dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      Init->getType()->isFirstClassType())
925dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    Size = addSizeOfGlobalsInConstantVal(Init, Size);
926dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  return Size;
927dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen}
928dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
929dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// GetSizeOfGlobalsInBytes - walk the code for the function, looking for
930dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// globals; then walk the initializers of those globals looking for more.
931dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// If their size has not been considered yet, add it into the running total
932dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen/// Size.
933dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
934dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesenunsigned JITEmitter::GetSizeOfGlobalsInBytes(MachineFunction &MF) {
935dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  unsigned Size = 0;
936dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  GVSet.clear();
937dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
938dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
939dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen       MBB != E; ++MBB) {
940dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    for (MachineBasicBlock::const_iterator I = MBB->begin(), E = MBB->end();
941dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen         I != E; ++I) {
942dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      const TargetInstrDesc &Desc = I->getDesc();
943dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      const MachineInstr &MI = *I;
944dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      unsigned NumOps = Desc.getNumOperands();
945dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      for (unsigned CurOp = 0; CurOp < NumOps; CurOp++) {
946dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen        const MachineOperand &MO = MI.getOperand(CurOp);
947d735b8019b0f297d7c14b55adcd887af24d8e602Dan Gohman        if (MO.isGlobal()) {
948dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          GlobalValue* V = MO.getGlobal();
949dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          const GlobalVariable *GV = dyn_cast<const GlobalVariable>(V);
950dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          if (!GV)
951dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen            continue;
952dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // If seen in previous function, it will have an entry here.
953dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          if (TheJIT->getPointerToGlobalIfAvailable(GV))
954dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen            continue;
955dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // If seen earlier in this function, it will have an entry here.
956dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // FIXME: it should be possible to combine these tables, by
957dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // assuming the addresses of the new globals in this module
958dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // start at 0 (or something) and adjusting them after codegen
959dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen          // complete.  Another possibility is to grab a marker bit in GV.
96047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng          if (GVSet.insert(GV))
961dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen            // A variable as yet unseen.  Add in its size.
962dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen            Size = addSizeOfGlobal(GV, Size);
963dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen        }
964dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      }
965dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    }
966dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  }
967eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng  DOUT << "JIT: About to look through initializers\n";
968dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // Look for more globals that are referenced only from initializers.
969dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  // GVSet.end is computed each time because the set can grow as we go.
97047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng  for (SmallPtrSet<const GlobalVariable *, 8>::iterator I = GVSet.begin();
971dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen       I != GVSet.end(); I++) {
972dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    const GlobalVariable* GV = *I;
973dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    if (GV->hasInitializer())
974dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen      Size = addSizeOfGlobalsInInitializer(GV->getInitializer(), Size);
975dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  }
976dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
977dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen  return Size;
978dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen}
979dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
980166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::startFunction(MachineFunction &F) {
981eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng  DOUT << "JIT: Starting CodeGen of Function "
982eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng       << F.getFunction()->getName() << "\n";
983eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng
984dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  uintptr_t ActualSize = 0;
985cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach  // Set the memory writable, if it's not already
986cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach  MemMgr->setMemoryWritable();
9875913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray  if (MemMgr->NeedsExactSize()) {
988eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng    DOUT << "JIT: ExactSize\n";
989dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
990dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
991dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    MachineConstantPool *MCP = F.getConstantPool();
992dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
993dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Ensure the constant pool/jump table info is at least 4-byte aligned.
994580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray    ActualSize = RoundUpToAlign(ActualSize, 16);
995dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
996dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the alignment of the constant pool
9971606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    ActualSize = RoundUpToAlign(ActualSize, MCP->getConstantPoolAlignment());
998dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
999dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the constant pool size
10001606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    ActualSize += GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
1001dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
1002dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the aligment of the jump table info
1003580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray    ActualSize = RoundUpToAlign(ActualSize, MJTI->getAlignment());
1004dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
1005dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the jump table size
1006dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    ActualSize += GetJumpTableSizeInBytes(MJTI);
1007dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
1008dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the alignment for the function
1009580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray    ActualSize = RoundUpToAlign(ActualSize,
1010580631a73a71ff621c71618b16e9644b30a9d3c9Nicolas Geoffray                                std::max(F.getFunction()->getAlignment(), 8U));
1011dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
1012dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    // Add the function size
1013dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    ActualSize += TII->GetFunctionSizeInBytes(F);
1014dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
1015eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng    DOUT << "JIT: ActualSize before globals " << ActualSize << "\n";
1016dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    // Add the size of the globals that will be allocated after this function.
1017dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    // These are all the ones referenced from this function that were not
1018dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    // previously allocated.
1019dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen    ActualSize += GetSizeOfGlobalsInBytes(F);
1020eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng    DOUT << "JIT: ActualSize after globals " << ActualSize << "\n";
1021dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray  }
1022dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
10238907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner  BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
10248907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner                                                         ActualSize);
1025e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  BufferEnd = BufferBegin+ActualSize;
1026f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
10279a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng  // Ensure the constant pool/jump table info is at least 4-byte aligned.
10289a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng  emitAlignment(16);
10299a1e9b91407f4752ff3de392d60a6cf3f1dcc37dEvan Cheng
1030f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  emitConstantPool(F.getConstantPool());
1031f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  initJumpTableInfo(F.getJumpTableInfo());
1032f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
1033f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  // About to start emitting the machine code for the function.
10340eb4d6b52e1b5db9a4c86e5a954356ae3507a287Chris Lattner  emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
1035f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
103655fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng
1037b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner  MBBLocations.clear();
1038bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
1039bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
104043b429b05989075b60693d57395c99b0ad789f8dChris Lattnerbool JITEmitter::finishFunction(MachineFunction &F) {
1041e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  if (CurBufferPtr == BufferEnd) {
1042e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner    // FIXME: Allocate more space, then try again.
1043832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling    cerr << "JIT: Ran out of space for generated machine code!\n";
1044e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner    abort();
1045e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  }
1046e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1047b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey  emitJumpTableInfo(F.getJumpTableInfo());
1048b4432f3d4754e16c918428d34a9d8ec18ab79204Chris Lattner
1049a827953c32e420740c281b4a38a056d15b180932Chris Lattner  // FnStart is the start of the text, not the start of the constant pool and
1050a827953c32e420740c281b4a38a056d15b180932Chris Lattner  // other per-function data.
1051a827953c32e420740c281b4a38a056d15b180932Chris Lattner  unsigned char *FnStart =
1052a827953c32e420740c281b4a38a056d15b180932Chris Lattner    (unsigned char *)TheJIT->getPointerToGlobalIfAvailable(F.getFunction());
1053bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
105419fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis  // FnEnd is the end of the function's machine code.
105519fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis  unsigned char *FnEnd = CurBufferPtr;
105619fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis
10575be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner  if (!Relocations.empty()) {
105850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    CurFn = F.getFunction();
1059e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner    NumRelos += Relocations.size();
1060e884dc2c586bc2f6646ffce89fef5100b412326eChris Lattner
10615be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    // Resolve the relocations to concrete pointers.
10625be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
10635be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner      MachineRelocation &MR = Relocations[i];
10649200605cd5f6db50be20efb7df926dc5a0d19a4dEvan Cheng      void *ResultPtr = 0;
1065ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng      if (!MR.letTargetResolve()) {
1066d7398c9b699cae3a109e9808401f7d0b2fc7e686Evan Cheng        if (MR.isExternalSymbol()) {
106769f9378675b23135043d93aa58300fed3ec41cbfDan Gohman          ResultPtr = TheJIT->getPointerToNamedFunction(MR.getExternalSymbol(),
106869f9378675b23135043d93aa58300fed3ec41cbfDan Gohman                                                        false);
1069d7398c9b699cae3a109e9808401f7d0b2fc7e686Evan Cheng          DOUT << "JIT: Map \'" << MR.getExternalSymbol() << "\' to ["
1070ca66b08bc6c3cf899459e642a5297df8b9ccdb0dEvan Cheng               << ResultPtr << "]\n";
1071ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng
1072ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          // If the target REALLY wants a stub for this function, emit it now.
1073841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman          if (!MR.doesntNeedStub()) {
1074841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman            if (!TheJIT->areDlsymStubsEnabled()) {
1075841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman              ResultPtr = Resolver.getExternalFunctionStub(ResultPtr);
1076841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman            } else {
1077841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman              void *&Stub = ExtFnStubs[MR.getExternalSymbol()];
1078841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman              if (!Stub) {
1079841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman                Stub = Resolver.getExternalFunctionStub((void *)&Stub);
1080841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman                AddStubToCurrentFunction(Stub);
1081841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman              }
1082841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman              ResultPtr = Stub;
1083841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman            }
1084841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman          }
1085ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        } else if (MR.isGlobalValue()) {
1086ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
1087ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng                                         BufferBegin+MR.getMachineCodeOffset(),
1088ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng                                         MR.doesntNeedStub());
10895594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng        } else if (MR.isIndirectSymbol()) {
10905594f120b8880f7c514b0376c4adac1267a0b2b6Evan Cheng          ResultPtr = getPointerToGVIndirectSym(MR.getGlobalValue(),
1091be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng                                          BufferBegin+MR.getMachineCodeOffset(),
1092be8c03fc66b75fa775e1f47d62a1b0d803fced1cEvan Cheng                                          MR.doesntNeedStub());
1093ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        } else if (MR.isBasicBlock()) {
1094ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock());
1095ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        } else if (MR.isConstantPoolIndex()) {
1096ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          ResultPtr = (void*)getConstantPoolEntryAddress(MR.getConstantPoolIndex());
1097ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        } else {
1098ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          assert(MR.isJumpTableIndex());
1099ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng          ResultPtr=(void*)getJumpTableEntryAddress(MR.getJumpTableIndex());
1100ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        }
110100b16889ab461b7ecef1c91ade101186b7f1fce2Jeff Cohen
1102ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng        MR.setResultPointer(ResultPtr);
1103ef5784ef9b9cdfbc9819a96440c6873196eade76Evan Cheng      }
110416ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth
11056a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth      // if we are managing the GOT and the relocation wants an index,
11066a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth      // give it one
11078907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner      if (MR.isGOTRelative() && MemMgr->isManagingGOT()) {
1108e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner        unsigned idx = Resolver.getGOTIndexForAddr(ResultPtr);
11096a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth        MR.setGOTIndex(idx);
11108907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner        if (((void**)MemMgr->getGOTBase())[idx] != ResultPtr) {
1111eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng          DOUT << "JIT: GOT was out of date for " << ResultPtr
11128907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner               << " pointing at " << ((void**)MemMgr->getGOTBase())[idx]
1113832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling               << "\n";
11148907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner          ((void**)MemMgr->getGOTBase())[idx] = ResultPtr;
11156a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth        }
111616ec33c6ef630730ad55a4af7242c658e1efb8b3Andrew Lenharth      }
11175be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner    }
11185be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner
111950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    CurFn = 0;
112043b429b05989075b60693d57395c99b0ad789f8dChris Lattner    TheJIT->getJITInfo().relocate(BufferBegin, &Relocations[0],
11218907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner                                  Relocations.size(), MemMgr->getGOTBase());
11225be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner  }
11235be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner
1124d2d5c76753b132c34c71248db2f136b38531bc6dChris Lattner  // Update the GOT entry for F to point to the new code.
11258907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner  if (MemMgr->isManagingGOT()) {
1126e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner    unsigned idx = Resolver.getGOTIndexForAddr((void*)BufferBegin);
11278907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner    if (((void**)MemMgr->getGOTBase())[idx] != (void*)BufferBegin) {
1128eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng      DOUT << "JIT: GOT was out of date for " << (void*)BufferBegin
11298907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner           << " pointing at " << ((void**)MemMgr->getGOTBase())[idx] << "\n";
11308907b4ba479bbfbe630a4c3abab32c7d49749a48Chris Lattner      ((void**)MemMgr->getGOTBase())[idx] = (void*)BufferBegin;
11316a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth    }
11326a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth  }
11336a9746127a168306a670eaff11925605dbea9d4fAndrew Lenharth
113419fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis  // CurBufferPtr may have moved beyond FnEnd, due to memory allocation for
113519fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis  // global variables that were referenced in the relocations.
113619fee415f63ddb78fca703085fe56510be3e058cArgyrios Kyrtzidis  MemMgr->endFunctionBody(F.getFunction(), BufferBegin, CurBufferPtr);
11375788d1a169db3346a612a13113348d2709bdd15bEvan Cheng
11385788d1a169db3346a612a13113348d2709bdd15bEvan Cheng  if (CurBufferPtr == BufferEnd) {
11395788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    // FIXME: Allocate more space, then try again.
11405788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    cerr << "JIT: Ran out of space for generated machine code!\n";
11415788d1a169db3346a612a13113348d2709bdd15bEvan Cheng    abort();
11425788d1a169db3346a612a13113348d2709bdd15bEvan Cheng  }
11435788d1a169db3346a612a13113348d2709bdd15bEvan Cheng
1144cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  BufferBegin = CurBufferPtr = 0;
1145cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  NumBytes += FnEnd-FnStart;
1146cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes
114755fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng  // Invalidate the icache if necessary.
1148bc52cada0933f353d30da7b49af9a641bdb2c57dChris Lattner  sys::Memory::InvalidateInstructionCache(FnStart, FnEnd-FnStart);
11498ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
11508ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  // Add it to the JIT symbol table if the host wants it.
11518ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  AddFunctionToSymbolTable(F.getFunction()->getNameStart(),
11528ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner                           FnStart, FnEnd-FnStart);
115355fc28076fa48723bd170e51638b3b5974ca0fa1Evan Cheng
1154832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling  DOUT << "JIT: Finished CodeGen of [" << (void*)FnStart
1155832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling       << "] Function: " << F.getFunction()->getName()
1156832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling       << ": " << (FnEnd-FnStart) << " bytes of text, "
1157832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling       << Relocations.size() << " relocations\n";
11585be478f360b4c632d1adfccc64df87840e1ccfc1Chris Lattner  Relocations.clear();
11591606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  ConstPoolAddresses.clear();
11608cd4c3e6534a14566bf163301fd45bca34e655c1Anton Korobeynikov
1161bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng  // Mark code region readable and executable if it's not so already.
1162cce6c297c54b4c9c8615c77e97cd64e70812ea60Jim Grosbach  MemMgr->setMemoryExecutable();
1163bc4707a2554ac04ba006bf70035e7bc7270236a9Evan Cheng
1164c5633c235e94f69c6a77e894bcc84d8ba71106f0Chris Lattner#ifndef NDEBUG
1165a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng  {
1166e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng    if (sys::hasDisassembler()) {
1167e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng      DOUT << "JIT: Disassembled code:\n";
1168eb5d95a22df7ab88815f35bdc8b6e5d3a6a1119dEvan Cheng      DOUT << sys::disassembleBuffer(FnStart, FnEnd-FnStart, (uintptr_t)FnStart);
1169e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng    } else {
1170e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng      DOUT << "JIT: Binary code:\n";
1171a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng      DOUT << std::hex;
1172a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng      unsigned char* q = FnStart;
1173e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng      for (int i = 0; q < FnEnd; q += 4, ++i) {
1174e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        if (i == 4)
1175e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng          i = 0;
1176e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        if (i == 0)
1177e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng          DOUT << "JIT: " << std::setw(8) << std::setfill('0')
1178e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng               << (long)(q - FnStart) << ": ";
1179e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        bool Done = false;
1180e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        for (int j = 3; j >= 0; --j) {
1181e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng          if (q + j >= FnEnd)
1182e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng            Done = true;
1183e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng          else
1184e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng            DOUT << std::setw(2) << std::setfill('0') << (unsigned short)q[j];
1185e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        }
1186e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        if (Done)
1187e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng          break;
1188e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        DOUT << ' ';
1189e7c3551e6f75ca3fc8a3a30e8ca5f9c19edbe2e3Evan Cheng        if (i == 3)
11906863fb033a9079e04edc7a568e34098bcf5b9ebeEvan Cheng          DOUT << '\n';
1191a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng      }
1192a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng      DOUT << std::dec;
11936863fb033a9079e04edc7a568e34098bcf5b9ebeEvan Cheng      DOUT<< '\n';
1194a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng    }
1195a7916f586d438b0e626e54ce713435437c4b901cEvan Cheng  }
1196c5633c235e94f69c6a77e894bcc84d8ba71106f0Chris Lattner#endif
1197afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray  if (ExceptionHandling) {
1198dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    uintptr_t ActualSize = 0;
1199afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    SavedBufferBegin = BufferBegin;
1200afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    SavedBufferEnd = BufferEnd;
1201afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    SavedCurBufferPtr = CurBufferPtr;
1202dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray
12035913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray    if (MemMgr->NeedsExactSize()) {
12045913e6c5dbaff88ac00d5e679382abc72323831aNicolas Geoffray      ActualSize = DE->GetDwarfTableSizeInBytes(F, *this, FnStart, FnEnd);
1205dc17ab2bf0c4d325b87ac8130004ab11f3f7106dNicolas Geoffray    }
1206afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
1207afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    BufferBegin = CurBufferPtr = MemMgr->startExceptionTable(F.getFunction(),
1208afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray                                                             ActualSize);
1209afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    BufferEnd = BufferBegin+ActualSize;
1210afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    unsigned char* FrameRegister = DE->EmitDwarfTable(F, *this, FnStart, FnEnd);
12110fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner    MemMgr->endExceptionTable(F.getFunction(), BufferBegin, CurBufferPtr,
12120fdaa0b8f194f0ef7cec0610c50672b89bd7c17aChris Lattner                              FrameRegister);
1213afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    BufferBegin = SavedBufferBegin;
1214afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    BufferEnd = SavedBufferEnd;
1215afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    CurBufferPtr = SavedCurBufferPtr;
1216afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
1217afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray    TheJIT->RegisterTable(FrameRegister);
1218afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray  }
1219252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng
1220252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng  if (MMI)
1221252ddfbdbc834d1abe80de9c2205afac7918d3eaEvan Cheng    MMI->EndFunction();
1222afe6c2b001a924cd74bd0aacfed5984d9af004b0Nicolas Geoffray
122343b429b05989075b60693d57395c99b0ad789f8dChris Lattner  return false;
1224bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner}
1225bd199fb1148b9e16c4e6f3d0ee386c2505a55b71Chris Lattner
122650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman/// deallocateMemForFunction - Deallocate all memory for the specified
122750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman/// function body.  Also drop any references the function has to stubs.
122850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begemanvoid JITEmitter::deallocateMemForFunction(Function *F) {
122950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  MemMgr->deallocateMemForFunction(F);
123050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
123150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // If the function did not reference any stubs, return.
123250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  if (CurFnStubUses.find(F) == CurFnStubUses.end())
123350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    return;
123450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
123550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // For each referenced stub, erase the reference to this function, and then
123650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // erase the list of referenced stubs.
123750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
123850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
123950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    void *Stub = StubList[i];
1240841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
1241841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    // If we already invalidated this stub for this function, continue.
1242841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    if (StubFnRefs.count(Stub) == 0)
1243841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      continue;
1244841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
124550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
124650cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    FnRefs.erase(F);
124750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
124850cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // If this function was the last reference to the stub, invalidate the stub
124950cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // in the JITResolver.  Were there a memory manager deallocateStub routine,
125050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    // we could call that at this point too.
125150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    if (FnRefs.empty()) {
1252b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman      DOUT << "\nJIT: Invalidated Stub at [" << Stub << "]\n";
1253841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      StubFnRefs.erase(Stub);
1254841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
1255841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      // Invalidate the stub.  If it is a GV stub, update the JIT's global
1256841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      // mapping for that GV to zero, otherwise, search the string map of
1257841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      // external function names to stubs and remove the entry for this stub.
1258b9c6c9bfe410bbea357503872ce662d6838026ceNate Begeman      GlobalValue *GV = Resolver.invalidateStub(Stub);
1259841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      if (GV) {
1260841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman        TheJIT->updateGlobalMapping(GV, 0);
1261841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      } else {
1262841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman        for (StringMapIterator<void*> i = ExtFnStubs.begin(),
1263841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman             e = ExtFnStubs.end(); i != e; ++i) {
1264841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman          if (i->second == Stub) {
1265841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman            ExtFnStubs.erase(i);
1266841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman            break;
1267841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman          }
1268841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman        }
1269841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      }
127050cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman    }
127150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  }
127250cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  CurFnStubUses.erase(F);
127350cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman}
127450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
127550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman
12765788d1a169db3346a612a13113348d2709bdd15bEvan Chengvoid* JITEmitter::allocateSpace(uintptr_t Size, unsigned Alignment) {
1277cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  if (BufferBegin)
1278cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes    return MachineCodeEmitter::allocateSpace(Size, Alignment);
1279cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes
1280cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  // create a new memory block if there is no active one.
1281cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  // care must be taken so that BufferBegin is invalidated when a
1282cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  // block is trimmed
1283cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  BufferBegin = CurBufferPtr = MemMgr->allocateSpace(Size, Alignment);
1284cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  BufferEnd = BufferBegin+Size;
1285cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes  return CurBufferPtr;
1286cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes}
1287cef7527a85d026aeb17a4dacca73c70c0ab5da40Nuno Lopes
1288166f2269f5e5e54f8b5df705e7653929374d1893Chris Lattnervoid JITEmitter::emitConstantPool(MachineConstantPool *MCP) {
128947c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng  if (TheJIT->getJITInfo().hasCustomConstantPool())
12908fe95356dd487a79145ec07a9f46cd743b4c9bddJim Grosbach    return;
129147c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng
1292fa77d43ba1d91ed39f46e11caeb28dcabae9e193Chris Lattner  const std::vector<MachineConstantPoolEntry> &Constants = MCP->getConstants();
12932c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner  if (Constants.empty()) return;
12942c0a6a19ef42f2ad547dbc0693e55e082a21ac8bChris Lattner
12951606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned Size = GetConstantPoolSizeInBytes(MCP, TheJIT->getTargetData());
12961606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned Align = MCP->getConstantPoolAlignment();
129797b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng  ConstantPoolBase = allocateSpace(Size, Align);
1298239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner  ConstantPool = MCP;
1299f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
1300f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  if (ConstantPoolBase == 0) return;  // Buffer overflow.
1301f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
130297b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng  DOUT << "JIT: Emitted constant pool at [" << ConstantPoolBase
130397b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng       << "] (size: " << Size << ", alignment: " << Align << ")\n";
130497b8c40d095c4eb5d8e8ff5ac6da567f043bd8baEvan Cheng
1305239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner  // Initialize the memory for all of the constant pool entries.
13061606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  unsigned Offset = 0;
13073029f920519e0871a5aad5d7c592281093953733Chris Lattner  for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
13081606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    MachineConstantPoolEntry CPE = Constants[i];
13091606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    unsigned AlignMask = CPE.getAlignment() - 1;
13101606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    Offset = (Offset + AlignMask) & ~AlignMask;
13111606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng
13121606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    uintptr_t CAddr = (uintptr_t)ConstantPoolBase + Offset;
13131606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    ConstPoolAddresses.push_back(CAddr);
13141606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    if (CPE.isMachineConstantPoolEntry()) {
1315cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng      // FIXME: add support to lower machine constant pool values into bytes!
1316832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling      cerr << "Initialize memory with machine specific constant pool entry"
1317832171cb9724d2d31c8dfb73172e2be8f6dd13eeBill Wendling           << " has not been implemented!\n";
1318cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng      abort();
1319cd5731d98b15c9de236bd0dd6c9c57d9bcecbcebEvan Cheng    }
13201606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    TheJIT->InitializeMemory(CPE.Val.ConstVal, (void*)CAddr);
13211606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    DOUT << "JIT:   CP" << i << " at [0x"
13221606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng         << std::hex << CAddr << std::dec << "]\n";
13231606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng
13241606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng    const Type *Ty = CPE.Val.ConstVal->getType();
1325777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands    Offset += TheJIT->getTargetData()->getTypeAllocSize(Ty);
13261cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner  }
13271cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner}
13281cc08381f1ab57efdf07248fd5e9fd75ef6f0f99Chris Lattner
132937efe6764568a3829fee26aba532283131d1a104Nate Begemanvoid JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
133047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng  if (TheJIT->getJITInfo().hasCustomJumpTables())
133147c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    return;
133247c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng
133337efe6764568a3829fee26aba532283131d1a104Nate Begeman  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
133437efe6764568a3829fee26aba532283131d1a104Nate Begeman  if (JT.empty()) return;
133537efe6764568a3829fee26aba532283131d1a104Nate Begeman
1336f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  unsigned NumEntries = 0;
133737efe6764568a3829fee26aba532283131d1a104Nate Begeman  for (unsigned i = 0, e = JT.size(); i != e; ++i)
1338f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner    NumEntries += JT[i].MBBs.size();
1339f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
1340f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  unsigned EntrySize = MJTI->getEntrySize();
1341f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner
134237efe6764568a3829fee26aba532283131d1a104Nate Begeman  // Just allocate space for all the jump tables now.  We will fix up the actual
134337efe6764568a3829fee26aba532283131d1a104Nate Begeman  // MBB entries in the tables after we emit the code for each block, since then
134437efe6764568a3829fee26aba532283131d1a104Nate Begeman  // we will know the final locations of the MBBs in memory.
134537efe6764568a3829fee26aba532283131d1a104Nate Begeman  JumpTable = MJTI;
1346f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
134737efe6764568a3829fee26aba532283131d1a104Nate Begeman}
134837efe6764568a3829fee26aba532283131d1a104Nate Begeman
1349b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskeyvoid JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
135047c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng  if (TheJIT->getJITInfo().hasCustomJumpTables())
135147c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng    return;
135247c01a0099c10c031f8c544baf44b1c3a1de3fadEvan Cheng
135337efe6764568a3829fee26aba532283131d1a104Nate Begeman  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1354f75f9be3fb89eb6661a0ed8bfee8a6328ee5a4d1Chris Lattner  if (JT.empty() || JumpTableBase == 0) return;
135537efe6764568a3829fee26aba532283131d1a104Nate Begeman
1356b92767afd442a8363a8696e54880ee31c5d48c1eJim Laskey  if (TargetMachine::getRelocationModel() == Reloc::PIC_) {
1357acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?");
1358acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    // For each jump table, place the offset from the beginning of the table
1359acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    // to the target address.
1360acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    int *SlotPtr = (int*)JumpTableBase;
1361acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey
1362acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    for (unsigned i = 0, e = JT.size(); i != e; ++i) {
1363acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
1364acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      // Store the offset of the basic block for this jump table slot in the
1365acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      // memory we allocated for the jump table in 'initJumpTableInfo'
13665788d1a169db3346a612a13113348d2709bdd15bEvan Cheng      uintptr_t Base = (uintptr_t)SlotPtr;
13672a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng      for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) {
13685788d1a169db3346a612a13113348d2709bdd15bEvan Cheng        uintptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]);
13692a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng        *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base);
13702a3e08b5961353fa3faeadf81f481ae9f5463427Evan Cheng      }
1371acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    }
1372acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey  } else {
1373acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?");
1374acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey
1375acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    // For each jump table, map each target in the jump table to the address of
1376acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    // an emitted MachineBasicBlock.
1377acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    intptr_t *SlotPtr = (intptr_t*)JumpTableBase;
1378acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey
1379acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    for (unsigned i = 0, e = JT.size(); i != e; ++i) {
1380acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      const std::vector<MachineBasicBlock*> &MBBs = JT[i].MBBs;
1381acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      // Store the address of the basic block for this jump table slot in the
1382acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      // memory we allocated for the jump table in 'initJumpTableInfo'
1383acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey      for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi)
1384acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey        *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]);
1385acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    }
138637efe6764568a3829fee26aba532283131d1a104Nate Begeman  }
138737efe6764568a3829fee26aba532283131d1a104Nate Begeman}
138837efe6764568a3829fee26aba532283131d1a104Nate Begeman
1389ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Chengvoid JITEmitter::startGVStub(const GlobalValue* GV, unsigned StubSize,
1390ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Cheng                             unsigned Alignment) {
139143b429b05989075b60693d57395c99b0ad789f8dChris Lattner  SavedBufferBegin = BufferBegin;
139243b429b05989075b60693d57395c99b0ad789f8dChris Lattner  SavedBufferEnd = BufferEnd;
139343b429b05989075b60693d57395c99b0ad789f8dChris Lattner  SavedCurBufferPtr = CurBufferPtr;
139443b429b05989075b60693d57395c99b0ad789f8dChris Lattner
1395ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Cheng  BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize, Alignment);
139643b429b05989075b60693d57395c99b0ad789f8dChris Lattner  BufferEnd = BufferBegin+StubSize+1;
13976125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner}
13986125fddb52c3d821a4e4c000cbd210428b0009f6Chris Lattner
1399d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JITEmitter::startGVStub(const GlobalValue* GV, void *Buffer,
1400d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman                             unsigned StubSize) {
1401d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SavedBufferBegin = BufferBegin;
1402d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SavedBufferEnd = BufferEnd;
1403d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SavedCurBufferPtr = CurBufferPtr;
1404d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1405d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  BufferBegin = CurBufferPtr = (unsigned char *)Buffer;
1406d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  BufferEnd = BufferBegin+StubSize+1;
1407d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman}
1408d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1409ce4a70bd7608861e104b04265a0c71e5df8ecefeEvan Chengvoid *JITEmitter::finishGVStub(const GlobalValue* GV) {
141043b429b05989075b60693d57395c99b0ad789f8dChris Lattner  NumBytes += getCurrentPCOffset();
141143b429b05989075b60693d57395c99b0ad789f8dChris Lattner  std::swap(SavedBufferBegin, BufferBegin);
141243b429b05989075b60693d57395c99b0ad789f8dChris Lattner  BufferEnd = SavedBufferEnd;
141343b429b05989075b60693d57395c99b0ad789f8dChris Lattner  CurBufferPtr = SavedCurBufferPtr;
141443b429b05989075b60693d57395c99b0ad789f8dChris Lattner  return SavedBufferBegin;
1415bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner}
1416bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner
1417bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// getConstantPoolEntryAddress - Return the address of the 'ConstantNum' entry
1418bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// in the constant pool that was last emitted with the 'emitConstantPool'
1419bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner// method.
1420bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner//
14215788d1a169db3346a612a13113348d2709bdd15bEvan Chenguintptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const {
1422239862ce995adfd3b51062e62e54ef2db92b1150Chris Lattner  assert(ConstantNum < ConstantPool->getConstants().size() &&
14233c94497ec7852eccd68c1bc1663e8ac2a7bb1ab9Misha Brukman         "Invalid ConstantPoolIndex!");
14241606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng  return ConstPoolAddresses[ConstantNum];
1425bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner}
1426bba1b6df9a7ac36e3a479dfe953a9618c87db7bbChris Lattner
142737efe6764568a3829fee26aba532283131d1a104Nate Begeman// getJumpTableEntryAddress - Return the address of the JumpTable with index
142837efe6764568a3829fee26aba532283131d1a104Nate Begeman// 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo'
142937efe6764568a3829fee26aba532283131d1a104Nate Begeman//
14305788d1a169db3346a612a13113348d2709bdd15bEvan Chenguintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const {
143137efe6764568a3829fee26aba532283131d1a104Nate Begeman  const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
143237efe6764568a3829fee26aba532283131d1a104Nate Begeman  assert(Index < JT.size() && "Invalid jump table index!");
143337efe6764568a3829fee26aba532283131d1a104Nate Begeman
143437efe6764568a3829fee26aba532283131d1a104Nate Begeman  unsigned Offset = 0;
143537efe6764568a3829fee26aba532283131d1a104Nate Begeman  unsigned EntrySize = JumpTable->getEntrySize();
143637efe6764568a3829fee26aba532283131d1a104Nate Begeman
143737efe6764568a3829fee26aba532283131d1a104Nate Begeman  for (unsigned i = 0; i < Index; ++i)
1438acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey    Offset += JT[i].MBBs.size();
1439acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey
1440acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey   Offset *= EntrySize;
144137efe6764568a3829fee26aba532283131d1a104Nate Begeman
14425788d1a169db3346a612a13113348d2709bdd15bEvan Cheng  return (uintptr_t)((char *)JumpTableBase + Offset);
144337efe6764568a3829fee26aba532283131d1a104Nate Begeman}
144437efe6764568a3829fee26aba532283131d1a104Nate Begeman
1445e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===//
1446e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//  Public interface to this file
1447e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//===----------------------------------------------------------------------===//
1448e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
14499f2f142d255bc96f109dd5c6524a485937b1f3a1Chris LattnerMachineCodeEmitter *JIT::createEmitter(JIT &jit, JITMemoryManager *JMM) {
14509f2f142d255bc96f109dd5c6524a485937b1f3a1Chris Lattner  return new JITEmitter(jit, JMM);
1451e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner}
1452e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1453d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// getPointerToNamedFunction - This function is used as a global wrapper to
14544d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner// JIT::getPointerToNamedFunction for the purpose of resolving symbols when
1455d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// bugpoint is debugging the JIT. In that scenario, we are loading an .so and
1456d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// need to resolve function(s) that are being mis-codegenerated, so we need to
1457d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman// resolve their addresses at runtime, and this is the way to do it.
1458d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukmanextern "C" {
1459d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman  void *getPointerToNamedFunction(const char *Name) {
1460fe854034677f59baca1e38075e71f6efca247a03Chris Lattner    if (Function *F = TheJIT->FindFunctionNamed(Name))
14614d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner      return TheJIT->getPointerToFunction(F);
14624d326fa9bea5b80147edf14d1521fc41ce315275Chris Lattner    return TheJIT->getPointerToNamedFunction(Name);
1463d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman  }
1464d69c1e6dc28bed3c156f78fee5253748e3d509e2Misha Brukman}
1465e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1466e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// getPointerToFunctionOrStub - If the specified function has been
1467e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// code-gen'd, return a pointer to the function.  If not, compile it, or use
1468e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner// a stub to implement lazy compilation if available.
1469e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner//
1470e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid *JIT::getPointerToFunctionOrStub(Function *F) {
1471e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  // If we have already code generated the function, just return the address.
1472e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  if (void *Addr = getPointerToGlobalIfAvailable(F))
1473e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner    return Addr;
1474e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1475e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner  // Get a stub if the target supports it.
1476a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng  assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
1477a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng  JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
1478e748401b180d7041738e14d3896ac61ca4bdfcbaChris Lattner  return JE->getJITResolver().getFunctionStub(F);
1479e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner}
1480e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1481d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JIT::updateFunctionStub(Function *F) {
1482d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // Get the empty stub we generated earlier.
1483d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
1484d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
1485d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  void *Stub = JE->getJITResolver().getFunctionStub(F);
1486d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1487d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // Tell the target jit info to rewrite the stub at the specified address,
1488d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // rather than creating a new one.
1489d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  void *Addr = getPointerToGlobalIfAvailable(F);
1490d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  getJITInfo().emitFunctionStubAtAddr(F, Addr, Stub, *getCodeEmitter());
1491d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman}
1492d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1493d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman/// updateDlsymStubTable - Emit the data necessary to relocate the stubs
1494d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman/// that were emitted during code generation.
1495d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman///
1496d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begemanvoid JIT::updateDlsymStubTable() {
1497d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
1498d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
1499d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1500d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SmallVector<GlobalValue*, 8> GVs;
1501d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SmallVector<void*, 8> Ptrs;
1502841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  const StringMap<void *> &ExtFns = JE->getExternalFnStubs();
1503d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1504d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  JE->getJITResolver().getRelocatableGVs(GVs, Ptrs);
1505d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1506841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  unsigned nStubs = GVs.size() + ExtFns.size();
1507841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
1508d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // If there are no relocatable stubs, return.
1509841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  if (nStubs == 0)
1510d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    return;
1511d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1512d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // If there are no new relocatable stubs, return.
1513d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  void *CurTable = JE->getMemMgr()->getDlsymTable();
1514841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  if (CurTable && (*(unsigned *)CurTable == nStubs))
1515d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    return;
1516d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1517d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // Calculate the size of the stub info
1518841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  unsigned offset = 4 + 4 * nStubs + sizeof(intptr_t) * nStubs;
1519d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1520d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  SmallVector<unsigned, 8> Offsets;
1521d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  for (unsigned i = 0; i != GVs.size(); ++i) {
1522d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    Offsets.push_back(offset);
1523d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    offset += GVs[i]->getName().length() + 1;
1524d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  }
1525841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
1526841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman       i != e; ++i) {
1527841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    Offsets.push_back(offset);
1528841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    offset += strlen(i->first()) + 1;
1529841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  }
1530d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
153150cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Allocate space for the new "stub", which contains the dlsym table.
1532d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  JE->startGVStub(0, offset, 4);
1533d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1534d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // Emit the number of records
1535841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  MCE->emitInt32(nStubs);
1536d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1537d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  // Emit the string offsets
1538841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  for (unsigned i = 0; i != nStubs; ++i)
1539d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    MCE->emitInt32(Offsets[i]);
1540d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
154166941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  // Emit the pointers.  Verify that they are at least 2-byte aligned, and set
154266941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  // the low bit to 0 == GV, 1 == Function, so that the client code doing the
154366941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  // relocation can write the relocated pointer at the appropriate place in
154466941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  // the stub.
154566941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  for (unsigned i = 0; i != GVs.size(); ++i) {
154666941988de6a295649b33f4c2b0f36a094b2244dNate Begeman    intptr_t Ptr = (intptr_t)Ptrs[i];
154766941988de6a295649b33f4c2b0f36a094b2244dNate Begeman    assert((Ptr & 1) == 0 && "Stub pointers must be at least 2-byte aligned!");
154866941988de6a295649b33f4c2b0f36a094b2244dNate Begeman
154966941988de6a295649b33f4c2b0f36a094b2244dNate Begeman    if (isa<Function>(GVs[i]))
155066941988de6a295649b33f4c2b0f36a094b2244dNate Begeman      Ptr |= (intptr_t)1;
155166941988de6a295649b33f4c2b0f36a094b2244dNate Begeman
1552841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    if (sizeof(Ptr) == 8)
1553841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      MCE->emitInt64(Ptr);
1554841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    else
1555841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman      MCE->emitInt32(Ptr);
1556841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  }
1557841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
1558841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman       i != e; ++i) {
1559841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    intptr_t Ptr = (intptr_t)i->second | 1;
1560841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman
1561841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    if (sizeof(Ptr) == 8)
156266941988de6a295649b33f4c2b0f36a094b2244dNate Begeman      MCE->emitInt64(Ptr);
1563d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    else
156466941988de6a295649b33f4c2b0f36a094b2244dNate Begeman      MCE->emitInt32(Ptr);
156566941988de6a295649b33f4c2b0f36a094b2244dNate Begeman  }
1566d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
156750cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Emit the strings.
1568d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  for (unsigned i = 0; i != GVs.size(); ++i)
1569d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman    MCE->emitString(GVs[i]->getName());
1570841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman  for (StringMapConstIterator<void*> i = ExtFns.begin(), e = ExtFns.end();
1571841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman       i != e; ++i)
1572841c6a4345082e9a1252cc39bcce7f1423a76dedNate Begeman    MCE->emitString(i->first());
1573d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
157450cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // Tell the JIT memory manager where it is.  The JIT Memory Manager will
157550cd6fda9e98f68a9a6e1adf72c38baf614bd305Nate Begeman  // deallocate space for the old one, if one existed.
1576d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman  JE->getMemMgr()->SetDlsymTable(JE->finishGVStub(0));
1577d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman}
1578d6b7a242d345fd79a337afd384bb586c5619cfe7Nate Begeman
1579e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner/// freeMachineCodeForFunction - release machine code memory for given Function.
1580e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner///
1581e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattnervoid JIT::freeMachineCodeForFunction(Function *F) {
1582dd947ea3c5e020c33c58a31939561265b980a3adDale Johannesen
1583e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  // Delete translation for this from the ExecutionEngine, so it will get
1584e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  // retranslated next time it is used.
15858ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  void *OldPtr = updateGlobalMapping(F, 0);
15868ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner
15878ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner  if (OldPtr)
15888ac66c122b099bc3eab858bfc18f3cb342efc818Chris Lattner    RemoveFunctionFromSymbolTable(OldPtr);
1589e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1590e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner  // Free the actual memory for the function body and related stuff.
1591a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng  assert(isa<JITEmitter>(MCE) && "Unexpected MCE?");
1592a044dfcb5ae3b789799cefaf5c4c2e1973fbf4c5Evan Cheng  cast<JITEmitter>(MCE)->deallocateMemForFunction(F);
1593e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner}
1594e993cc27ad9fd84e6aaf652c94eb9ca0cb63a898Chris Lattner
1595