@@ -130,6 +130,24 @@ bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes(
130130 return true ;
131131}
132132
133+ // / Return true if we do not know how to (mechanically) hoist or sink \p R out
134+ // / of a loop region.
135+ static bool cannotHoistOrSinkRecipe (const VPRecipeBase &R) {
136+ // Assumes don't alias anything or throw; as long as they're guaranteed to
137+ // execute, they're safe to hoist.
138+ if (match (&R, m_Intrinsic<Intrinsic::assume>()))
139+ return false ;
140+
141+ // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
142+ // memory location is not modified in the vector loop.
143+ if (R.mayHaveSideEffects () || R.mayReadFromMemory () || R.isPhi ())
144+ return true ;
145+
146+ // Allocas cannot be hoisted.
147+ auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
148+ return RepR && RepR->getOpcode () == Instruction::Alloca;
149+ }
150+
133151static bool sinkScalarOperands (VPlan &Plan) {
134152 auto Iter = vp_depth_first_deep (Plan.getEntry ());
135153 bool Changed = false ;
@@ -1789,7 +1807,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
17891807 VPDT.properlyDominates (Previous, SinkCandidate))
17901808 return true ;
17911809
1792- if (SinkCandidate-> mayHaveSideEffects ( ))
1810+ if (cannotHoistOrSinkRecipe (*SinkCandidate ))
17931811 return false ;
17941812
17951813 WorkList.push_back (SinkCandidate);
@@ -1829,7 +1847,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
18291847static bool hoistPreviousBeforeFORUsers (VPFirstOrderRecurrencePHIRecipe *FOR,
18301848 VPRecipeBase *Previous,
18311849 VPDominatorTree &VPDT) {
1832- if (Previous-> mayHaveSideEffects () || Previous-> mayReadFromMemory ( ))
1850+ if (cannotHoistOrSinkRecipe (* Previous))
18331851 return false ;
18341852
18351853 // Collect recipes that need hoisting.
@@ -1876,11 +1894,6 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18761894 return nullptr ;
18771895 return HoistCandidate;
18781896 };
1879- auto CanHoist = [&](VPRecipeBase *HoistCandidate) {
1880- // Avoid hoisting candidates with side-effects, as we do not yet analyze
1881- // associated dependencies.
1882- return !HoistCandidate->mayHaveSideEffects ();
1883- };
18841897
18851898 if (!NeedsHoisting (Previous->getVPSingleValue ()))
18861899 return true ;
@@ -1892,7 +1905,7 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18921905 VPRecipeBase *Current = HoistCandidates[I];
18931906 assert (Current->getNumDefinedValues () == 1 &&
18941907 " only recipes with a single defined value expected" );
1895- if (! CanHoist ( Current))
1908+ if (cannotHoistOrSinkRecipe (* Current))
18961909 return false ;
18971910
18981911 for (VPValue *Op : Current->operands ()) {
@@ -2121,24 +2134,6 @@ void VPlanTransforms::cse(VPlan &Plan) {
21212134static void licm (VPlan &Plan) {
21222135 VPBasicBlock *Preheader = Plan.getVectorPreheader ();
21232136
2124- // Return true if we do not know how to (mechanically) hoist a given recipe
2125- // out of a loop region.
2126- auto CannotHoistRecipe = [](VPRecipeBase &R) {
2127- // Assumes don't alias anything or throw; as long as they're guaranteed to
2128- // execute, they're safe to hoist.
2129- if (match (&R, m_Intrinsic<Intrinsic::assume>()))
2130- return false ;
2131-
2132- // TODO: Relax checks in the future, e.g. we could also hoist reads, if
2133- // their memory location is not modified in the vector loop.
2134- if (R.mayHaveSideEffects () || R.mayReadFromMemory () || R.isPhi ())
2135- return true ;
2136-
2137- // Allocas cannot be hoisted.
2138- auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
2139- return RepR && RepR->getOpcode () == Instruction::Alloca;
2140- };
2141-
21422137 // Hoist any loop invariant recipes from the vector loop region to the
21432138 // preheader. Preform a shallow traversal of the vector loop region, to
21442139 // exclude recipes in replicate regions. Since the top-level blocks in the
@@ -2150,7 +2145,7 @@ static void licm(VPlan &Plan) {
21502145 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
21512146 vp_depth_first_shallow (LoopRegion->getEntry ()))) {
21522147 for (VPRecipeBase &R : make_early_inc_range (*VPBB)) {
2153- if (CannotHoistRecipe (R))
2148+ if (cannotHoistOrSinkRecipe (R))
21542149 continue ;
21552150 if (any_of (R.operands (), [](VPValue *Op) {
21562151 return !Op->isDefinedOutsideLoopRegions ();
0 commit comments