Index: llvm/trunk/include/llvm/Transforms/IPO/Attributor.h =================================================================== --- llvm/trunk/include/llvm/Transforms/IPO/Attributor.h +++ llvm/trunk/include/llvm/Transforms/IPO/Attributor.h @@ -104,6 +104,7 @@ struct AbstractAttribute; struct InformationCache; +struct AAIsDead; class Function; @@ -652,6 +653,11 @@ void identifyDefaultAbstractAttributes( Function &F, DenseSet *Whitelist = nullptr); + /// Return true if \p AA (or its context instruction) is assumed dead. + /// + /// If \p LivenessAA is not provided it is queried. + bool isAssumedDead(const AbstractAttribute &AA, const AAIsDead *LivenessAA); + /// Check \p Pred on all function call sites. /// /// This method will evaluate \p Pred on call sites and return Index: llvm/trunk/lib/Transforms/IPO/Attributor.cpp =================================================================== --- llvm/trunk/lib/Transforms/IPO/Attributor.cpp +++ llvm/trunk/lib/Transforms/IPO/Attributor.cpp @@ -1076,7 +1076,6 @@ std::function &)> Pred = [&](Value &RV, const SmallPtrSetImpl &RetInsts) -> bool { - if (isKnownNonZero(&RV, A.getDataLayout())) return true; @@ -2143,6 +2142,23 @@ /// Attributor /// ---------------------------------------------------------------------------- +bool Attributor::isAssumedDead(const AbstractAttribute &AA, + const AAIsDead *LivenessAA) { + const Instruction *CtxI = AA.getIRPosition().getCtxI(); + if (!CtxI) + return false; + + if (!LivenessAA) + LivenessAA = + getAAFor(AA, IRPosition::function(*CtxI->getFunction())); + if (!LivenessAA || !LivenessAA->isAssumedDead(CtxI)) + return false; + + // TODO: Do not track dependences automatically but add it here as only a + // "is-assumed-dead" result causes a dependence. + return true; +} + bool Attributor::checkForAllCallSites(const function_ref &Pred, const AbstractAttribute &QueryingAA, bool RequireAllCallSites) { @@ -2354,8 +2370,9 @@ // Update all abstract attribute in the work list and record the ones that // changed. for (AbstractAttribute *AA : Worklist) - if (AA->update(*this) == ChangeStatus::CHANGED) - ChangedAAs.push_back(AA); + if (!isAssumedDead(*AA, nullptr)) + if (AA->update(*this) == ChangeStatus::CHANGED) + ChangedAAs.push_back(AA); // Reset the work list and repopulate with the changed abstract attributes. // Note that dependent ones are added above. @@ -2415,6 +2432,9 @@ if (!State.isValidState()) continue; + // Skip dead code. + if (isAssumedDead(*AA, nullptr)) + continue; // Manifest the state and record if we changed the IR. ChangeStatus LocalChange = AA->manifest(*this); if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())