diff -ur include/llvm/BasicBlock.h.orig include/llvm/BasicBlock.h --- include/llvm/BasicBlock.h.orig (revision 105101) +++ include/llvm/BasicBlock.h (working copy) @@ -74,6 +74,7 @@ private: InstListType InstList; Function *Parent; + mutable uintptr_t PCInJit; // this is the code offset of this block inside it's function void setParent(Function *parent); friend class SymbolTableListTraits; @@ -109,6 +110,18 @@ const Function *getParent() const { return Parent; } Function *getParent() { return Parent; } + /// setPCInJit - sets offset of this BB in the enclosing Function + // + void setPCInJit(uintptr_t NewPCInJit) const { + if (PCInJit==~uintptr_t(0)) { // ignore subsequent locations as they result from the original BB split into multiple MBBs + PCInJit = NewPCInJit; + } + } + + /// getPCInJit - Return the offset of this BB in the enclosing Function + // + uintptr_t getPCInJit() const { return PCInJit; } + /// use_back - Specialize the methods defined in Value, as we know that an /// BasicBlock can only be used by Users (specifically PHI nodes, terminators, /// and BlockAddress's). diff -ur lib/ExecutionEngine/JIT/JITEmitter.cpp.orig lib/ExecutionEngine/JIT/JITEmitter.cpp --- lib/ExecutionEngine/JIT/JITEmitter.cpp.orig (revision 105101) +++ lib/ExecutionEngine/JIT/JITEmitter.cpp (working copy) @@ -435,6 +435,7 @@ if (MBBLocations.size() <= (unsigned)MBB->getNumber()) MBBLocations.resize((MBB->getNumber()+1)*2); MBBLocations[MBB->getNumber()] = getCurrentPCValue(); + MBB->getBasicBlock()->setPCInJit(getCurrentPCValue()); DEBUG(dbgs() << "JIT: Emitting BB" << MBB->getNumber() << " at [" << (void*) getCurrentPCValue() << "]\n"); } diff -ur lib/ExecutionEngine/JIT/JIT.cpp.orig lib/ExecutionEngine/JIT/JIT.cpp --- lib/ExecutionEngine/JIT/JIT.cpp.orig (revision 105101) +++ lib/ExecutionEngine/JIT/JIT.cpp (working copy) @@ -687,6 +687,14 @@ return Addr; } +void *JIT::getPointerToBasicBlock(BasicBlock *BB) { + // make sure it's function is compiled by JIT + (void)getPointerToFunction(BB->getParent()); + // return PC address + assert(BB->getPCInJit()!=~uintptr_t(0) && "JIT does not have BB address for address-of-label, was it eliminated by optimizer?"); + return (void*)BB->getPCInJit(); +} + /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the /// Emitter. diff -ur lib/ExecutionEngine/JIT/JIT.h.orig lib/ExecutionEngine/JIT/JIT.h --- lib/ExecutionEngine/JIT/JIT.h.orig (revision 105101) +++ lib/ExecutionEngine/JIT/JIT.h (working copy) @@ -127,10 +127,9 @@ /// void *getPointerToFunction(Function *F); - void *getPointerToBasicBlock(BasicBlock *BB) { - assert(0 && "JIT does not support address-of-label yet!"); - return 0; - } + /// getPointerToBasicBlock - This returns the address of the specified basic + /// block, assuming function is compiled + void *getPointerToBasicBlock(BasicBlock *BB); /// getOrEmitGlobalVariable - Return the address of the specified global /// variable, possibly emitting it to memory if needed. This is used by the diff -ur lib/VMCore/BasicBlock.cpp.orig lib/VMCore/BasicBlock.cpp --- lib/VMCore/BasicBlock.cpp.orig (revision 105101) +++ lib/VMCore/BasicBlock.cpp (working copy) @@ -41,7 +41,7 @@ BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent, BasicBlock *InsertBefore) - : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0) { + : Value(Type::getLabelTy(C), Value::BasicBlockVal), Parent(0), PCInJit((uintptr_t)-1) { // Make sure that we get added to a function LeakDetector::addGarbageObject(this);