Correlate stubs with functions in JIT: when emitting a stub, the JIT tells the memory...
authorNicolas Geoffray <nicolas.geoffray@lip6.fr>
Wed, 16 Apr 2008 20:46:05 +0000 (20:46 +0000)
committerNicolas Geoffray <nicolas.geoffray@lip6.fr>
Wed, 16 Apr 2008 20:46:05 +0000 (20:46 +0000)
the stub will resolve.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49814 91177308-0d34-0410-b5e6-96231b3b80d8

15 files changed:
include/llvm/CodeGen/MachineCodeEmitter.h
include/llvm/ExecutionEngine/JITMemoryManager.h
include/llvm/Target/TargetJITInfo.h
lib/CodeGen/ELFWriter.cpp
lib/CodeGen/MachOWriter.cpp
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/ExecutionEngine/JIT/JITMemoryManager.cpp
lib/Target/ARM/ARMJITInfo.cpp
lib/Target/ARM/ARMJITInfo.h
lib/Target/Alpha/AlphaJITInfo.cpp
lib/Target/Alpha/AlphaJITInfo.h
lib/Target/PowerPC/PPCJITInfo.cpp
lib/Target/PowerPC/PPCJITInfo.h
lib/Target/X86/X86JITInfo.cpp
lib/Target/X86/X86JITInfo.h

index 8fe7ecc9e9bfbc6a75c99c22add6b53febcdc107..6bf72de0ff292992647ee2917cba94896647cec4 100644 (file)
@@ -82,12 +82,13 @@ public:
   /// have constant pools, the can only use the other emitByte*/emitWord*
   /// methods.
   ///
-  virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) = 0;
+  virtual void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                                 unsigned Alignment = 1) = 0;
 
   /// finishFunctionStub - This callback is invoked to terminate a function
   /// stub.
   ///
-  virtual void *finishFunctionStub(const Function *F) = 0;
+  virtual void *finishFunctionStub(const GlobalValue* F) = 0;
 
   /// emitByte - This callback is invoked when a byte needs to be written to the
   /// output stream.
index 7226496753683a5d043ceb650cf74bbcb2dd051c..0977d5640fa3f3d308f1069496cfcf473aeba560 100644 (file)
@@ -74,7 +74,8 @@ public:
   /// thunk for it.  The stub should be "close" to the current function body,
   /// but should not be included in the 'actualsize' returned by
   /// startFunctionBody.
-  virtual unsigned char *allocateStub(unsigned StubSize, unsigned Alignment) =0;
+  virtual unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
+                                      unsigned Alignment) =0;
   
   
   /// endFunctionBody - This method is called when the JIT is done codegen'ing
