[llvm-commits] CVS: llvm/tools/bugpoint/Miscompilation.cpp
Chris Lattner
lattner at cs.uiuc.edu
Mon Jul 11 18:00:43 PDT 2005
Changes in directory llvm/tools/bugpoint:
Miscompilation.cpp updated: 1.67 -> 1.68
---
Log message:
Fix PR576: http://llvm.cs.uiuc.edu/PR576 .
Instead of emitting a JIT stub that looks like this:
internal void %l1_main_entry_2E_ce_wrapper(int) {
header:
%resolver = call sbyte* %getPointerToNamedFunction( sbyte* getelementptr ([20 x sbyte]* %l1_main_entry_2E_ce_name, int 0, int 0) ) ; <sbyte*> [#uses=1]
%resolverCast = cast sbyte* %resolver to void (int)* ; <void (int)*> [#uses=1]
call void %resolverCast( int %0 )
ret void
}
Emit one that looks like this:
internal void %l1_main_entry_2E_ce_wrapper(int) {
Entry:
%fpcache = load void (int)** %l1_main_entry_2E_ce.fpcache ; <void (int)*> [#uses=2]
%isNull = seteq void (int)* %fpcache, null ; <bool> [#uses=1]
br bool %isNull, label %lookupfp, label %usecache
usecache: ; preds = %lookupfp, %Entry
%fp = phi void (int)* [ %resolverCast, %lookupfp ], [ %fpcache, %Entry ] ; <void (int)*> [#uses=1]
call void %fp( int %0 )
ret void
lookupfp: ; preds = %Entry
%resolver = call sbyte* %getPointerToNamedFunction( sbyte* getelementptr ([20 x sbyte]* %l1_main_entry_2E_ce_name, int 0, int 0) ) ; <sbyte*> [#uses=1]
%resolverCast = cast sbyte* %resolver to void (int)* ; <void (int)*> [#uses=2]
store void (int)* %resolverCast, void (int)** %l1_main_entry_2E_ce.fpcache
br label %usecache
}
This makes the JIT debugger *MUCH* faster on large programs, as
getPointerToNamedFunction takes time linear with the size of the program, and
before we would call it every time a function in the text module was called from
the safe module (ouch!).
---
Diffs of the changes: (+36 -21)
Miscompilation.cpp | 57 +++++++++++++++++++++++++++++++++--------------------
1 files changed, 36 insertions(+), 21 deletions(-)
Index: llvm/tools/bugpoint/Miscompilation.cpp
diff -u llvm/tools/bugpoint/Miscompilation.cpp:1.67 llvm/tools/bugpoint/Miscompilation.cpp:1.68
--- llvm/tools/bugpoint/Miscompilation.cpp:1.67 Thu Jul 7 22:08:58 2005
+++ llvm/tools/bugpoint/Miscompilation.cpp Mon Jul 11 20:00:32 2005
@@ -686,28 +686,47 @@
// Rewrite uses of F in global initializers, etc. to uses of a wrapper
// function that dynamically resolves the calls to F via our JIT API
- if (F->use_begin() != F->use_end()) {
+ if (!F->use_empty()) {
+ // Create a new global to hold the cached function pointer.
+ Constant *NullPtr = ConstantPointerNull::get(F->getType());
+ GlobalVariable *Cache =
+ new GlobalVariable(F->getType(), false,GlobalValue::InternalLinkage,
+ NullPtr,F->getName()+".fpcache", F->getParent());
+
// Construct a new stub function that will re-route calls to F
const FunctionType *FuncTy = F->getFunctionType();
Function *FuncWrapper = new Function(FuncTy,
GlobalValue::InternalLinkage,
F->getName() + "_wrapper",
F->getParent());
- BasicBlock *Header = new BasicBlock("header", FuncWrapper);
-
+ BasicBlock *EntryBB = new BasicBlock("entry", FuncWrapper);
+ BasicBlock *DoCallBB = new BasicBlock("usecache", FuncWrapper);
+ BasicBlock *LookupBB = new BasicBlock("lookupfp", FuncWrapper);
+
+ // Check to see if we already looked up the value.
+ Value *CachedVal = new LoadInst(Cache, "fpcache", EntryBB);
+ Value *IsNull = new SetCondInst(Instruction::SetEQ, CachedVal,
+ NullPtr, "isNull", EntryBB);
+ new BranchInst(LookupBB, DoCallBB, IsNull, EntryBB);
+
// Resolve the call to function F via the JIT API:
//
// call resolver(GetElementPtr...)
- CallInst *resolve = new CallInst(resolverFunc, ResolverArgs,
- "resolver");
- Header->getInstList().push_back(resolve);
+ CallInst *Resolver = new CallInst(resolverFunc, ResolverArgs,
+ "resolver", LookupBB);
// cast the result from the resolver to correctly-typed function
- CastInst *castResolver =
- new CastInst(resolve, PointerType::get(F->getFunctionType()),
- "resolverCast");
- Header->getInstList().push_back(castResolver);
-
- // Save the argument list
+ CastInst *CastedResolver =
+ new CastInst(Resolver, PointerType::get(F->getFunctionType()),
+ "resolverCast", LookupBB);
+ // Save the value in our cache.
+ new StoreInst(CastedResolver, Cache, LookupBB);
+ new BranchInst(DoCallBB, LookupBB);
+
+ PHINode *FuncPtr = new PHINode(NullPtr->getType(), "fp", DoCallBB);
+ FuncPtr->addIncoming(CastedResolver, LookupBB);
+ FuncPtr->addIncoming(CachedVal, EntryBB);
+
+ // Save the argument list.
std::vector<Value*> Args;
for (Function::arg_iterator i = FuncWrapper->arg_begin(),
e = FuncWrapper->arg_end(); i != e; ++i)
@@ -715,17 +734,13 @@
// Pass on the arguments to the real function, return its result
if (F->getReturnType() == Type::VoidTy) {
- CallInst *Call = new CallInst(castResolver, Args);
- Header->getInstList().push_back(Call);
- ReturnInst *Ret = new ReturnInst();
- Header->getInstList().push_back(Ret);
+ CallInst *Call = new CallInst(FuncPtr, Args, "", DoCallBB);
+ new ReturnInst(DoCallBB);
} else {
- CallInst *Call = new CallInst(castResolver, Args, "redir");
- Header->getInstList().push_back(Call);
- ReturnInst *Ret = new ReturnInst(Call);
- Header->getInstList().push_back(Ret);
+ CallInst *Call = new CallInst(FuncPtr, Args, "retval", DoCallBB);
+ new ReturnInst(Call, DoCallBB);
}
-
+
// Use the wrapper function instead of the old function
F->replaceAllUsesWith(FuncWrapper);
}
More information about the llvm-commits
mailing list