-
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 9 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,40 @@ 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-and-only-if we know how to (mechanically) both hoist a given | ||
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. both? 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. Dropped thanks! |
||
// recipe out of a loop region. Does not address legality concerns such as | ||
// aliasing or speculation safety. | ||
auto CanHoistRecipe = [](VPRecipeBase &R) { | ||
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. CannotHoistRecipe than double negate? Inline? 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. adjusted, thanks! |
||
// Allocas cannot be hoisted. | ||
auto *RepR = dyn_cast<VPReplicateRecipe>(&R); | ||
return !RepR || RepR->getOpcode() != Instruction::Alloca; | ||
}; | ||
|
||
// Hoist any loop invariant recipes from the vector loop region to the | ||
// preheader. | ||
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 (!CanHoistRecipe(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 +1157,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()
?