index c78a212540f752ffa8610f411ea5066ccd8adb35..918319f11cc6e9682b0aec04237021ef8ea1fa21 100644 (file)
@@ -23,6 +23,7 @@
 
 namespace llvm {
   class Function;
+  class GlobalValue;
   class MachineBasicBlock;
   class MachineCodeEmitter;
   class MachineRelocation;
@@ -41,8 +42,9 @@ namespace llvm {
     virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
 
     /// emitGlobalValueLazyPtr - Use the specified MachineCodeEmitter object to
-    /// emit a lazy pointer which contains the address of the specified GV.
-    virtual void *emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE) {
+    /// emit a lazy pointer which contains the address of the specified ptr.
+    virtual void *emitGlobalValueLazyPtr(const GlobalValue* GV, void *ptr,
+                                         MachineCodeEmitter &MCE) {
       assert(0 && "This target doesn't implement emitGlobalValueLazyPtr!");
       return 0;
     }
@@ -50,7 +52,8 @@ namespace llvm {
     /// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
     /// small native function that simply calls the function at the specified
     /// address.  Return the address of the resultant function.
-    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+    virtual void *emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE) {
       assert(0 && "This target doesn't implement emitFunctionStub!");
       return 0;
     }
index 8b6fbb779afd19cd19708eade52a01c45a605f71..baba0551dd44838e939f940b8b303f75b4678474 100644 (file)
@@ -114,11 +114,12 @@ namespace llvm {
 
 
     /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
-    void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+    void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                           unsigned Alignment = 1) {
       assert(0 && "JIT specific function called!");
       abort();
     }
-    void *finishFunctionStub(const Function *F) {
+    void *finishFunctionStub(const GlobalValue *F) {
       assert(0 && "JIT specific function called!");
       abort();
       return 0;
index f77f85e98d51f0b9eeaa6296a7eafe37a93a4b49..2726f706d7f04cea6bdfdf11f3c0f9849056716b 100644 (file)
@@ -141,11 +141,12 @@ namespace llvm {
     virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
 
     /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
-    virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1) {
+    virtual void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                                   unsigned Alignment = 1) {
       assert(0 && "JIT specific function called!");
       abort();
     }
-    virtual void *finishFunctionStub(const Function *F) {
+    virtual void *finishFunctionStub(const GlobalValue* F) {
       assert(0 && "JIT specific function called!");
       abort();
       return 0;
index 64d3cd784057f6b01d0a839a131d2f77818333e5..1a0bb26fbed395ae8907d2faef35c575af0ec202 100644 (file)
@@ -175,7 +175,7 @@ void *JITResolver::getFunctionStub(Function *F) {
 
   // Otherwise, codegen a new stub.  For now, the stub will call the lazy
   // resolver function.
-  Stub = TheJIT->getJITInfo().emitFunctionStub(Actual,
+  Stub = TheJIT->getJITInfo().emitFunctionStub(F, Actual,
                                                *TheJIT->getCodeEmitter());
 
   if (Actual != (void*)(intptr_t)LazyResolverFn) {
@@ -204,7 +204,7 @@ void *JITResolver::getGlobalValueLazyPtr(GlobalValue *GV, void *GVAddress) {
   if (LazyPtr) return LazyPtr;
 
   // Otherwise, codegen a new lazy pointer.
-  LazyPtr = TheJIT->getJITInfo().emitGlobalValueLazyPtr(GVAddress,
+  LazyPtr = TheJIT->getJITInfo().emitGlobalValueLazyPtr(GV, GVAddress,
                                                     *TheJIT->getCodeEmitter());
 
   DOUT << "JIT: Stub emitted at [" << LazyPtr << "] for GV '"
@@ -220,7 +220,7 @@ void *JITResolver::getExternalFunctionStub(void *FnAddr) {
   void *&Stub = ExternalFnToStubMap[FnAddr];
   if (Stub) return Stub;
 
-  Stub = TheJIT->getJITInfo().emitFunctionStub(FnAddr,
+  Stub = TheJIT->getJITInfo().emitFunctionStub(0, FnAddr,
                                                *TheJIT->getCodeEmitter());
 
   DOUT << "JIT: Stub emitted at [" << Stub
@@ -503,8 +503,9 @@ namespace {
     void initJumpTableInfo(MachineJumpTableInfo *MJTI);
     void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
     
-    virtual void startFunctionStub(unsigned StubSize, unsigned Alignment = 1);
-    virtual void* finishFunctionStub(const Function *F);
+    virtual void startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                                   unsigned Alignment = 1);
+    virtual void* finishFunctionStub(const GlobalValue *F);
 
     virtual void addRelocation(const MachineRelocation &MR) {
       Relocations.push_back(MR);
@@ -822,16 +823,17 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
   }
 }
 
-void JITEmitter::startFunctionStub(unsigned StubSize, unsigned Alignment) {
+void JITEmitter::startFunctionStub(const GlobalValue* F, unsigned StubSize,
+                                   unsigned Alignment) {
   SavedBufferBegin = BufferBegin;
   SavedBufferEnd = BufferEnd;
   SavedCurBufferPtr = CurBufferPtr;
   
-  BufferBegin = CurBufferPtr = MemMgr->allocateStub(StubSize, Alignment);
+  BufferBegin = CurBufferPtr = MemMgr->allocateStub(F, StubSize, Alignment);
   BufferEnd = BufferBegin+StubSize+1;
 }
 
-void *JITEmitter::finishFunctionStub(const Function *F) {
+void *JITEmitter::finishFunctionStub(const GlobalValue* F) {
   NumBytes += getCurrentPCOffset();
   std::swap(SavedBufferBegin, BufferBegin);
   BufferEnd = SavedBufferEnd;
index 5908e434516ada4473a87793fa4ee7596ba54708..b07af2e11ddd0f35c60bd0c5d3ab25b461683ab2 100644 (file)
@@ -11,6 +11,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "llvm/GlobalValue.h"
 #include "llvm/ExecutionEngine/JITMemoryManager.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/System/Memory.h"
@@ -265,7 +266,8 @@ namespace {
 
     void AllocateGOT();
 
-    unsigned char *allocateStub(unsigned StubSize, unsigned Alignment);
+    unsigned char *allocateStub(const GlobalValue* F, unsigned StubSize,
+                                unsigned Alignment);
     
     /// startFunctionBody - When a function starts, allocate a block of free
     /// executable memory, returning a pointer to it and its actual size.
@@ -438,7 +440,8 @@ DefaultJITMemoryManager::~DefaultJITMemoryManager() {
   Blocks.clear();
 }
 
-unsigned char *DefaultJITMemoryManager::allocateStub(unsigned StubSize,
+unsigned char *DefaultJITMemoryManager::allocateStub(const GlobalValue* F,
+                                                     unsigned StubSize,
                                                      unsigned Alignment) {
   CurStubPtr -= StubSize;
   CurStubPtr = (unsigned char*)(((intptr_t)CurStubPtr) &
index 915963c26cacc847f631a7cb95d055143a805cb3..bc2bba36c80a340293ad8ac07586cfbec88c8b3b 100644 (file)
@@ -15,6 +15,7 @@
 #include "ARMJITInfo.h"
 #include "ARMRelocations.h"
 #include "ARMSubtarget.h"
+#include "llvm/Function.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/Config/alloca.h"
 #include <cstdlib>
@@ -93,20 +94,21 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) {
   return ARMCompilationCallback;
 }
 
-void *ARMJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE) {
   unsigned addr = (intptr_t)Fn;
   // If this is just a call to an external function, emit a branch instead of a
   // call.  The code is the same except for one bit of the last instruction.
   if (Fn != (void*)(intptr_t)ARMCompilationCallback) {
     // branch to the corresponding function addr
     // the stub is 8-byte size and 4-aligned
-    MCE.startFunctionStub(8, 4);
+    MCE.startFunctionStub(F, 8, 4);
     MCE.emitWordLE(0xE51FF004); // LDR PC, [PC,#-4]
     MCE.emitWordLE(addr);       // addr of function
   } else {
     // branch and link to the corresponding function addr
     // the stub is 20-byte size and 4-aligned
-    MCE.startFunctionStub(20, 4);
+    MCE.startFunctionStub(F, 20, 4);
     MCE.emitWordLE(0xE92D4800); // STMFD SP!, [R11, LR]
     MCE.emitWordLE(0xE28FE004); // ADD LR, PC, #4
     MCE.emitWordLE(0xE51FF004); // LDR PC, [PC,#-4]
@@ -114,7 +116,7 @@ void *ARMJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
     MCE.emitWordLE(0xE8BD8800); // LDMFD SP!, [R11, PC]
   }
 
-  return MCE.finishFunctionStub(0);
+  return MCE.finishFunctionStub(F);
 }
 
 /// relocate - Before the JIT can run a block of code that has been emitted,
index 81d896b7f1ad44cba1ce3034aa31c2d28d3c95af..de3ff08ad2a269082710019786cf7564ddca187b 100644 (file)
@@ -34,7 +34,8 @@ namespace llvm {
     /// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
     /// small native function that simply calls the function at the specified
     /// address.
-    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
+    virtual void *emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE);
 
     /// getLazyResolverFunction - Expose the lazy resolver to the JIT.
     virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
index a20ae9fd5e5cdc0811a9cb8ecb70d92fcba8ac55..4fd0ebcaef8432c64c0fabfafed6a65bc2d54b81 100644 (file)
@@ -14,6 +14,7 @@
 #define DEBUG_TYPE "jit"
 #include "AlphaJITInfo.h"
 #include "AlphaRelocations.h"
+#include "llvm/Function.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/Config/alloca.h"
 #include "llvm/Support/Debug.h"
@@ -190,16 +191,17 @@ extern "C" {
 #endif
 }
 
-void *AlphaJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+void *AlphaJITInfo::emitFunctionStub(const Function* F, void *Fn,
+                                     MachineCodeEmitter &MCE) {
   //assert(Fn == AlphaCompilationCallback && "Where are you going?\n");
   //Do things in a stupid slow way!
-  MCE.startFunctionStub(19*4);
+  MCE.startFunctionStub(F, 19*4);
   void* Addr = (void*)(intptr_t)MCE.getCurrentPCValue();
   for (int x = 0; x < 19; ++ x)
     MCE.emitWordLE(0);
   EmitBranchToAt(Addr, Fn);
   DOUT << "Emitting Stub to " << Fn << " at [" << Addr << "]\n";
-  return MCE.finishFunctionStub(0);
+  return MCE.finishFunctionStub(F);
 }
 
 TargetJITInfo::LazyResolverFn
index 29511694d842f621c831e698f72ae890b5df3e3a..7bf51d628d4039af1e7731c967aa693ac3d359d7 100644 (file)
@@ -29,7 +29,8 @@ namespace llvm {
     explicit AlphaJITInfo(TargetMachine &tm) : TM(tm)
     { useGOT = true; }
 
-    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
+    virtual void *emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE);
     virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
     virtual void relocate(void *Function, MachineRelocation *MR,
                           unsigned NumRelocs, unsigned char* GOTBase);
index 6dea3d3306b6c4a13244b5bdb102d2718d4b3420..461cfec34acb6964a490776b98e85fceedf86082 100644 (file)
@@ -15,6 +15,7 @@
 #include "PPCJITInfo.h"
 #include "PPCRelocations.h"
 #include "PPCTargetMachine.h"
+#include "llvm/Function.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/Config/alloca.h"
 #include "llvm/Support/Debug.h"
@@ -338,12 +339,13 @@ defined(__APPLE__)
 #endif
 }
 
-void *PPCJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+void *PPCJITInfo::emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE) {
   // If this is just a call to an external function, emit a branch instead of a
   // call.  The code is the same except for one bit of the last instruction.
   if (Fn != (void*)(intptr_t)PPC32CompilationCallback && 
       Fn != (void*)(intptr_t)PPC64CompilationCallback) {
-    MCE.startFunctionStub(7*4);
+    MCE.startFunctionStub(F, 7*4);
     intptr_t Addr = (intptr_t)MCE.getCurrentPCValue();
     MCE.emitWordBE(0);
     MCE.emitWordBE(0);
@@ -354,10 +356,10 @@ void *PPCJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
     MCE.emitWordBE(0);
     EmitBranchToAt(Addr, (intptr_t)Fn, false, is64Bit);
     SyncICache((void*)Addr, 7*4);
-    return MCE.finishFunctionStub(0);
+    return MCE.finishFunctionStub(F);
   }
 
-  MCE.startFunctionStub(10*4);
+  MCE.startFunctionStub(F, 10*4);
   intptr_t Addr = (intptr_t)MCE.getCurrentPCValue();
   if (is64Bit) {
     MCE.emitWordBE(0xf821ffb1);     // stdu r1,-80(r1)
@@ -382,7 +384,7 @@ void *PPCJITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
   MCE.emitWordBE(0);
   EmitBranchToAt(BranchAddr, (intptr_t)Fn, true, is64Bit);
   SyncICache((void*)Addr, 10*4);
-  return MCE.finishFunctionStub(0);
+  return MCE.finishFunctionStub(F);
 }
 
 
index cce07484d300ff2ddbb21a828a9f75899d31c47b..c93a84aca05f51274b5c22c80811d5815a2eeeb9 100644 (file)
@@ -29,7 +29,8 @@ namespace llvm {
       is64Bit = tmIs64Bit;
     }
 
-    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
+    virtual void *emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE);
     virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn);
     virtual void relocate(void *Function, MachineRelocation *MR,
                           unsigned NumRelocs, unsigned char* GOTBase);
index 5d942a1768e45226e63de518ab8b625c626e7ebf..7f72bd473e37e692c61703e886694c5212a93353 100644 (file)
@@ -15,6 +15,7 @@
 #include "X86JITInfo.h"
 #include "X86Relocations.h"
 #include "X86Subtarget.h"
+#include "llvm/Function.h"
 #include "llvm/CodeGen/MachineCodeEmitter.h"
 #include "llvm/Config/alloca.h"
 #include <cstdlib>
@@ -391,19 +392,21 @@ X86JITInfo::getLazyResolverFunction(JITCompilerFn F) {
   return X86CompilationCallback;
 }
 
-void *X86JITInfo::emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE) {
+void *X86JITInfo::emitGlobalValueLazyPtr(const GlobalValue* GV, void *ptr,
+                                         MachineCodeEmitter &MCE) {
 #if defined (X86_64_JIT)
   MCE.startFunctionStub(8, 8);
-  MCE.emitWordLE(((unsigned *)&GV)[0]);
-  MCE.emitWordLE(((unsigned *)&GV)[1]);
+  MCE.emitWordLE(((unsigned *)&ptr)[0]);
+  MCE.emitWordLE(((unsigned *)&ptr)[1]);
 #else
-  MCE.startFunctionStub(4, 4);
-  MCE.emitWordLE((intptr_t)GV);
+  MCE.startFunctionStub(GV, 4, 4);
+  MCE.emitWordLE((intptr_t)ptr);
 #endif
-  return MCE.finishFunctionStub(0);
+  return MCE.finishFunctionStub(GV);
 }
 
-void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
+void *X86JITInfo::emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE) {
   // Note, we cast to intptr_t here to silence a -pedantic warning that 
   // complains about casting a function pointer to a normal pointer.
 #if defined (X86_32_JIT) && !defined (_MSC_VER)
@@ -414,7 +417,7 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
 #endif
   if (NotCC) {
 #if defined (X86_64_JIT)
-    MCE.startFunctionStub(13, 4);
+    MCE.startFunctionStub(F, 13, 4);
     MCE.emitByte(0x49);          // REX prefix
     MCE.emitByte(0xB8+2);        // movabsq r10
     MCE.emitWordLE(((unsigned *)&Fn)[0]);
@@ -423,15 +426,15 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
     MCE.emitByte(0xFF);          // jmpq *r10
     MCE.emitByte(2 | (4 << 3) | (3 << 6));
 #else
-    MCE.startFunctionStub(5, 4);
+    MCE.startFunctionStub(F, 5, 4);
     MCE.emitByte(0xE9);
     MCE.emitWordLE((intptr_t)Fn-MCE.getCurrentPCValue()-4);
 #endif
-    return MCE.finishFunctionStub(0);
+    return MCE.finishFunctionStub(F);
   }
 
 #if defined (X86_64_JIT)
-  MCE.startFunctionStub(14, 4);
+  MCE.startFunctionStub(F, 14, 4);
   MCE.emitByte(0x49);          // REX prefix
   MCE.emitByte(0xB8+2);        // movabsq r10
   MCE.emitWordLE(((unsigned *)&Fn)[0]);
@@ -440,14 +443,14 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
   MCE.emitByte(0xFF);          // callq *r10
   MCE.emitByte(2 | (2 << 3) | (3 << 6));
 #else
-  MCE.startFunctionStub(6, 4);
+  MCE.startFunctionStub(F, 6, 4);
   MCE.emitByte(0xE8);   // Call with 32 bit pc-rel destination...
 
   MCE.emitWordLE((intptr_t)Fn-MCE.getCurrentPCValue()-4);
 #endif
 
   MCE.emitByte(0xCD);   // Interrupt - Just a marker identifying the stub!
-  return MCE.finishFunctionStub(0);
+  return MCE.finishFunctionStub(F);
 }
 
 /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
index 69bebd0270cadc3f880333a28ac3403fb368d204..f9fcefecff5b3d6905e038625cd87804d99afc1e 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef X86JITINFO_H
 #define X86JITINFO_H
 
+#include "llvm/Function.h"
 #include "llvm/Target/TargetJITInfo.h"
 
 namespace llvm {
@@ -33,13 +34,15 @@ namespace llvm {
     virtual void replaceMachineCodeForFunction(void *Old, void *New);
 
     /// emitGlobalValueLazyPtr - Use the specified MachineCodeEmitter object to
-    /// emit a lazy pointer which contains the address of the specified GV.
-    virtual void *emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE);
+    /// emit a lazy pointer which contains the address of the specified ptr.
+    virtual void *emitGlobalValueLazyPtr(const GlobalValue* GV, void *ptr,
+                                         MachineCodeEmitter &MCE);
 
     /// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
     /// small native function that simply calls the function at the specified
     /// address.
-    virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE);
+    virtual void *emitFunctionStub(const Function* F, void *Fn,
+                                   MachineCodeEmitter &MCE);
 
     /// getPICJumpTableEntry - Returns the value of the jumptable entry for the
     /// specific basic block.