Index: include/llvm/Analysis/AssumptionCache.h =================================================================== --- include/llvm/Analysis/AssumptionCache.h +++ include/llvm/Analysis/AssumptionCache.h @@ -112,30 +112,38 @@ Scanned = false; } - /// \brief Access the list of assumption handles currently tracked for this + struct NullVHFilter { + bool operator()(const WeakTrackingVH& WTVH) const { + return WTVH; + } + }; + + /// \brief A range of assumptions by value. + using AssumptionRange = + iterator_range>>; + + /// \brief Access the list of assumptions currently tracked for this /// function. - /// - /// Note that these produce weak handles that may be null. The caller must - /// handle that case. - /// FIXME: We should replace this with pointee_iterator> - /// when we can write that to filter out the null values. Then caller code - /// will become simpler. - MutableArrayRef assumptions() { + AssumptionRange assumptions() { if (!Scanned) scanFunction(); - return AssumeHandles; + return make_pointee_range(make_filter_range(AssumeHandles, + NullVHFilter())); } /// \brief Access the list of assumptions which affect this value. - MutableArrayRef assumptionsFor(const Value *V) { + AssumptionRange assumptionsFor(const Value *V) { if (!Scanned) scanFunction(); auto AVI = AffectedValues.find_as(const_cast(V)); if (AVI == AffectedValues.end()) - return MutableArrayRef(); + return make_pointee_range(make_filter_range( + MutableArrayRef(), NullVHFilter())); - return AVI->second; + return make_pointee_range(make_filter_range(AVI->second, + NullVHFilter())); } }; Index: lib/Analysis/AssumptionCache.cpp =================================================================== --- lib/Analysis/AssumptionCache.cpp +++ lib/Analysis/AssumptionCache.cpp @@ -205,9 +205,8 @@ AssumptionCache &AC = AM.getResult(F); OS << "Cached assumptions for function: " << F.getName() << "\n"; - for (auto &VH : AC.assumptions()) - if (VH) - OS << " " << *cast(VH)->getArgOperand(0) << "\n"; + for (auto &V : AC.assumptions()) + OS << " " << *cast(V).getArgOperand(0) << "\n"; return PreservedAnalyses::all(); } @@ -246,9 +245,8 @@ SmallPtrSet AssumptionSet; for (const auto &I : AssumptionCaches) { - for (auto &VH : I.second->assumptions()) - if (VH) - AssumptionSet.insert(cast(VH)); + for (auto &V : I.second->assumptions()) + AssumptionSet.insert(cast(&V)); for (const BasicBlock &B : cast(*I.first)) for (const Instruction &II : B) Index: lib/Analysis/CodeMetrics.cpp =================================================================== --- lib/Analysis/CodeMetrics.cpp +++ lib/Analysis/CodeMetrics.cpp @@ -76,10 +76,8 @@ SmallPtrSet Visited; SmallVector Worklist; - for (auto &AssumeVH : AC->assumptions()) { - if (!AssumeVH) - continue; - Instruction *I = cast(AssumeVH); + for (auto &AssumeV : AC->assumptions()) { + Instruction *I = cast(&AssumeV); // Filter out call sites outside of the loop so we don't do a function's // worth of work for each of its loops (and, in the common case, ephemeral @@ -100,10 +98,8 @@ SmallPtrSet Visited; SmallVector Worklist; - for (auto &AssumeVH : AC->assumptions()) { - if (!AssumeVH) - continue; - Instruction *I = cast(AssumeVH); + for (auto &AssumeV : AC->assumptions()) { + Instruction *I = cast(&AssumeV); assert(I->getParent()->getParent() == F && "Found assumption for the wrong function!"); Index: lib/Analysis/LazyValueInfo.cpp =================================================================== --- lib/Analysis/LazyValueInfo.cpp +++ lib/Analysis/LazyValueInfo.cpp @@ -1022,10 +1022,8 @@ if (!BBI) return; - for (auto &AssumeVH : AC->assumptionsFor(Val)) { - if (!AssumeVH) - continue; - auto *I = cast(AssumeVH); + for (auto &AssumeV : AC->assumptionsFor(Val)) { + auto *I = cast(&AssumeV); if (!isValidAssumeForContext(I, BBI, DT)) continue; Index: lib/Analysis/ScalarEvolution.cpp =================================================================== --- lib/Analysis/ScalarEvolution.cpp +++ lib/Analysis/ScalarEvolution.cpp @@ -1653,8 +1653,9 @@ // these to compute max backedge taken counts, but can still use // these to prove lack of overflow. Use this fact to avoid // doing extra work that may not pay off. + auto assumptions = AC.assumptions(); if (!isa(MaxBECount) || HasGuards || - !AC.assumptions().empty()) { + assumptions.begin() != assumptions.end()) { // If the backedge is guarded by a comparison with the pre-inc // value the addrec is safe. Also, if the entry is guarded by // a comparison with the start value and the backedge is @@ -1912,9 +1913,9 @@ // these to compute max backedge taken counts, but can still use // these to prove lack of overflow. Use this fact to avoid // doing extra work that may not pay off. - + auto assumptions = AC.assumptions(); if (!isa(MaxBECount) || HasGuards || - !AC.assumptions().empty()) { + assumptions.begin() != assumptions.end()) { // If the backedge is guarded by a comparison with the pre-inc // value the addrec is safe. Also, if the entry is guarded by // a comparison with the start value and the backedge is @@ -8182,10 +8183,8 @@ } // Check conditions due to any @llvm.assume intrinsics. - for (auto &AssumeVH : AC.assumptions()) { - if (!AssumeVH) - continue; - auto *CI = cast(AssumeVH); + for (auto &AssumeV : AC.assumptions()) { + auto *CI = cast(&AssumeV); if (!DT.dominates(CI, Latch->getTerminator())) continue; @@ -8276,10 +8275,8 @@ } // Check conditions due to any @llvm.assume intrinsics. - for (auto &AssumeVH : AC.assumptions()) { - if (!AssumeVH) - continue; - auto *CI = cast(AssumeVH); + for (auto &AssumeV : AC.assumptions()) { + auto *CI = cast(&AssumeV); if (!DT.dominates(CI, L->getHeader())) continue; Index: lib/Analysis/ValueTracking.cpp =================================================================== --- lib/Analysis/ValueTracking.cpp +++ lib/Analysis/ValueTracking.cpp @@ -514,10 +514,8 @@ // Note that the patterns below need to be kept in sync with the code // in AssumptionCache::updateAffectedValues. - for (auto &AssumeVH : Q.AC->assumptionsFor(V)) { - if (!AssumeVH) - continue; - CallInst *I = cast(AssumeVH); + for (auto &AssumeV : Q.AC->assumptionsFor(V)) { + CallInst *I = cast(&AssumeV); assert(I->getParent()->getParent() == Q.CxtI->getParent()->getParent() && "Got assumption for the wrong function!"); if (Q.isExcluded(I)) Index: lib/Transforms/InstCombine/InstCombineSelect.cpp =================================================================== --- lib/Transforms/InstCombine/InstCombineSelect.cpp +++ lib/Transforms/InstCombine/InstCombineSelect.cpp @@ -1475,7 +1475,9 @@ // putting this fold here with limitations rather than in InstSimplify. // The motivation for this call into value tracking is to take advantage of // the assumption cache, so make sure that is populated. - if (!CondVal->getType()->isVectorTy() && !AC.assumptions().empty()) { + auto assumptions = AC.assumptions(); + if (!CondVal->getType()->isVectorTy() && + assumptions.begin() != assumptions.end()) { KnownBits Known(1); computeKnownBits(CondVal, Known, 0, &SI); if (Known.One == 1) Index: lib/Transforms/Scalar/AlignmentFromAssumptions.cpp =================================================================== --- lib/Transforms/Scalar/AlignmentFromAssumptions.cpp +++ lib/Transforms/Scalar/AlignmentFromAssumptions.cpp @@ -425,9 +425,8 @@ NewSrcAlignments.clear(); bool Changed = false; - for (auto &AssumeVH : AC.assumptions()) - if (AssumeVH) - Changed |= processAssumption(cast(AssumeVH)); + for (auto &AssumeV : AC.assumptions()) + Changed |= processAssumption(cast(&AssumeV)); return Changed; } Index: lib/Transforms/Utils/PredicateInfo.cpp =================================================================== --- lib/Transforms/Utils/PredicateInfo.cpp +++ lib/Transforms/Utils/PredicateInfo.cpp @@ -465,8 +465,8 @@ processSwitch(SI, BranchBB, OpsToRename); } } - for (auto &Assume : AC.assumptions()) { - if (auto *II = dyn_cast_or_null(Assume)) + for (auto &AssumeV : AC.assumptions()) { + if (auto *II = dyn_cast(&AssumeV)) processAssume(II, II->getParent(), OpsToRename); } // Now rename all our operations.