X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FIPO%2FPruneEH.cpp;h=c2f55d896ba783cd4f160f3019b9ea5950fc6de0;hp=c9c0b197eae666377a3eca5d9745bf9e83ea95b9;hb=9f25a0678ed9f06088a09649a040a6bef362e6af;hpb=9c609eaad830ef4d94c43ca50e41b766dddcd8d7 diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp index c9c0b197eae..c2f55d896ba 100644 --- a/lib/Transforms/IPO/PruneEH.cpp +++ b/lib/Transforms/IPO/PruneEH.cpp @@ -29,6 +29,7 @@ #include "llvm/IR/Instructions.h" #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/Transforms/Utils/Local.h" #include using namespace llvm; @@ -153,21 +154,16 @@ bool PruneEH::runOnSCC(CallGraphSCC &SCC) { // If the SCC doesn't unwind or doesn't throw, note this fact. if (!SCCMightUnwind || !SCCMightReturn) for (CallGraphSCC::iterator I = SCC.begin(), E = SCC.end(); I != E; ++I) { - AttrBuilder NewAttributes; - - if (!SCCMightUnwind) - NewAttributes.addAttribute(Attribute::NoUnwind); - if (!SCCMightReturn) - NewAttributes.addAttribute(Attribute::NoReturn); - Function *F = (*I)->getFunction(); - const AttributeSet &PAL = F->getAttributes().getFnAttributes(); - const AttributeSet &NPAL = AttributeSet::get( - F->getContext(), AttributeSet::FunctionIndex, NewAttributes); - if (PAL != NPAL) { + if (!SCCMightUnwind && !F->hasFnAttribute(Attribute::NoUnwind)) { + F->addFnAttr(Attribute::NoUnwind); + MadeChange = true; + } + + if (!SCCMightReturn && !F->hasFnAttribute(Attribute::NoReturn)) { + F->addFnAttr(Attribute::NoReturn); MadeChange = true; - F->addAttributes(AttributeSet::FunctionIndex, NPAL); } } @@ -191,33 +187,8 @@ bool PruneEH::SimplifyFunction(Function *F) { for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) { if (InvokeInst *II = dyn_cast(BB->getTerminator())) if (II->doesNotThrow() && canSimplifyInvokeNoUnwind(F)) { - CallSite CS(II); - SmallVector Args(CS.arg_begin(), CS.arg_end()); - SmallVector OpBundles; - II->getOperandBundlesAsDefs(OpBundles); - - // Insert a call instruction before the invoke. - CallInst *Call = CallInst::Create(II->getCalledValue(), Args, OpBundles, - "", II); - Call->takeName(II); - Call->setCallingConv(II->getCallingConv()); - Call->setAttributes(II->getAttributes()); - Call->setDebugLoc(II->getDebugLoc()); - - // Anything that used the value produced by the invoke instruction - // now uses the value produced by the call instruction. Note that we - // do this even for void functions and calls with no uses so that the - // callgraph edge is updated. - II->replaceAllUsesWith(Call); BasicBlock *UnwindBlock = II->getUnwindDest(); - UnwindBlock->removePredecessor(II->getParent()); - - // Insert a branch to the normal destination right before the - // invoke. - BranchInst::Create(II->getNormalDest(), II); - - // Finally, delete the invoke instruction! - BB->getInstList().pop_back(); + removeUnwindEdge(&*BB); // If the unwind block is now dead, nuke it. if (pred_empty(UnwindBlock)) @@ -257,23 +228,38 @@ void PruneEH::DeleteBasicBlock(BasicBlock *BB) { assert(pred_empty(BB) && "BB is not dead!"); CallGraph &CG = getAnalysis().getCallGraph(); + Instruction *TokenInst = nullptr; + CallGraphNode *CGN = CG[BB->getParent()]; for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) { --I; - if (CallInst *CI = dyn_cast(I)) { - if (!isa(I)) - CGN->removeCallEdgeFor(CI); - } else if (InvokeInst *II = dyn_cast(I)) - CGN->removeCallEdgeFor(II); + + if (I->getType()->isTokenTy()) { + TokenInst = &*I; + break; + } + + if (auto CS = CallSite (&*I)) { + const Function *Callee = CS.getCalledFunction(); + if (!Callee || !Intrinsic::isLeaf(Callee->getIntrinsicID())) + CGN->removeCallEdgeFor(CS); + else if (!Callee->isIntrinsic()) + CGN->removeCallEdgeFor(CS); + } + if (!I->use_empty()) I->replaceAllUsesWith(UndefValue::get(I->getType())); } - // Get the list of successors of this block. - std::vector Succs(succ_begin(BB), succ_end(BB)); + if (TokenInst) { + changeToUnreachable(TokenInst->getNextNode(), /*UseLLVMTrap=*/false); + } else { + // Get the list of successors of this block. + std::vector Succs(succ_begin(BB), succ_end(BB)); - for (unsigned i = 0, e = Succs.size(); i != e; ++i) - Succs[i]->removePredecessor(BB); + for (unsigned i = 0, e = Succs.size(); i != e; ++i) + Succs[i]->removePredecessor(BB); - BB->eraseFromParent(); + BB->eraseFromParent(); + } }