forked from OSchip/llvm-project
Teach the CallGraph to ignore calls to intrinsics.
llvm-svn: 132797
This commit is contained in:
parent
9008377c2d
commit
729c35b680
|
@ -259,6 +259,9 @@ public:
|
||||||
/// addCalledFunction - Add a function to the list of functions called by this
|
/// addCalledFunction - Add a function to the list of functions called by this
|
||||||
/// one.
|
/// one.
|
||||||
void addCalledFunction(CallSite CS, CallGraphNode *M) {
|
void addCalledFunction(CallSite CS, CallGraphNode *M) {
|
||||||
|
assert(!CS.getInstruction() ||
|
||||||
|
!CS.getCalledFunction() ||
|
||||||
|
!CS.getCalledFunction()->isIntrinsic());
|
||||||
CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
|
CalledFunctions.push_back(std::make_pair(CS.getInstruction(), M));
|
||||||
M->AddRef();
|
M->AddRef();
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ private:
|
||||||
for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
|
for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
|
||||||
II != IE; ++II) {
|
II != IE; ++II) {
|
||||||
CallSite CS(cast<Value>(II));
|
CallSite CS(cast<Value>(II));
|
||||||
if (CS && !isa<DbgInfoIntrinsic>(II)) {
|
if (CS && !isa<IntrinsicInst>(II)) {
|
||||||
const Function *Callee = CS.getCalledFunction();
|
const Function *Callee = CS.getCalledFunction();
|
||||||
if (Callee)
|
if (Callee)
|
||||||
Node->addCalledFunction(CS, getOrInsertFunction(Callee));
|
Node->addCalledFunction(CS, getOrInsertFunction(Callee));
|
||||||
|
|
|
@ -245,8 +245,8 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC,
|
||||||
|
|
||||||
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
||||||
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
|
||||||
CallSite CS(cast<Value>(I));
|
CallSite CS(cast<Value>(I));
|
||||||
if (!CS || isa<DbgInfoIntrinsic>(I)) continue;
|
if (!CS || isa<IntrinsicInst>(I)) continue;
|
||||||
|
|
||||||
// If this call site already existed in the callgraph, just verify it
|
// If this call site already existed in the callgraph, just verify it
|
||||||
// matches up to expectations and remove it from CallSites.
|
// matches up to expectations and remove it from CallSites.
|
||||||
|
|
|
@ -132,18 +132,6 @@ namespace {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replace all the instruction uses of a value with a different value.
|
|
||||||
/// This has the advantage of not screwing up the CallGraph.
|
|
||||||
static void replaceAllInsnUsesWith(Instruction *insn, Value *replacement) {
|
|
||||||
for (Value::use_iterator i = insn->use_begin(), e = insn->use_end();
|
|
||||||
i != e; ) {
|
|
||||||
Use &use = i.getUse();
|
|
||||||
++i;
|
|
||||||
if (isa<Instruction>(use.getUser()))
|
|
||||||
use.set(replacement);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get or create a target for the branch out of rewritten calls to
|
/// Get or create a target for the branch out of rewritten calls to
|
||||||
/// llvm.eh.resume.
|
/// llvm.eh.resume.
|
||||||
BasicBlock *InvokeInliningInfo::getInnerUnwindDest() {
|
BasicBlock *InvokeInliningInfo::getInnerUnwindDest() {
|
||||||
|
@ -196,14 +184,14 @@ BasicBlock *InvokeInliningInfo::getInnerUnwindDest() {
|
||||||
// Create a phi for the exception value...
|
// Create a phi for the exception value...
|
||||||
InnerExceptionPHI = PHINode::Create(exn->getType(), phiCapacity,
|
InnerExceptionPHI = PHINode::Create(exn->getType(), phiCapacity,
|
||||||
"exn.lpad-body", insertPoint);
|
"exn.lpad-body", insertPoint);
|
||||||
replaceAllInsnUsesWith(exn, InnerExceptionPHI);
|
exn->replaceAllUsesWith(InnerExceptionPHI);
|
||||||
selector->setArgOperand(0, exn); // restore this use
|
selector->setArgOperand(0, exn); // restore this use
|
||||||
InnerExceptionPHI->addIncoming(exn, OuterUnwindDest);
|
InnerExceptionPHI->addIncoming(exn, OuterUnwindDest);
|
||||||
|
|
||||||
// ...and the selector.
|
// ...and the selector.
|
||||||
InnerSelectorPHI = PHINode::Create(selector->getType(), phiCapacity,
|
InnerSelectorPHI = PHINode::Create(selector->getType(), phiCapacity,
|
||||||
"selector.lpad-body", insertPoint);
|
"selector.lpad-body", insertPoint);
|
||||||
replaceAllInsnUsesWith(selector, InnerSelectorPHI);
|
selector->replaceAllUsesWith(InnerSelectorPHI);
|
||||||
InnerSelectorPHI->addIncoming(selector, OuterUnwindDest);
|
InnerSelectorPHI->addIncoming(selector, OuterUnwindDest);
|
||||||
|
|
||||||
// All done.
|
// All done.
|
||||||
|
@ -547,15 +535,7 @@ static Value *HandleByValArgument(Value *Arg, Instruction *TheCall,
|
||||||
ConstantInt::get(Type::getInt32Ty(Context), 1),
|
ConstantInt::get(Type::getInt32Ty(Context), 1),
|
||||||
ConstantInt::getFalse(Context) // isVolatile
|
ConstantInt::getFalse(Context) // isVolatile
|
||||||
};
|
};
|
||||||
CallInst *TheMemCpy =
|
CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall);
|
||||||
CallInst::Create(MemCpyFn, CallArgs, CallArgs+5, "", TheCall);
|
|
||||||
|
|
||||||
// If we have a call graph, update it.
|
|
||||||
if (CallGraph *CG = IFI.CG) {
|
|
||||||
CallGraphNode *MemCpyCGN = CG->getOrInsertFunction(MemCpyFn);
|
|
||||||
CallGraphNode *CallerNode = (*CG)[Caller];
|
|
||||||
CallerNode->addCalledFunction(TheMemCpy, MemCpyCGN);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Uses of the argument in the function should use our new alloca
|
// Uses of the argument in the function should use our new alloca
|
||||||
// instead.
|
// instead.
|
||||||
|
@ -767,12 +747,10 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
||||||
if (hasLifetimeMarkers(AI))
|
if (hasLifetimeMarkers(AI))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
CallInst *StartCall = builder.CreateLifetimeStart(AI);
|
builder.CreateLifetimeStart(AI);
|
||||||
if (IFI.CG) CallerNode->addCalledFunction(StartCall, StartCGN);
|
|
||||||
for (unsigned ri = 0, re = Returns.size(); ri != re; ++ri) {
|
for (unsigned ri = 0, re = Returns.size(); ri != re; ++ri) {
|
||||||
IRBuilder<> builder(Returns[ri]);
|
IRBuilder<> builder(Returns[ri]);
|
||||||
CallInst *EndCall = builder.CreateLifetimeEnd(AI);
|
builder.CreateLifetimeEnd(AI);
|
||||||
if (IFI.CG) CallerNode->addCalledFunction(EndCall, EndCGN);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -785,25 +763,14 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
||||||
Function *StackSave = Intrinsic::getDeclaration(M, Intrinsic::stacksave);
|
Function *StackSave = Intrinsic::getDeclaration(M, Intrinsic::stacksave);
|
||||||
Function *StackRestore=Intrinsic::getDeclaration(M,Intrinsic::stackrestore);
|
Function *StackRestore=Intrinsic::getDeclaration(M,Intrinsic::stackrestore);
|
||||||
|
|
||||||
// If we are preserving the callgraph, add edges to the stacksave/restore
|
|
||||||
// functions for the calls we insert.
|
|
||||||
CallGraphNode *StackSaveCGN = 0, *StackRestoreCGN = 0, *CallerNode = 0;
|
|
||||||
if (CallGraph *CG = IFI.CG) {
|
|
||||||
StackSaveCGN = CG->getOrInsertFunction(StackSave);
|
|
||||||
StackRestoreCGN = CG->getOrInsertFunction(StackRestore);
|
|
||||||
CallerNode = (*CG)[Caller];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert the llvm.stacksave.
|
// Insert the llvm.stacksave.
|
||||||
CallInst *SavedPtr = CallInst::Create(StackSave, "savedstack",
|
CallInst *SavedPtr = CallInst::Create(StackSave, "savedstack",
|
||||||
FirstNewBlock->begin());
|
FirstNewBlock->begin());
|
||||||
if (IFI.CG) CallerNode->addCalledFunction(SavedPtr, StackSaveCGN);
|
|
||||||
|
|
||||||
// Insert a call to llvm.stackrestore before any return instructions in the
|
// Insert a call to llvm.stackrestore before any return instructions in the
|
||||||
// inlined function.
|
// inlined function.
|
||||||
for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
|
for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
|
||||||
CallInst *CI = CallInst::Create(StackRestore, SavedPtr, "", Returns[i]);
|
CallInst::Create(StackRestore, SavedPtr, "", Returns[i]);
|
||||||
if (IFI.CG) CallerNode->addCalledFunction(CI, StackRestoreCGN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Count the number of StackRestore calls we insert.
|
// Count the number of StackRestore calls we insert.
|
||||||
|
@ -815,8 +782,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI) {
|
||||||
for (Function::iterator BB = FirstNewBlock, E = Caller->end();
|
for (Function::iterator BB = FirstNewBlock, E = Caller->end();
|
||||||
BB != E; ++BB)
|
BB != E; ++BB)
|
||||||
if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
|
if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
|
||||||
CallInst *CI = CallInst::Create(StackRestore, SavedPtr, "", UI);
|
CallInst::Create(StackRestore, SavedPtr, "", UI);
|
||||||
if (IFI.CG) CallerNode->addCalledFunction(CI, StackRestoreCGN);
|
|
||||||
++NumStackRestores;
|
++NumStackRestores;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue