diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp --- a/llvm/lib/Transforms/IPO/Attributor.cpp +++ b/llvm/lib/Transforms/IPO/Attributor.cpp @@ -1539,62 +1539,39 @@ /// See Abstract Attribute::updateImpl(...). ChangeStatus updateImpl(Attributor &A) override { const IRPosition &IRP = getIRPosition(); - Function *F = IRP.getAnchorScope(); - - const AAIsDead &LivenessAA = - A.getAAFor(*this, IRPosition::function(*F)); const auto &NoFreeAA = A.getAAFor(*this, IRPosition::function_scope(IRP)); if (NoFreeAA.isAssumedNoFree()) return ChangeStatus::UNCHANGED; - SmallPtrSet Visited; - SmallVector Worklist; - Value &AssociatedValue = getIRPosition().getAssociatedValue(); - for (Use &U : AssociatedValue.uses()) - Worklist.push_back(&U); - - while (!Worklist.empty()) { - const Use *U = Worklist.pop_back_val(); - if (!Visited.insert(U).second) - continue; - - auto *UserI = U->getUser(); - if (!UserI) - continue; - - if (LivenessAA.isAssumedDead(cast(UserI))) - continue; - + auto Pred = [&](const Use &U, bool &Follow) -> bool { + Instruction *UserI = cast(U.getUser()); if (auto *CB = dyn_cast(UserI)) { - if (CB->isBundleOperand(U)) - return indicatePessimisticFixpoint(); - if (!CB->isArgOperand(U)) - continue; - - unsigned ArgNo = CB->getArgOperandNo(U); + if (CB->isBundleOperand(&U)) + return false; + if (!CB->isArgOperand(&U)) + return true; + unsigned ArgNo = CB->getArgOperandNo(&U); const auto &NoFreeArg = A.getAAFor( *this, IRPosition::callsite_argument(*CB, ArgNo)); - - if (NoFreeArg.isAssumedNoFree()) - continue; - - return indicatePessimisticFixpoint(); + return NoFreeArg.isAssumedNoFree(); } if (isa(UserI) || isa(UserI) || isa(UserI) || isa(UserI)) { - for (Use &U : UserI->uses()) - Worklist.push_back(&U); - continue; - } + Follow = true; + return true; + }; // Unknown user. + return false; + }; + if (!A.checkForAllUses(Pred, *this, AssociatedValue)) return indicatePessimisticFixpoint(); - } + return ChangeStatus::UNCHANGED; } };