-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[VPlan] Add initial loop-invariant code motion transform. #107894
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7e9a5f8
3caeea3
f93524c
578ec3e
a3ac937
62a24af
eb9dc17
b996541
9807dfe
7817971
fa1d94f
46636d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -971,6 +971,41 @@ static void simplifyRecipe(VPRecipeBase &R, VPTypeAnalysis &TypeInfo) { | |
return R.getVPSingleValue()->replaceAllUsesWith(A); | ||
} | ||
|
||
/// Move loop-invariant recipes out of the vector loop region in \p Plan. | ||
static void licm(VPlan &Plan) { | ||
VPRegionBlock *LoopRegion = Plan.getVectorLoopRegion(); | ||
VPBasicBlock *Preheader = | ||
cast<VPBasicBlock>(LoopRegion->getSinglePredecessor()); | ||
|
||
// Return true if we do not know how to (mechanically) hoist a given recipe | ||
// out of a loop region. Does not address legality concerns such as aliasing | ||
// or speculation safety. | ||
auto CannotHoistRecipe = [](VPRecipeBase &R) { | ||
// Allocas cannot be hoisted. | ||
auto *RepR = dyn_cast<VPReplicateRecipe>(&R); | ||
return RepR && RepR->getOpcode() == Instruction::Alloca; | ||
Comment on lines
+985
to
+986
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: match? |
||
}; | ||
|
||
// Hoist any loop invariant recipes from the vector loop region to the | ||
// preheader. Preform a shallow traversal of the vector loop region, to | ||
// exclude recipes in replicate regions. | ||
for (VPBasicBlock *VPBB : VPBlockUtils::blocksOnly<VPBasicBlock>( | ||
vp_depth_first_shallow(LoopRegion->getEntry()))) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shallow to exclude going into replicate regions (we also check for side effects), visit only blocks that post-dom the header? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, I'll add a comment to clarify re shallow traversal. |
||
for (VPRecipeBase &R : make_early_inc_range(*VPBB)) { | ||
if (CannotHoistRecipe(R)) | ||
continue; | ||
// TODO: Relax checks in the future, e.g. we could also hoist reads, if | ||
// their memory location is not modified in the vector loop. | ||
if (R.mayHaveSideEffects() || R.mayReadFromMemory() || R.isPhi() || | ||
any_of(R.operands(), [](VPValue *Op) { | ||
return !Op->isDefinedOutsideLoopRegions(); | ||
})) | ||
continue; | ||
R.moveBefore(*Preheader, Preheader->end()); | ||
} | ||
} | ||
} | ||
|
||
/// Try to simplify the recipes in \p Plan. | ||
static void simplifyRecipes(VPlan &Plan) { | ||
ReversePostOrderTraversal<VPBlockDeepTraversalWrapper<VPBlockBase *>> RPOT( | ||
|
@@ -1123,6 +1158,7 @@ void VPlanTransforms::optimize(VPlan &Plan) { | |
removeRedundantInductionCasts(Plan); | ||
|
||
simplifyRecipes(Plan); | ||
licm(Plan); | ||
legalizeAndOptimizeInductions(Plan); | ||
removeDeadRecipes(Plan); | ||
|
||
|
Large diffs are not rendered by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(strictly speaking, qualifies as
GrandParent
;-))There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we should introduce
getParentRegion
orgetRegion
, similar toInstruction::getFunction
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe
getEnclosingRegion()
, to complement and servegetEnclosingLoopRegion()
?