@@ -131,6 +131,24 @@ bool VPlanTransforms::tryToConvertVPInstructionsToVPRecipes(
131131 return true ;
132132}
133133
134+ // / Return true if we do not know how to (mechanically) hoist or sink \p R out
135+ // / of a loop region.
136+ static bool cannotHoistOrSinkRecipe (const VPRecipeBase &R) {
137+ // Assumes don't alias anything or throw; as long as they're guaranteed to
138+ // execute, they're safe to hoist.
139+ if (match (&R, m_Intrinsic<Intrinsic::assume>()))
140+ return false ;
141+
142+ // TODO: Relax checks in the future, e.g. we could also hoist reads, if their
143+ // memory location is not modified in the vector loop.
144+ if (R.mayHaveSideEffects () || R.mayReadFromMemory () || R.isPhi ())
145+ return true ;
146+
147+ // Allocas cannot be hoisted.
148+ auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
149+ return RepR && RepR->getOpcode () == Instruction::Alloca;
150+ }
151+
134152static bool sinkScalarOperands (VPlan &Plan) {
135153 auto Iter = vp_depth_first_deep (Plan.getEntry ());
136154 bool Changed = false ;
@@ -1826,7 +1844,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
18261844 VPDT.properlyDominates (Previous, SinkCandidate))
18271845 return true ;
18281846
1829- if (SinkCandidate-> mayHaveSideEffects ( ))
1847+ if (cannotHoistOrSinkRecipe (*SinkCandidate ))
18301848 return false ;
18311849
18321850 WorkList.push_back (SinkCandidate);
@@ -1866,7 +1884,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
18661884static bool hoistPreviousBeforeFORUsers (VPFirstOrderRecurrencePHIRecipe *FOR,
18671885 VPRecipeBase *Previous,
18681886 VPDominatorTree &VPDT) {
1869- if (Previous-> mayHaveSideEffects () || Previous-> mayReadFromMemory ( ))
1887+ if (cannotHoistOrSinkRecipe (* Previous))
18701888 return false ;
18711889
18721890 // Collect recipes that need hoisting.
@@ -1913,11 +1931,6 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
19131931 return nullptr ;
19141932 return HoistCandidate;
19151933 };
1916- auto CanHoist = [&](VPRecipeBase *HoistCandidate) {
1917- // Avoid hoisting candidates with side-effects, as we do not yet analyze
1918- // associated dependencies.
1919- return !HoistCandidate->mayHaveSideEffects ();
1920- };
19211934
19221935 if (!NeedsHoisting (Previous->getVPSingleValue ()))
19231936 return true ;
@@ -1929,7 +1942,7 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
19291942 VPRecipeBase *Current = HoistCandidates[I];
19301943 assert (Current->getNumDefinedValues () == 1 &&
19311944 " only recipes with a single defined value expected" );
1932- if (! CanHoist ( Current))
1945+ if (cannotHoistOrSinkRecipe (* Current))
19331946 return false ;
19341947
19351948 for (VPValue *Op : Current->operands ()) {
@@ -2144,24 +2157,6 @@ void VPlanTransforms::cse(VPlan &Plan) {
21442157static void licm (VPlan &Plan) {
21452158 VPBasicBlock *Preheader = Plan.getVectorPreheader ();
21462159
2147- // Return true if we do not know how to (mechanically) hoist a given recipe
2148- // out of a loop region.
2149- auto CannotHoistRecipe = [](VPRecipeBase &R) {
2150- // Assumes don't alias anything or throw; as long as they're guaranteed to
2151- // execute, they're safe to hoist.
2152- if (match (&R, m_Intrinsic<Intrinsic::assume>()))
2153- return false ;
2154-
2155- // TODO: Relax checks in the future, e.g. we could also hoist reads, if
2156- // their memory location is not modified in the vector loop.
2157- if (R.mayHaveSideEffects () || R.mayReadFromMemory () || R.isPhi ())
2158- return true ;
2159-
2160- // Allocas cannot be hoisted.
2161- auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
2162- return RepR && RepR->getOpcode () == Instruction::Alloca;
2163- };
2164-
21652160 // Hoist any loop invariant recipes from the vector loop region to the
21662161 // preheader. Preform a shallow traversal of the vector loop region, to
21672162 // exclude recipes in replicate regions. Since the top-level blocks in the
@@ -2173,7 +2168,7 @@ static void licm(VPlan &Plan) {
21732168 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
21742169 vp_depth_first_shallow (LoopRegion->getEntry ()))) {
21752170 for (VPRecipeBase &R : make_early_inc_range (*VPBB)) {
2176- if (CannotHoistRecipe (R))
2171+ if (cannotHoistOrSinkRecipe (R))
21772172 continue ;
21782173 if (any_of (R.operands (), [](VPValue *Op) {
21792174 return !Op->isDefinedOutsideLoopRegions ();
0 commit comments