Skip to content

Commit 09464c4

Browse files
committed
[MachinePipeliner] Fix constraints aren't considered in certain cases
when scheduling When scheduling an instruction, if both any predecessors and any successors of the instruction are already scheduled, `SchedStart` isn't taken into account. It may result generating incorrect code. This patch fixes the problem.
1 parent 307d91e commit 09464c4

File tree

3 files changed

+379
-33
lines changed

3 files changed

+379
-33
lines changed

llvm/include/llvm/CodeGen/MachinePipeliner.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,8 +594,8 @@ class SMSchedule {
594594
/// chain.
595595
int latestCycleInChain(const SDep &Dep);
596596

597-
void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
598-
int *MinEnd, int *MaxStart, int II, SwingSchedulerDAG *DAG);
597+
void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int II,
598+
SwingSchedulerDAG *DAG);
599599
bool insert(SUnit *SU, int StartCycle, int EndCycle, int II);
600600

601601
/// Iterators for the cycle to instruction map.
@@ -653,6 +653,9 @@ class SMSchedule {
653653
bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const;
654654
bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def,
655655
MachineOperand &MO) const;
656+
657+
bool onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU,
658+
SwingSchedulerDAG *DAG) const;
656659
void print(raw_ostream &os) const;
657660
void dump() const;
658661
};

llvm/lib/CodeGen/MachinePipeliner.cpp

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2420,47 +2420,43 @@ bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
24202420
// upon the scheduled time for any predecessors/successors.
24212421
int EarlyStart = INT_MIN;
24222422
int LateStart = INT_MAX;
2423-
// These values are set when the size of the schedule window is limited
2424-
// due to chain dependences.
2425-
int SchedEnd = INT_MAX;
2426-
int SchedStart = INT_MIN;
2427-
Schedule.computeStart(SU, &EarlyStart, &LateStart, &SchedEnd, &SchedStart,
2428-
II, this);
2423+
Schedule.computeStart(SU, &EarlyStart, &LateStart, II, this);
24292424
LLVM_DEBUG({
24302425
dbgs() << "\n";
24312426
dbgs() << "Inst (" << SU->NodeNum << ") ";
24322427
SU->getInstr()->dump();
24332428
dbgs() << "\n";
24342429
});
2435-
LLVM_DEBUG({
2436-
dbgs() << format("\tes: %8x ls: %8x me: %8x ms: %8x\n", EarlyStart,
2437-
LateStart, SchedEnd, SchedStart);
2438-
});
2430+
LLVM_DEBUG(
2431+
dbgs() << format("\tes: %8x ls: %8x\n", EarlyStart, LateStart));
24392432

