[llvm] ec858f0 - [SLP] Optimize stacksave dependence handling [NFC]
Philip Reames via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 25 10:04:51 PDT 2022
Author: Philip Reames
Date: 2022-03-25T10:04:10-07:00
New Revision: ec858f02015c32c683852fe72761a2e610dc5785
URL: https://github.com/llvm/llvm-project/commit/ec858f02015c32c683852fe72761a2e610dc5785
DIFF: https://github.com/llvm/llvm-project/commit/ec858f02015c32c683852fe72761a2e610dc5785.diff
LOG: [SLP] Optimize stacksave dependence handling [NFC]
After writing the commit message for 4b1bace28, realized that the mentioned optimization was rather straight forward. We already have the code for scanning a block during region initialization, we can simply keep track if we've seen a stacksave or stackrestore. If we haven't, none of these dependencies are relevant and we can avoid the relatively expensive scans entirely.
Added:
Modified:
llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
index 7296dba13aaac..7999f469be928 100644
--- a/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
+++ b/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
@@ -2764,6 +2764,7 @@ class BoUpSLP {
ScheduleEnd = nullptr;
FirstLoadStoreInRegion = nullptr;
LastLoadStoreInRegion = nullptr;
+ RegionHasStackSave = false;
// Reduce the maximum schedule region size by the size of the
// previous scheduling run.
@@ -3032,6 +3033,11 @@ class BoUpSLP {
/// (can be null).
ScheduleData *LastLoadStoreInRegion = nullptr;
+ /// Is there an llvm.stacksave or llvm.stackrestore in the scheduling
+ /// region? Used to optimize the dependence calculation for the
+ /// common case where there isn't.
+ bool RegionHasStackSave = false;
+
/// The current size of the scheduling region.
int ScheduleRegionSize = 0;
@@ -8016,6 +8022,10 @@ void BoUpSLP::BlockScheduling::initScheduleData(Instruction *FromI,
}
CurrentLoadStore = SD;
}
+
+ if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
+ match(I, m_Intrinsic<Intrinsic::stackrestore>()))
+ RegionHasStackSave = true;
}
if (NextLoadStore) {
if (CurrentLoadStore)
@@ -8099,40 +8109,42 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
}
}
- // If we have an inalloc alloca instruction, it needs to be scheduled
- // after any preceeding stacksave. We also need to prevent any alloca
- // from reordering above a preceeding stackrestore.
- if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>()) ||
- match(BundleMember->Inst, m_Intrinsic<Intrinsic::stackrestore>())) {
- for (Instruction *I = BundleMember->Inst->getNextNode();
- I != ScheduleEnd; I = I->getNextNode()) {
- if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
- match(I, m_Intrinsic<Intrinsic::stackrestore>()))
- // Any allocas past here must be control dependent on I, and I
- // must be memory dependend on BundleMember->Inst.
- break;
+ if (RegionHasStackSave) {
+ // If we have an inalloc alloca instruction, it needs to be scheduled
+ // after any preceeding stacksave. We also need to prevent any alloca
+ // from reordering above a preceeding stackrestore.
+ if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>()) ||
+ match(BundleMember->Inst, m_Intrinsic<Intrinsic::stackrestore>())) {
+ for (Instruction *I = BundleMember->Inst->getNextNode();
+ I != ScheduleEnd; I = I->getNextNode()) {
+ if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
+ match(I, m_Intrinsic<Intrinsic::stackrestore>()))
+ // Any allocas past here must be control dependent on I, and I
+ // must be memory dependend on BundleMember->Inst.
+ break;
- if (!isa<AllocaInst>(I))
- continue;
+ if (!isa<AllocaInst>(I))
+ continue;
- // Add the dependency
- makeControlDependent(I);
+ // Add the dependency
+ makeControlDependent(I);
+ }
}
- }
- // In addition to the cases handle just above, we need to prevent
- // allocas from moving below a stacksave. The stackrestore case
- // is currently thought to be conservatism.
- if (isa<AllocaInst>(BundleMember->Inst)) {
- for (Instruction *I = BundleMember->Inst->getNextNode();
- I != ScheduleEnd; I = I->getNextNode()) {
- if (!match(I, m_Intrinsic<Intrinsic::stacksave>()) &&
- !match(I, m_Intrinsic<Intrinsic::stackrestore>()))
- continue;
+ // In addition to the cases handle just above, we need to prevent
+ // allocas from moving below a stacksave. The stackrestore case
+ // is currently thought to be conservatism.
+ if (isa<AllocaInst>(BundleMember->Inst)) {
+ for (Instruction *I = BundleMember->Inst->getNextNode();
+ I != ScheduleEnd; I = I->getNextNode()) {
+ if (!match(I, m_Intrinsic<Intrinsic::stacksave>()) &&
+ !match(I, m_Intrinsic<Intrinsic::stackrestore>()))
+ continue;
- // Add the dependency
- makeControlDependent(I);
- break;
+ // Add the dependency
+ makeControlDependent(I);
+ break;
+ }
}
}
More information about the llvm-commits
mailing list