[llvm-commits] [llvm] r86941 - in /llvm/trunk: lib/ExecutionEngine/JIT/JITEmitter.cpp unittests/ExecutionEngine/JIT/JITTest.cpp

Eric Christopher echristo at apple.com
Thu Nov 12 09:11:58 PST 2009


Yeah I sent mail to test results last night. I can't duplicate it on  
my machine in either 32 or 64bit. I asked Jeffrey for a bit of help  
tracking it down. If you've got a machine in the office that can  
duplicate it that'd be awesome :)

-eric

On Nov 12, 2009, at 7:42 AM, Daniel Dunbar <daniel at zuster.org> wrote:

> Hi Eric,
>
> This test:
>  LLVM-Unit::ExecutionEngine/JIT/Debug/JITTests/ 
> JITTest.FarCallToKnownFunction
> appears to be failing with this change, on linux and x86_64. Can you
> take a look?
>
> - Daniel
>
> On Wed, Nov 11, 2009 at 7:12 PM, Eric Christopher  
> <echristo at apple.com> wrote:
>> Author: echristo
>> Date: Wed Nov 11 21:12:18 2009
>> New Revision: 86941
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=86941&view=rev
>> Log:
>> Use stubs when we have them, otherwise use code we already have,
>> otherwise create a stub.
>>
>> Add a test to make sure we don't create extraneous stubs.
>>
>> Modified:
>>    llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
>>    llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=86941&r1=86940&r2=86941&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Wed Nov 11  
>> 21:12:18 2009
>> @@ -225,7 +225,7 @@
>>       assert(TheJITResolver == 0 && "Multiple JIT resolvers?");
>>       TheJITResolver = this;
>>     }
>> -
>> +
>>     ~JITResolver() {
>>       TheJITResolver = 0;
>>     }
>> @@ -256,10 +256,10 @@
>>       state.AddCallSite(locked, Location, F);
>>       return (void*)(intptr_t)LazyResolverFn;
>>     }
>> -
>> +
>>     void getRelocatableGVs(SmallVectorImpl<GlobalValue*> &GVs,
>>                            SmallVectorImpl<void*> &Ptrs);
>> -
>> +
>>     GlobalValue *invalidateStub(void *Stub);
>>
>>     /// getGOTIndexForAddress - Return a new or existing index in  
>> the GOT for
>> @@ -291,7 +291,7 @@
>>     /// Relocations - These are the relocations that the function  
>> needs, as
>>     /// emitted.
>>     std::vector<MachineRelocation> Relocations;
>> -
>> +
>>     /// MBBLocations - This vector is a mapping from MBB ID's to  
>> their address.
>>     /// It is filled in by the StartMachineBasicBlock callback and  
>> queried by
>>     /// the getMachineBasicBlockAddress callback.
>> @@ -312,7 +312,7 @@
>>     /// JumpTable - The jump tables for the current function.
>>     ///
>>     MachineJumpTableInfo *JumpTable;
>> -
>> +
>>     /// JumpTableBase - A pointer to the first entry in the jump  
>> table.
>>     ///
>>     void *JumpTableBase;
>> @@ -326,7 +326,7 @@
>>     /// DR - The debug registerer for the jit.
>>     OwningPtr<JITDebugRegisterer> DR;
>>
>> -    /// LabelLocations - This vector is a mapping from Label ID's  
>> to their
>> +    /// LabelLocations - This vector is a mapping from Label ID's  
>> to their
>>     /// address.
>>     std::vector<uintptr_t> LabelLocations;
>>
>> @@ -336,7 +336,7 @@
>>     // GVSet - a set to keep track of which globals have been seen
>>     SmallPtrSet<const GlobalVariable*, 8> GVSet;
>>
>> -    // CurFn - The llvm function being emitted.  Only valid during
>> +    // CurFn - The llvm function being emitted.  Only valid during
>>     // finishFunction().
>>     const Function *CurFn;
>>
>> @@ -368,7 +368,7 @@
>>     // reference the stub.  When the count of a stub's references  
>> drops to zero,
>>     // the stub is unused.
>>     DenseMap<void *, SmallPtrSet<const Function*, 1> > StubFnRefs;
>> -
>> +
>>     DebugLocTuple PrevDLT;
>>
>>   public:
>> @@ -388,7 +388,7 @@
>>         DR.reset(new JITDebugRegisterer(TM));
>>       }
>>     }
>> -    ~JITEmitter() {
>> +    ~JITEmitter() {
>>       delete MemMgr;
>>     }
>>
>> @@ -397,16 +397,16 @@
>>     ///
>>     static inline bool classof(const JITEmitter*) { return true; }
>>     static inline bool classof(const MachineCodeEmitter*) { return  
>> true; }
>> -
>> +
>>     JITResolver &getJITResolver() { return Resolver; }
>>
>>     virtual void startFunction(MachineFunction &F);
>>     virtual bool finishFunction(MachineFunction &F);
>> -
>> +
>>     void emitConstantPool(MachineConstantPool *MCP);
>>     void initJumpTableInfo(MachineJumpTableInfo *MJTI);
>>     void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
>> -
>> +
>>     virtual void startGVStub(const GlobalValue* GV, unsigned  
>> StubSize,
>>                                    unsigned Alignment = 1);
>>     virtual void startGVStub(const GlobalValue* GV, void *Buffer,
>> @@ -425,7 +425,7 @@
>>     virtual void addRelocation(const MachineRelocation &MR) {
>>       Relocations.push_back(MR);
>>     }
>> -
>> +
>>     virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) {
>>       if (MBBLocations.size() <= (unsigned)MBB->getNumber())
>>         MBBLocations.resize((MBB->getNumber()+1)*2);
>> @@ -438,7 +438,7 @@
>>     virtual uintptr_t getJumpTableEntryAddress(unsigned Entry) const;
>>
>>     virtual uintptr_t getMachineBasicBlockAddress(MachineBasicBlock  
>> *MBB) const {
>> -      assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
>> +      assert(MBBLocations.size() > (unsigned)MBB->getNumber() &&
>>              MBBLocations[MBB->getNumber()] && "MBB not emitted!");
>>       return MBBLocations[MBB->getNumber()];
>>     }
>> @@ -456,7 +456,7 @@
>>     /// using the stub at the specified address. Allows
>>     /// deallocateMemForFunction to also remove stubs no longer  
>> referenced.
>>     void AddStubToCurrentFunction(void *Stub);
>> -
>> +
>>     virtual void processDebugLoc(DebugLoc DL, bool  
>> BeforePrintingInsn);
>>
>>     virtual void emitLabel(uint64_t LabelID) {
>> @@ -466,11 +466,11 @@
>>     }
>>
>>     virtual uintptr_t getLabelAddress(uint64_t LabelID) const {
>> -      assert(LabelLocations.size() > (unsigned)LabelID &&
>> +      assert(LabelLocations.size() > (unsigned)LabelID &&
>>              LabelLocations[LabelID] && "Label not emitted!");
>>       return LabelLocations[LabelID];
>>     }
>> -
>> +
>>     virtual void setModuleInfo(MachineModuleInfo* Info) {
>>       MMI = Info;
>>       if (DE.get()) DE->setModuleInfo(Info);
>> @@ -479,7 +479,7 @@
>>     void setMemoryExecutable() {
>>       MemMgr->setMemoryExecutable();
>>     }
>> -
>> +
>>     JITMemoryManager *getMemMgr() const { return MemMgr; }
>>
>>   private:
>> @@ -573,7 +573,7 @@
>>   IndirectSym = TheJIT->getJITInfo().emitGlobalValueIndirectSym(GV,  
>> GVAddress,
>>                                                                 JE);
>>
>> -  DEBUG(errs() << "JIT: Indirect symbol emitted at [" << IndirectSym
>> +  DEBUG(errs() << "JIT: Indirect symbol emitted at [" << IndirectSym
>>         << "] for GV '" << GV->getName() << "'\n");
>>
>>   return IndirectSym;
>> @@ -607,10 +607,10 @@
>>  void JITResolver::getRelocatableGVs(SmallVectorImpl<GlobalValue*>  
>> &GVs,
>>                                     SmallVectorImpl<void*> &Ptrs) {
>>   MutexGuard locked(TheJIT->lock);
>> -
>> +
>>   const FunctionToStubMapTy &FM = state.getFunctionToStubMap(locked);
>>   GlobalToIndirectSymMapTy &GM = state.getGlobalToIndirectSymMap 
>> (locked);
>> -
>> +
>>   for (FunctionToStubMapTy::const_iterator i = FM.begin(), e =  
>> FM.end();
>>        i != e; ++i){
>>     Function *F = i->first;
>> @@ -646,7 +646,7 @@
>>     GM.erase(i);
>>     return GV;
>>   }
>> -
>> +
>>   // Lastly, check to see if it's in the ExternalFnToStubMap.
>>   for (std::map<void *, void *>::iterator i =  
>> ExternalFnToStubMap.begin(),
>>        e = ExternalFnToStubMap.end(); i != e; ++i) {
>> @@ -655,7 +655,7 @@
>>     ExternalFnToStubMap.erase(i);
>>     break;
>>   }
>> -
>> +
>>   return 0;
>>  }
>>
>> @@ -664,7 +664,7 @@
>>  /// it if necessary, then returns the resultant function pointer.
>>  void *JITResolver::JITCompilerFn(void *Stub) {
>>   JITResolver &JR = *TheJITResolver;
>> -
>> +
>>   Function* F = 0;
>>   void* ActualPtr = 0;
>>
>> @@ -684,16 +684,16 @@
>>
>>   // If we have already code generated the function, just return  
>> the address.
>>   void *Result = TheJIT->getPointerToGlobalIfAvailable(F);
>> -
>> +
>>   if (!Result) {
>>     // Otherwise we don't have it, do lazy compilation now.
>> -
>> +
>>     // If lazy compilation is disabled, emit a useful error message  
>> and abort.
>>     if (!TheJIT->isCompilingLazily()) {
>>       llvm_report_error("LLVM JIT requested to do lazy compilation  
>> of function '"
>>                         + F->getName() + "' when lazy compiles are  
>> disabled!");
>>     }
>> -
>> +
>>     DEBUG(errs() << "JIT: Lazily resolving function '" << F->getName 
>> ()
>>           << "' In stub ptr = " << Stub << " actual ptr = "
>>           << ActualPtr << "\n");
>> @@ -736,15 +736,18 @@
>>
>>   // If we have already compiled the function, return a pointer to  
>> its body.
>>   Function *F = cast<Function>(V);
>> -  void *ResultPtr;
>> -  if (MayNeedFarStub) {
>> -    // Return the function stub if it's already created.
>> -    ResultPtr = Resolver.getFunctionStubIfAvailable(F);
>> -    if (ResultPtr)
>> -      AddStubToCurrentFunction(ResultPtr);
>> -  } else {
>> -    ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
>> +
>> +  void *FnStub = Resolver.getFunctionStubIfAvailable(F);
>> +  if (FnStub) {
>> +    // Return the function stub if it's already created.  We do  
>> this first
>> +    // so that we're returning the same address for the function  
>> as any
>> +    // previous call.
>> +    AddStubToCurrentFunction(FnStub);
>> +    return FnStub;
>>   }
>> +
>> +  // Otherwise if we have code, go ahead and return that.
>> +  void *ResultPtr = TheJIT->getPointerToGlobalIfAvailable(F);
>>   if (ResultPtr) return ResultPtr;
>>
>>   // If this is an external function pointer, we can force the JIT to
>> @@ -778,11 +781,11 @@
>>   // resolved address.
>>   void *GVAddress = getPointerToGlobal(V, Reference, false);
>>   void *StubAddr = Resolver.getGlobalValueIndirectSym(V, GVAddress);
>> -
>> +
>>   // Add the stub to the current function's list of referenced  
>> stubs, so we can
>>   // deallocate them if the current function is ever freed.
>>   AddStubToCurrentFunction(StubAddr);
>> -
>> +
>>   return StubAddr;
>>  }
>>
>> @@ -807,7 +810,7 @@
>>         NextLine.Loc = DL;
>>         EmissionDetails.LineStarts.push_back(NextLine);
>>       }
>> -
>> +
>>       PrevDLT = CurDLT;
>>     }
>>   }
>> @@ -832,7 +835,7 @@
>>  static unsigned GetJumpTableSizeInBytes(MachineJumpTableInfo  
>> *MJTI) {
>>   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables 
>> ();
>>   if (JT.empty()) return 0;
>> -
>> +
>>   unsigned NumEntries = 0;
>>   for (unsigned i = 0, e = JT.size(); i != e; ++i)
>>     NumEntries += JT[i].MBBs.size();
>> @@ -844,7 +847,7 @@
>>
>>  static uintptr_t RoundUpToAlign(uintptr_t Size, unsigned  
>> Alignment) {
>>   if (Alignment == 0) Alignment = 1;
>> -  // Since we do not know where the buffer will be allocated, be  
>> pessimistic.
>> +  // Since we do not know where the buffer will be allocated, be  
>> pessimistic.
>>   return Size + Alignment;
>>  }
>>
>> @@ -854,7 +857,7 @@
>>  unsigned JITEmitter::addSizeOfGlobal(const GlobalVariable *GV,  
>> unsigned Size) {
>>   const Type *ElTy = GV->getType()->getElementType();
>>   size_t GVSize = (size_t)TheJIT->getTargetData()->getTypeAllocSize 
>> (ElTy);
>> -  size_t GVAlign =
>> +  size_t GVAlign =
>>       (size_t)TheJIT->getTargetData()->getPreferredAlignment(GV);
>>   DEBUG(errs() << "JIT: Adding in size " << GVSize << " alignment "  
>> << GVAlign);
>>   DEBUG(GV->dump());
>> @@ -871,7 +874,7 @@
>>  /// but are referenced from the constant; put them in GVSet and  
>> add their
>>  /// size into the running total Size.
>>
>> -unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant  
>> *C,
>> +unsigned JITEmitter::addSizeOfGlobalsInConstantVal(const Constant  
>> *C,
>>                                               unsigned Size) {
>>   // If its undefined, return the garbage.
>>   if (isa<UndefValue>(C))
>> @@ -934,7 +937,7 @@
>>  /// addSizeOfGLobalsInInitializer - handle any globals that we  
>> haven't seen yet
>>  /// but are referenced from the given initializer.
>>
>> -unsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant  
>> *Init,
>> +unsigned JITEmitter::addSizeOfGlobalsInInitializer(const Constant  
>> *Init,
>>                                               unsigned Size) {
>>   if (!isa<UndefValue>(Init) &&
>>       !isa<ConstantVector>(Init) &&
>> @@ -955,7 +958,7 @@
>>   unsigned Size = 0;
>>   GVSet.clear();
>>
>> -  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
>> +  for (MachineFunction::iterator MBB = MF.begin(), E = MF.end();
>>        MBB != E; ++MBB) {
>>     for (MachineBasicBlock::const_iterator I = MBB->begin(), E =  
>> MBB->end();
>>          I != E; ++I) {
>> @@ -987,7 +990,7 @@
>>   DEBUG(errs() << "JIT: About to look through initializers\n");
>>   // Look for more globals that are referenced only from  
>> initializers.
>>   // GVSet.end is computed each time because the set can grow as we  
>> go.
>> -  for (SmallPtrSet<const GlobalVariable *, 8>::iterator I =  
>> GVSet.begin();
>> +  for (SmallPtrSet<const GlobalVariable *, 8>::iterator I =  
>> GVSet.begin();
>>        I != GVSet.end(); I++) {
>>     const GlobalVariable* GV = *I;
>>     if (GV->hasInitializer())
>> @@ -1009,10 +1012,10 @@
>>     const TargetInstrInfo* TII = F.getTarget().getInstrInfo();
>>     MachineJumpTableInfo *MJTI = F.getJumpTableInfo();
>>     MachineConstantPool *MCP = F.getConstantPool();
>> -
>> +
>>     // Ensure the constant pool/jump table info is at least 4-byte  
>> aligned.
>>     ActualSize = RoundUpToAlign(ActualSize, 16);
>> -
>> +
>>     // Add the alignment of the constant pool
>>     ActualSize = RoundUpToAlign(ActualSize, MCP- 
>> >getConstantPoolAlignment());
>>
>> @@ -1024,7 +1027,7 @@
>>
>>     // Add the jump table size
>>     ActualSize += GetJumpTableSizeInBytes(MJTI);
>> -
>> +
>>     // Add the alignment for the function
>>     ActualSize = RoundUpToAlign(ActualSize,
>>                                 std::max(F.getFunction()- 
>> >getAlignment(), 8U));
>> @@ -1097,7 +1100,7 @@
>>           ResultPtr = TheJIT->getPointerToNamedFunction 
>> (MR.getExternalSymbol(),
>>                                                         false);
>>           DEBUG(errs() << "JIT: Map \'" << MR.getExternalSymbol()  
>> << "\' to ["
>> -                       << ResultPtr << "]\n");
>> +                       << ResultPtr << "]\n");
>>
>>           // If the target REALLY wants a stub for this function,  
>> emit it now.
>>           if (MR.mayNeedFarStub()) {
>> @@ -1255,7 +1258,7 @@
>>
>>   if (MMI)
>>     MMI->EndFunction();
>> -
>> +
>>   return false;
>>  }
>>
>> @@ -1293,20 +1296,20 @@
>>   // If the function did not reference any stubs, return.
>>   if (CurFnStubUses.find(F) == CurFnStubUses.end())
>>     return;
>> -
>> +
>>   // For each referenced stub, erase the reference to this  
>> function, and then
>>   // erase the list of referenced stubs.
>>   SmallVectorImpl<void *> &StubList = CurFnStubUses[F];
>>   for (unsigned i = 0, e = StubList.size(); i != e; ++i) {
>>     void *Stub = StubList[i];
>> -
>> +
>>     // If we already invalidated this stub for this function,  
>> continue.
>>     if (StubFnRefs.count(Stub) == 0)
>>       continue;
>> -
>> +
>>     SmallPtrSet<const Function *, 1> &FnRefs = StubFnRefs[Stub];
>>     FnRefs.erase(F);
>> -
>> +
>>     // If this function was the last reference to the stub,  
>> invalidate the stub
>>     // in the JITResolver.  Were there a memory manager  
>> deallocateStub routine,
>>     // we could call that at this point too.
>> @@ -1389,7 +1392,7 @@
>>
>>   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables 
>> ();
>>   if (JT.empty()) return;
>> -
>> +
>>   unsigned NumEntries = 0;
>>   for (unsigned i = 0, e = JT.size(); i != e; ++i)
>>     NumEntries += JT[i].MBBs.size();
>> @@ -1409,7 +1412,7 @@
>>
>>   const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables 
>> ();
>>   if (JT.empty() || JumpTableBase == 0) return;
>> -
>> +
>>   if (TargetMachine::getRelocationModel() == Reloc::PIC_) {
>>     assert(MJTI->getEntrySize() == 4 && "Cross JIT'ing?");
>>     // For each jump table, place the offset from the beginning of  
>> the table
>> @@ -1428,8 +1431,8 @@
>>     }
>>   } else {
>>     assert(MJTI->getEntrySize() == sizeof(void*) && "Cross  
>> JIT'ing?");
>> -
>> -    // For each jump table, map each target in the jump table to  
>> the address of
>> +
>> +    // For each jump table, map each target in the jump table to  
>> the address of
>>     // an emitted MachineBasicBlock.
>>     intptr_t *SlotPtr = (intptr_t*)JumpTableBase;
>>
>> @@ -1448,7 +1451,7 @@
>>   SavedBufferBegin = BufferBegin;
>>   SavedBufferEnd = BufferEnd;
>>   SavedCurBufferPtr = CurBufferPtr;
>> -
>> +
>>   BufferBegin = CurBufferPtr = MemMgr->allocateStub(GV, StubSize,  
>> Alignment);
>>   BufferEnd = BufferBegin+StubSize+1;
>>  }
>> @@ -1458,7 +1461,7 @@
>>   SavedBufferBegin = BufferBegin;
>>   SavedBufferEnd = BufferEnd;
>>   SavedCurBufferPtr = CurBufferPtr;
>> -
>> +
>>   BufferBegin = CurBufferPtr = (uint8_t *)Buffer;
>>   BufferEnd = BufferBegin+StubSize+1;
>>  }
>> @@ -1487,15 +1490,15 @@
>>  uintptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index)  
>> const {
>>   const std::vector<MachineJumpTableEntry> &JT = JumpTable- 
>> >getJumpTables();
>>   assert(Index < JT.size() && "Invalid jump table index!");
>> -
>> +
>>   unsigned Offset = 0;
>>   unsigned EntrySize = JumpTable->getEntrySize();
>> -
>> +
>>   for (unsigned i = 0; i < Index; ++i)
>>     Offset += JT[i].MBBs.size();
>> -
>> +
>>    Offset *= EntrySize;
>> -
>> +
>>   return (uintptr_t)((char *)JumpTableBase + Offset);
>>  }
>>
>> @@ -1540,7 +1543,7 @@
>>   // If we have already code generated the function, just return  
>> the address.
>>   if (void *Addr = getPointerToGlobalIfAvailable(F))
>>     return Addr;
>> -
>> +
>>   // Get a stub if the target supports it.
>>   assert(isa<JITEmitter>(JCE) && "Unexpected MCE?");
>>   JITEmitter *JE = cast<JITEmitter>(getCodeEmitter());
>>
>> Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=86941&r1=86940&r2=86941&view=diff
>>
>> === 
>> === 
>> === 
>> =====================================================================
>> --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
>> +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Wed Nov 11  
>> 21:12:18 2009
>> @@ -61,6 +61,7 @@
>>  public:
>>   RecordingJITMemoryManager()
>>     : Base(JITMemoryManager::CreateDefaultMemManager()) {
>> +    stubsAllocated = 0;
>>   }
>>
>>   virtual void setMemoryWritable() { Base->setMemoryWritable(); }
>> @@ -88,8 +89,10 @@
>>       StartFunctionBodyCall(Result, F, InitialActualSize,  
>> ActualSize));
>>     return Result;
>>   }
>> +  int stubsAllocated;
>>   virtual uint8_t *allocateStub(const GlobalValue* F, unsigned  
>> StubSize,
>>                                 unsigned Alignment) {
>> +    stubsAllocated++;
>>     return Base->allocateStub(F, StubSize, Alignment);
>>   }
>>   struct EndFunctionBodyCall {
>> @@ -455,6 +458,44 @@
>>             NumTablesDeallocated);
>>  }
>>
>> +typedef int (*FooPtr) ();
>> +
>> +TEST_F(JITTest, NoStubs) {
>> +  LoadAssembly("define void @bar() {"
>> +              "entry: "
>> +              "ret void"
>> +              "}"
>> +              " "
>> +              "define i32 @foo() {"
>> +              "entry:"
>> +              "call void @bar()"
>> +              "ret i32 undef"
>> +              "}"
>> +              " "
>> +              "define i32 @main() {"
>> +              "entry:"
>> +              "%0 = call i32 @foo()"
>> +              "call void @bar()"
>> +              "ret i32 undef"
>> +              "}");
>> +  Function *foo = M->getFunction("foo");
>> +  uintptr_t tmp = (uintptr_t)(TheJIT->getPointerToFunction(foo));
>> +  FooPtr ptr = (FooPtr)(tmp);
>> +
>> +  (ptr)();
>> +
>> +  // We should now allocate no more stubs, we have the code to foo
>> +  // and the existing stub for bar.
>> +  int stubsBefore = RJMM->stubsAllocated;
>> +  Function *func = M->getFunction("main");
>> +  TheJIT->getPointerToFunction(func);
>> +
>> +  Function *bar = M->getFunction("bar");
>> +  TheJIT->getPointerToFunction(bar);
>> +
>> +  ASSERT_EQ(stubsBefore, RJMM->stubsAllocated);
>> +}
>> +
>>  // This code is copied from JITEventListenerTest, but it only runs  
>> once for all
>>  // the tests in this directory.  Everything seems fine, but that's  
>> strange
>>  // behavior.
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>>



More information about the llvm-commits mailing list