[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.
This commit is contained in:
Philip Reames 2022-03-25 10:01:39 -07:00
parent a16308c282
commit ec858f0201
1 changed files with 41 additions and 29 deletions

View File

@ -2764,6 +2764,7 @@ private:
ScheduleEnd = nullptr; ScheduleEnd = nullptr;
FirstLoadStoreInRegion = nullptr; FirstLoadStoreInRegion = nullptr;
LastLoadStoreInRegion = nullptr; LastLoadStoreInRegion = nullptr;
RegionHasStackSave = false;
// Reduce the maximum schedule region size by the size of the // Reduce the maximum schedule region size by the size of the
// previous scheduling run. // previous scheduling run.
@ -3032,6 +3033,11 @@ private:
/// (can be null). /// (can be null).
ScheduleData *LastLoadStoreInRegion = nullptr; 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. /// The current size of the scheduling region.
int ScheduleRegionSize = 0; int ScheduleRegionSize = 0;
@ -8016,6 +8022,10 @@ void BoUpSLP::BlockScheduling::initScheduleData(Instruction *FromI,
} }
CurrentLoadStore = SD; CurrentLoadStore = SD;
} }
if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
match(I, m_Intrinsic<Intrinsic::stackrestore>()))
RegionHasStackSave = true;
} }
if (NextLoadStore) { if (NextLoadStore) {
if (CurrentLoadStore) if (CurrentLoadStore)
@ -8099,40 +8109,42 @@ void BoUpSLP::BlockScheduling::calculateDependencies(ScheduleData *SD,
} }
} }
// If we have an inalloc alloca instruction, it needs to be scheduled if (RegionHasStackSave) {
// after any preceeding stacksave. We also need to prevent any alloca // If we have an inalloc alloca instruction, it needs to be scheduled
// from reordering above a preceeding stackrestore. // after any preceeding stacksave. We also need to prevent any alloca
if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>()) || // from reordering above a preceeding stackrestore.
match(BundleMember->Inst, m_Intrinsic<Intrinsic::stackrestore>())) { if (match(BundleMember->Inst, m_Intrinsic<Intrinsic::stacksave>()) ||
for (Instruction *I = BundleMember->Inst->getNextNode(); match(BundleMember->Inst, m_Intrinsic<Intrinsic::stackrestore>())) {
I != ScheduleEnd; I = I->getNextNode()) { for (Instruction *I = BundleMember->Inst->getNextNode();
if (match(I, m_Intrinsic<Intrinsic::stacksave>()) || I != ScheduleEnd; I = I->getNextNode()) {
match(I, m_Intrinsic<Intrinsic::stackrestore>())) if (match(I, m_Intrinsic<Intrinsic::stacksave>()) ||
// Any allocas past here must be control dependent on I, and I match(I, m_Intrinsic<Intrinsic::stackrestore>()))
// must be memory dependend on BundleMember->Inst. // Any allocas past here must be control dependent on I, and I
break; // must be memory dependend on BundleMember->Inst.
break;
if (!isa<AllocaInst>(I)) if (!isa<AllocaInst>(I))
continue; continue;
// Add the dependency // Add the dependency
makeControlDependent(I); makeControlDependent(I);
}
} }
}
// In addition to the cases handle just above, we need to prevent // In addition to the cases handle just above, we need to prevent
// allocas from moving below a stacksave. The stackrestore case // allocas from moving below a stacksave. The stackrestore case
// is currently thought to be conservatism. // is currently thought to be conservatism.
if (isa<AllocaInst>(BundleMember->Inst)) { if (isa<AllocaInst>(BundleMember->Inst)) {
for (Instruction *I = BundleMember->Inst->getNextNode(); for (Instruction *I = BundleMember->Inst->getNextNode();
I != ScheduleEnd; I = I->getNextNode()) { I != ScheduleEnd; I = I->getNextNode()) {
if (!match(I, m_Intrinsic<Intrinsic::stacksave>()) && if (!match(I, m_Intrinsic<Intrinsic::stacksave>()) &&
!match(I, m_Intrinsic<Intrinsic::stackrestore>())) !match(I, m_Intrinsic<Intrinsic::stackrestore>()))
continue; continue;
// Add the dependency // Add the dependency
makeControlDependent(I); makeControlDependent(I);
break; break;
}
} }
} }