@@ -776,13 +776,12 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
776776static bool hoistPreviousBeforeFORUsers (VPFirstOrderRecurrencePHIRecipe *FOR,
777777 VPRecipeBase *Previous,
778778 VPDominatorTree &VPDT) {
779- using namespace llvm ::VPlanPatternMatch;
780779 if (Previous->mayHaveSideEffects () || Previous->mayReadFromMemory ())
781780 return false ;
782781
783782 // Collect recipes that need hoisting.
784783 SmallVector<VPRecipeBase *> HoistCandidates;
785- SmallPtrSet<VPRecipeBase *, 8 > Seen ;
784+ SmallPtrSet<VPRecipeBase *, 8 > Visited ;
786785 VPRecipeBase *HoistPoint = nullptr ;
787786 // Find the closest hoist point by looking at all users of FOR and selecting
788787 // the recipe dominating all other users.
@@ -793,24 +792,31 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
793792 if (!HoistPoint || VPDT.properlyDominates (R, HoistPoint))
794793 HoistPoint = R;
795794 }
795+ assert (all_of (FOR->users (),
796+ [&VPDT, HoistPoint](VPUser *U) {
797+ auto *R = dyn_cast<VPRecipeBase>(U);
798+ return !R || HoistPoint == R ||
799+ VPDT.properlyDominates (HoistPoint, R);
800+ }) &&
801+ " HoistPoint must dominate all users of FOR" );
796802
797803 auto NeedsHoisting = [HoistPoint, &VPDT,
798- &Seen ](VPValue *HoistCandidateV) -> VPRecipeBase * {
804+ &Visited ](VPValue *HoistCandidateV) -> VPRecipeBase * {
799805 VPRecipeBase *HoistCandidate = HoistCandidateV->getDefiningRecipe ();
800806 if (!HoistCandidate)
801807 return nullptr ;
808+ VPRegionBlock *EnclosingLoopRegion =
809+ HoistCandidate->getParent ()->getEnclosingLoopRegion ();
802810 assert ((!HoistCandidate->getParent ()->getParent () ||
803- HoistCandidate->getParent ()->getParent () ==
804- HoistCandidate->getParent ()->getEnclosingLoopRegion ()) &&
805- " CFG in VPlan should still be flattened, without replicate regions" );
806- // Hoist candidate has already beend visited, no need to hoist.
807- if (!Seen.insert (HoistCandidate).second )
811+ HoistCandidate->getParent ()->getParent () == EnclosingLoopRegion) &&
812+ " CFG in VPlan should still be flat, without replicate regions" );
813+ // Hoist candidate was already visited, no need to hoist.
814+ if (!Visited.insert (HoistCandidate).second )
808815 return nullptr ;
809816
810817 // Candidate is outside loop region or a header phi, dominates FOR users w/o
811818 // hoisting.
812- if (!HoistCandidate->getParent ()->getEnclosingLoopRegion () ||
813- isa<VPHeaderPHIRecipe>(HoistCandidate))
819+ if (!EnclosingLoopRegion || isa<VPHeaderPHIRecipe>(HoistCandidate))
814820 return nullptr ;
815821
816822 // If we reached a recipe that dominates HoistPoint, we don't need to
@@ -825,9 +831,11 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
825831 return !HoistCandidate->mayHaveSideEffects ();
826832 };
827833
834+ if (!NeedsHoisting (Previous->getVPSingleValue ()))
835+ return true ;
836+
828837 // Recursively try to hoist Previous and its operands before all users of FOR.
829- if (NeedsHoisting (Previous->getVPSingleValue ()))
830- HoistCandidates.push_back (Previous);
838+ HoistCandidates.push_back (Previous);
831839
832840 for (unsigned I = 0 ; I != HoistCandidates.size (); ++I) {
833841 VPRecipeBase *Current = HoistCandidates[I];
@@ -849,8 +857,8 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
849857 }
850858 }
851859
852- // Keep recipes to hoist ordered by dominance so earlier instructions are
853- // processed first.
860+ // Order recipes to hoist by dominance so earlier instructions are processed
861+ // first.
854862 sort (HoistCandidates, [&VPDT](const VPRecipeBase *A, const VPRecipeBase *B) {
855863 return VPDT.properlyDominates (A, B);
856864 });
0 commit comments