diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -735,33 +735,21 @@ LLVM_DEBUG(dbgs() << "New: " << *AutoreleaseRV << "\n"); } -namespace { -Instruction * -CloneCallInstForBB(CallInst &CI, BasicBlock &BB, - const DenseMap &BlockColors) { - SmallVector OpBundles; - for (unsigned I = 0, E = CI.getNumOperandBundles(); I != E; ++I) { - auto Bundle = CI.getOperandBundleAt(I); - // Funclets will be reassociated in the future. - if (Bundle.getTagID() == LLVMContext::OB_funclet) - continue; - OpBundles.emplace_back(Bundle); - } - - if (!BlockColors.empty()) { - const ColorVector &CV = BlockColors.find(&BB)->second; - assert(CV.size() == 1 && "non-unique color for block!"); - Instruction *EHPad = CV.front()->getFirstNonPHI(); - if (EHPad->isEHPad()) - OpBundles.emplace_back("funclet", EHPad); +template +static void cloneOpBundlesIf(CallBase *CI, + SmallVectorImpl &OpBundles, + PredicateT Predicate) { + for (unsigned I = 0, E = CI->getNumOperandBundles(); I != E; ++I) { + OperandBundleUse B = CI->getOperandBundleAt(I); + if (Predicate(B)) + OpBundles.emplace_back(B); } - - return CallInst::Create(&CI, OpBundles); } -void addOpBundleForFunclet(BasicBlock *BB, - const DenseMap &BlockColors, - SmallVectorImpl &OpBundles) { +static void +addOpBundleForFunclet(BasicBlock *BB, + const DenseMap &BlockColors, + SmallVectorImpl &OpBundles) { if (!BlockColors.empty()) { const ColorVector &CV = BlockColors.find(BB)->second; assert(CV.size() == 1 && "non-unique color for block!"); @@ -770,7 +758,6 @@ OpBundles.emplace_back("funclet", EHPad); } } -} /// Visit each call, one at a time, and make simplifications without doing any /// additional analysis. @@ -1164,8 +1151,12 @@ continue; Value *Op = PN->getIncomingValue(i); Instruction *InsertPos = &PN->getIncomingBlock(i)->back(); - CallInst *Clone = cast( - CloneCallInstForBB(*CInst, *InsertPos->getParent(), BlockColors)); + SmallVector OpBundles; + cloneOpBundlesIf(CInst, OpBundles, [](const OperandBundleUse &B) { + return B.getTagID() != LLVMContext::OB_funclet; + }); + addOpBundleForFunclet(InsertPos->getParent(), BlockColors, OpBundles); + CallInst *Clone = CallInst::Create(CInst, OpBundles); if (Op->getType() != ParamTy) Op = new BitCastInst(Op, ParamTy, "", InsertPos); Clone->setArgOperand(0, Op); diff --git a/llvm/test/Transforms/ObjCARC/funclet.ll b/llvm/test/Transforms/ObjCARC/funclet-cleanuppad.ll rename from llvm/test/Transforms/ObjCARC/funclet.ll rename to llvm/test/Transforms/ObjCARC/funclet-cleanuppad.ll