[llvm] [VPlan] Cache the vector loop region lookup (PR #199437)
via llvm-commits
llvm-commits at lists.llvm.org
Sun May 24 11:46:34 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-vectorizers
Author: Madhur Amilkanthwar (madhur13490)
<details>
<summary>Changes</summary>
Resolves the TODO in VPlan::getVectorLoopRegion() with a mutable cache on VPlan, shared by both overloads.
Measured on an O3 build of the LLVM test suite (~12k TUs): 3,556,267 hits / 126,196 misses (96.57% hit rate).
---
Full diff: https://github.com/llvm/llvm-project/pull/199437.diff
3 Files Affected:
- (modified) llvm/lib/Transforms/Vectorize/VPlan.cpp (+7-7)
- (modified) llvm/lib/Transforms/Vectorize/VPlan.h (+10)
- (modified) llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp (+2)
``````````diff
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.cpp b/llvm/lib/Transforms/Vectorize/VPlan.cpp
index d2a1161984d9a..850b89f203e26 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlan.cpp
@@ -1096,18 +1096,18 @@ InstructionCost VPlan::cost(ElementCount VF, VPCostContext &Ctx) {
}
VPRegionBlock *VPlan::getVectorLoopRegion() {
- // TODO: Cache if possible.
+ if (VectorLoopRegion)
+ return VectorLoopRegion;
for (VPBlockBase *B : vp_depth_first_shallow(getEntry()))
- if (auto *R = dyn_cast<VPRegionBlock>(B))
- return R->isReplicator() ? nullptr : R;
+ if (auto *R = dyn_cast<VPRegionBlock>(B)) {
+ VectorLoopRegion = R->isReplicator() ? nullptr : R;
+ return VectorLoopRegion;
+ }
return nullptr;
}
const VPRegionBlock *VPlan::getVectorLoopRegion() const {
- for (const VPBlockBase *B : vp_depth_first_shallow(getEntry()))
- if (auto *R = dyn_cast<VPRegionBlock>(B))
- return R->isReplicator() ? nullptr : R;
- return nullptr;
+ return const_cast<VPlan *>(this)->getVectorLoopRegion();
}
bool VPlan::isOuterLoop() const {
diff --git a/llvm/lib/Transforms/Vectorize/VPlan.h b/llvm/lib/Transforms/Vectorize/VPlan.h
index 7025f39decaf5..040ac9e4e8da1 100644
--- a/llvm/lib/Transforms/Vectorize/VPlan.h
+++ b/llvm/lib/Transforms/Vectorize/VPlan.h
@@ -4675,6 +4675,11 @@ class VPlan {
/// VPlan is destroyed.
SmallVector<VPBlockBase *> CreatedBlocks;
+ /// Cached pointer to the (non-replicator) vector loop region, populated
+ /// lazily by getVectorLoopRegion(). Reset by setEntry() and by
+ /// VPlanTransforms::dissolveLoopRegions() once the loop region is detached.
+ mutable VPRegionBlock *VectorLoopRegion = nullptr;
+
/// Construct a VPlan with \p Entry to the plan and with \p ScalarHeader
/// wrapping the original header of the scalar loop. The vector loop will have
/// index type \p IdxTy.
@@ -4706,8 +4711,13 @@ class VPlan {
void setEntry(VPBasicBlock *VPBB) {
Entry = VPBB;
VPBB->setPlan(this);
+ invalidateVectorLoopRegionCache();
}
+ /// Reset the cached vector loop region pointer. Must be called by
+ /// transforms that change the top-level region structure.
+ void invalidateVectorLoopRegionCache() { VectorLoopRegion = nullptr; }
+
/// Generate the IR code for this VPlan.
void execute(VPTransformState *State);
diff --git a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
index e5b7041a002a1..3a1613b5f45d5 100644
--- a/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
+++ b/llvm/lib/Transforms/Vectorize/VPlanTransforms.cpp
@@ -3936,6 +3936,8 @@ void VPlanTransforms::dissolveLoopRegions(VPlan &Plan) {
}
for (VPRegionBlock *R : LoopRegions)
R->dissolveToCFGLoop();
+ // Drop any cached pointer to the (now-detached) vector loop region.
+ Plan.invalidateVectorLoopRegionCache();
}
void VPlanTransforms::expandBranchOnTwoConds(VPlan &Plan) {
``````````
</details>
https://github.com/llvm/llvm-project/pull/199437
More information about the llvm-commits
mailing list