Author: baldrick Date: Thu Nov 22 16:24:59 2007 New Revision: 44280 URL: http://llvm.org/viewvc/llvm-project?rev=44280&view=rev Log: Turn invokes of nounwind functions into ordinary calls.
Added: llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Modified: llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp?rev=44280&r1=44279&r2=44280&view=diff ============================================================================== --- llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp (original) +++ llvm/trunk/lib/Transforms/Scalar/SimplifyCFG.cpp Thu Nov 22 16:24:59 2007 @@ -71,6 +71,28 @@ } } +/// ChangeToCall - Convert the specified invoke into a normal call. +static void ChangeToCall(InvokeInst *II) { + BasicBlock *BB = II->getParent(); + SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end()); + CallInst *NewCall = new CallInst(II->getCalledValue(), Args.begin(), + Args.end(), "", II); + NewCall->takeName(II); + NewCall->setCallingConv(II->getCallingConv()); + NewCall->setParamAttrs(II->getParamAttrs()); + II->replaceAllUsesWith(NewCall); + + // Follow the call by a branch to the normal destination. + new BranchInst(II->getNormalDest(), II); + + // Update PHI nodes in the unwind destination + II->getUnwindDest()->removePredecessor(BB); + BB->getInstList().erase(II); + + if (NewCall->use_empty()) + BB->getInstList().erase(NewCall); +} + /// IsNoReturn - Return true if the specified call is to a no-return function. static bool IsNoReturn(const CallInst *CI) { if (const ParamAttrsList *Attrs = CI->getParamAttrs()) @@ -90,6 +112,25 @@ return false; } +/// IsNoUnwind - Return true if the specified invoke is to a no-unwind function. +static bool IsNoUnwind(const InvokeInst *II) { + if (const ParamAttrsList *Attrs = II->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + + if (const Function *Callee = II->getCalledFunction()) { + if (const ParamAttrsList *Attrs = Callee->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + + const FunctionType *FT = Callee->getFunctionType(); + if (const ParamAttrsList *Attrs = FT->getParamAttrs()) + if (Attrs->paramHasAttr(0, ParamAttr::NoUnwind)) + return true; + } + return false; +} + static bool MarkAliveBlocks(BasicBlock *BB, SmallPtrSet<BasicBlock*, 128> &Reachable) { @@ -106,7 +147,7 @@ // Do a quick scan of the basic block, turning any obviously unreachable // instructions into LLVM unreachable insts. The instruction combining pass - // canonnicalizes unreachable insts into stores to null or undef. + // canonicalizes unreachable insts into stores to null or undef. for (BasicBlock::iterator BBI = BB->begin(), E = BB->end(); BBI != E;++BBI){ if (CallInst *CI = dyn_cast<CallInst>(BBI)) { if (IsNoReturn(CI)) { @@ -131,6 +172,13 @@ } } + // Turn invokes that call 'nounwind' functions into ordinary calls. + if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator())) + if (IsNoUnwind(II)) { + ChangeToCall(II); + Changed = true; + } + Changed |= ConstantFoldTerminator(BB); for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI) Worklist.push_back(*SI); Added: llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll?rev=44280&view=auto ============================================================================== --- llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll (added) +++ llvm/trunk/test/Transforms/SimplifyCFG/2007-11-22-InvokeNoUnwind.ll Thu Nov 22 16:24:59 2007 @@ -0,0 +1,14 @@ +; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | not grep invoke + +declare i32 @func(i8*) nounwind + +define i32 @test() { + invoke i32 @func( i8* null ) nounwind + to label %Cont unwind label %Other ; <i32>:1 [#uses=0] + +Cont: ; preds = %0 + ret i32 0 + +Other: ; preds = %0 + ret i32 1 +} _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits