@@ -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 a given
135+ // recipe out of a loop region. Does not address legality concerns such as
136+ // aliasing or speculation safety.
137+ static bool cannotHoistOrSinkRecipe (const VPRecipeBase &R) {
138+ // Assumes don't alias anything or throw.
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 or sink reads,
143+ // if their memory location is not modified in the vector loop.
144+ if (R.mayReadOrWriteMemory () || R.isPhi ())
145+ return true ;
146+
147+ // Allocas cannot be hoisted or sunk.
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 ;
@@ -1765,7 +1783,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
17651783 VPDT.properlyDominates (Previous, SinkCandidate))
17661784 return true ;
17671785
1768- if (SinkCandidate-> mayHaveSideEffects ( ))
1786+ if (cannotHoistOrSinkRecipe (*SinkCandidate ))
17691787 return false ;
17701788
17711789 WorkList.push_back (SinkCandidate);
@@ -1805,7 +1823,7 @@ sinkRecurrenceUsersAfterPrevious(VPFirstOrderRecurrencePHIRecipe *FOR,
18051823static bool hoistPreviousBeforeFORUsers (VPFirstOrderRecurrencePHIRecipe *FOR,
18061824 VPRecipeBase *Previous,
18071825 VPDominatorTree &VPDT) {
1808- if (Previous-> mayHaveSideEffects () || Previous-> mayReadFromMemory ( ))
1826+ if (cannotHoistOrSinkRecipe (* Previous))
18091827 return false ;
18101828
18111829 // Collect recipes that need hoisting.
@@ -1852,11 +1870,6 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18521870 return nullptr ;
18531871 return HoistCandidate;
18541872 };
1855- auto CanHoist = [&](VPRecipeBase *HoistCandidate) {
1856- // Avoid hoisting candidates with side-effects, as we do not yet analyze
1857- // associated dependencies.
1858- return !HoistCandidate->mayHaveSideEffects ();
1859- };
18601873
18611874 if (!NeedsHoisting (Previous->getVPSingleValue ()))
18621875 return true ;
@@ -1868,7 +1881,7 @@ static bool hoistPreviousBeforeFORUsers(VPFirstOrderRecurrencePHIRecipe *FOR,
18681881 VPRecipeBase *Current = HoistCandidates[I];
18691882 assert (Current->getNumDefinedValues () == 1 &&
18701883 " only recipes with a single defined value expected" );
1871- if (! CanHoist ( Current))
1884+ if (cannotHoistOrSinkRecipe (* Current))
18721885 return false ;
18731886
18741887 for (VPValue *Op : Current->operands ()) {
@@ -2102,24 +2115,6 @@ static bool isSafeToSpeculativelyExecute(VPRecipeBase *R) {
21022115static void licm (VPlan &Plan) {
21032116 VPBasicBlock *Preheader = Plan.getVectorPreheader ();
21042117
2105- // Return true if we do not know how to (mechanically) hoist a given recipe
2106- // out of a loop region. Does not address legality concerns such as aliasing
2107- // or speculation safety.
2108- auto CannotHoistRecipe = [](VPRecipeBase &R) {
2109- // Assumes don't alias anything or throw.
2110- if (match (&R, m_Intrinsic<Intrinsic::assume>()))
2111- return false ;
2112-
2113- // TODO: Relax checks in the future, e.g. we could also hoist reads, if
2114- // their memory location is not modified in the vector loop.
2115- if (R.mayReadOrWriteMemory () || R.isPhi ())
2116- return true ;
2117-
2118- // Allocas cannot be hoisted.
2119- auto *RepR = dyn_cast<VPReplicateRecipe>(&R);
2120- return RepR && RepR->getOpcode () == Instruction::Alloca;
2121- };
2122-
21232118 // Hoist any loop invariant recipes from the vector loop region to the
21242119 // preheader. Preform a shallow traversal of the vector loop region, to
21252120 // exclude recipes in replicate regions.
@@ -2128,7 +2123,7 @@ static void licm(VPlan &Plan) {
21282123 for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>(
21292124 vp_depth_first_shallow (LoopRegion->getEntry ()))) {
21302125 for (VPRecipeBase &R : make_early_inc_range (*VPBB)) {
2131- if (CannotHoistRecipe (R))
2126+ if (cannotHoistOrSinkRecipe (R))
21322127 continue ;
21332128 if ((!GuaranteedToExecute && !isSafeToSpeculativelyExecute (&R)) ||
21342129 any_of (R.operands (), [](VPValue *Op) {
0 commit comments