2440-
if (EarlyStart > LateStart || SchedEnd < EarlyStart ||
2441-
SchedStart > LateStart)
2433+
if (EarlyStart > LateStart)
24422434
scheduleFound = false;
2443-
else if (EarlyStart != INT_MIN && LateStart == INT_MAX) {
2444-
SchedEnd = std::min(SchedEnd, EarlyStart + (int)II - 1);
2445-
scheduleFound = Schedule.insert(SU, EarlyStart, SchedEnd, II);
2446-
} else if (EarlyStart == INT_MIN && LateStart != INT_MAX) {
2447-
SchedStart = std::max(SchedStart, LateStart - (int)II + 1);
2448-
scheduleFound = Schedule.insert(SU, LateStart, SchedStart, II);
2449-
} else if (EarlyStart != INT_MIN && LateStart != INT_MAX) {
2450-
SchedEnd =
2451-
std::min(SchedEnd, std::min(LateStart, EarlyStart + (int)II - 1));
2452-
// When scheduling a Phi it is better to start at the late cycle and go
2453-
// backwards. The default order may insert the Phi too far away from
2454-
// its first dependence.
2455-
if (SU->getInstr()->isPHI())
2456-
scheduleFound = Schedule.insert(SU, SchedEnd, EarlyStart, II);
2435+
else if (EarlyStart != INT_MIN && LateStart == INT_MAX)
2436+
scheduleFound =
2437+
Schedule.insert(SU, EarlyStart, EarlyStart + (int)II - 1, II);
2438+
else if (EarlyStart == INT_MIN && LateStart != INT_MAX)
2439+
scheduleFound =
2440+
Schedule.insert(SU, LateStart, LateStart - (int)II + 1, II);
2441+
else if (EarlyStart != INT_MIN && LateStart != INT_MAX) {
2442+
LateStart = std::min(LateStart, EarlyStart + (int)II - 1);
2443+
// When scheduling a Phi it is better to start at the late cycle and
2444+
// go backwards. The default order may insert the Phi too far away
2445+
// from its first dependence.
2446+
// Also, do backward search when all scheduled predecessors are
2447+
// loop-carried output/order dependencies. Empirically, there are also
2448+
// cases where scheduling becomes possible with backward search.
2449+
if (SU->getInstr()->isPHI() ||
2450+
Schedule.onlyHasLoopCarriedOutputOrOrderPreds(SU, this))
2451+
scheduleFound = Schedule.insert(SU, LateStart, EarlyStart, II);
24572452
else
2458-
scheduleFound = Schedule.insert(SU, EarlyStart, SchedEnd, II);
2453+
scheduleFound = Schedule.insert(SU, EarlyStart, LateStart, II);
24592454
} else {
24602455
int FirstCycle = Schedule.getFirstCycle();
24612456
scheduleFound = Schedule.insert(SU, FirstCycle + getASAP(SU),
24622457
FirstCycle + getASAP(SU) + II - 1, II);
24632458
}
2459+
24642460
// Even if we find a schedule, make sure the schedule doesn't exceed the
24652461
// allowable number of stages. We keep trying if this happens.
24662462
if (scheduleFound)
@@ -2868,8 +2864,7 @@ static SUnit *multipleIterations(SUnit *SU, SwingSchedulerDAG *DAG) {
28682864
/// Compute the scheduling start slot for the instruction. The start slot
28692865
/// depends on any predecessor or successor nodes scheduled already.
28702866
void SMSchedule::computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
2871-
int *MinEnd, int *MaxStart, int II,
2872-
SwingSchedulerDAG *DAG) {
2867+
int II, SwingSchedulerDAG *DAG) {
28732868
// Iterate over each instruction that has been scheduled already. The start
28742869
// slot computation depends on whether the previously scheduled instruction
28752870
// is a predecessor or successor of the specified instruction.
@@ -2888,7 +2883,7 @@ void SMSchedule::computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
28882883
*MaxEarlyStart = std::max(*MaxEarlyStart, EarlyStart);
28892884
if (DAG->isLoopCarriedDep(SU, Dep, false)) {
28902885
int End = earliestCycleInChain(Dep) + (II - 1);
2891-
*MinEnd = std::min(*MinEnd, End);
2886+
*MinLateStart = std::min(*MinLateStart, End);
28922887
}
28932888
} else {
28942889
int LateStart = cycle - Dep.getLatency() +
@@ -2912,7 +2907,7 @@ void SMSchedule::computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
29122907
*MinLateStart = std::min(*MinLateStart, LateStart);
29132908
if (DAG->isLoopCarriedDep(SU, Dep)) {
29142909
int Start = latestCycleInChain(Dep) + 1 - II;
2915-
*MaxStart = std::max(*MaxStart, Start);
2910+
*MaxEarlyStart = std::max(*MaxEarlyStart, Start);
29162911
}
29172912
} else {
29182913
int EarlyStart = cycle + Dep.getLatency() -
@@ -3105,6 +3100,19 @@ bool SMSchedule::isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD,
31053100
return false;
31063101
}
31073102

3103+
/// Return true if all scheduled predecessors are loop-carried output/order
3104+
/// dependencies.
3105+
bool SMSchedule::onlyHasLoopCarriedOutputOrOrderPreds(
3106+
SUnit *SU, SwingSchedulerDAG *DAG) const {
3107+
for (const SDep &Pred : SU->Preds)
3108+
if (InstrToCycle.count(Pred.getSUnit()) && !DAG->isBackedge(SU, Pred))
3109+
return false;
3110+
for (const SDep &Succ : SU->Succs)
3111+
if (InstrToCycle.count(Succ.getSUnit()) && DAG->isBackedge(SU, Succ))
3112+
return false;
3113+
return true;
3114+
}
3115+
31083116
/// Determine transitive dependences of unpipelineable instructions
31093117
SmallSet<SUnit *, 8> SMSchedule::computeUnpipelineableNodes(
31103118
SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI) {

0 commit comments

Comments
 (0)