diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 154dce32176..7fc3108153e 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -3026,6 +3026,12 @@ public: addAttribute(AttributeSet::FunctionIndex, Attribute::NoUnwind); } + /// \brief Determine if the invoke cannot be duplicated. + bool cannotDuplicate() const {return hasFnAttr(Attribute::NoDuplicate); } + void setCannotDuplicate() { + addAttribute(AttributeSet::FunctionIndex, Attribute::NoDuplicate); + } + /// \brief Determine if the call returns a structure through first /// pointer argument. bool hasStructRetAttr() const { diff --git a/lib/Analysis/CodeMetrics.cpp b/lib/Analysis/CodeMetrics.cpp index 4a05888170a..4c8a093684f 100644 --- a/lib/Analysis/CodeMetrics.cpp +++ b/lib/Analysis/CodeMetrics.cpp @@ -65,11 +65,11 @@ void CodeMetrics::analyzeBasicBlock(const BasicBlock *BB, ++NumVectorInsts; if (const CallInst *CI = dyn_cast(II)) - if (CI->hasFnAttr(Attribute::NoDuplicate)) + if (CI->cannotDuplicate()) notDuplicatable = true; if (const InvokeInst *InvI = dyn_cast(II)) - if (InvI->hasFnAttr(Attribute::NoDuplicate)) + if (InvI->cannotDuplicate()) notDuplicatable = true; NumInsts += TTI.getUserCost(&*II); diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp index d4ef2247e2a..8dafc1c1c61 100644 --- a/lib/Analysis/IPA/InlineCost.cpp +++ b/lib/Analysis/IPA/InlineCost.cpp @@ -723,7 +723,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) { return false; } if (CS.isCall() && - cast(CS.getInstruction())->hasFnAttr(Attribute::NoDuplicate)) + cast(CS.getInstruction())->cannotDuplicate()) ContainsNoDuplicateCall = true; if (Function *F = CS.getCalledFunction()) { diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp index d4e7b54f224..b38672ec394 100644 --- a/lib/Analysis/LoopInfo.cpp +++ b/lib/Analysis/LoopInfo.cpp @@ -218,12 +218,12 @@ bool Loop::isSafeToClone() const { return false; if (const InvokeInst *II = dyn_cast((*I)->getTerminator())) - if (II->hasFnAttr(Attribute::NoDuplicate)) + if (II->cannotDuplicate()) return false; for (BasicBlock::iterator BI = (*I)->begin(), BE = (*I)->end(); BI != BE; ++BI) { if (const CallInst *CI = dyn_cast(BI)) { - if (CI->hasFnAttr(Attribute::NoDuplicate)) + if (CI->cannotDuplicate()) return false; } } diff --git a/lib/Transforms/Scalar/JumpThreading.cpp b/lib/Transforms/Scalar/JumpThreading.cpp index dcb4a954fc9..067deb7d78d 100644 --- a/lib/Transforms/Scalar/JumpThreading.cpp +++ b/lib/Transforms/Scalar/JumpThreading.cpp @@ -255,7 +255,7 @@ static unsigned getJumpThreadDuplicationCost(const BasicBlock *BB, // as having cost of 2 total, and if they are a vector intrinsic, we model // them as having cost 1. if (const CallInst *CI = dyn_cast(I)) { - if (CI->hasFnAttr(Attribute::NoDuplicate)) + if (CI->cannotDuplicate()) // Blocks with NoDuplicate are modelled as having infinite cost, so they // are never duplicated. return ~0U;