Skip to content

Commit 7933686

Browse files
committed
[CodeGen][MachinePipeliner] Limit register pressure when scheduling
In software pipelining, when searching for the Initiation Interval (II), `MachinePipeliner` tries to reduce register pressure, but doesn't check how many variables can actually alive at the same time. This can result a lot of register spills/fills can be generated after register allocation, which might cause performance degradation. To prevent such cases, this patch adds a check phase that calculates the maximum register pressure of the scheduled loop and reject it if the pressure is too high. This can be enabled this by specifying `pipeliner-register-pressure`. Additionally, an II search range is currently fixed at 10, which is too small to find a schedule when the above algorithm is applied. Threfore this patch also adds a new option `pipeliner-ii-search-range` to specify the length of the range to search. There is one more new option `pipeliner-register-pressure-margin`, which can be used to estimate a register pressure limit less than actual for conservative analysis. Discourse thread: https://discourse.llvm.org/t/considering-register-pressure-when-deciding-initiation-interval-in-machinepipeliner/74725
1 parent 5ac1295 commit 7933686

File tree

3 files changed

+791
-27
lines changed

3 files changed

+791
-27
lines changed

llvm/include/llvm/CodeGen/MachinePipeliner.h

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,8 @@ class SwingSchedulerDAG : public ScheduleDAGInstrs {
273273

274274
/// Return the new base register that was stored away for the changed
275275
/// instruction.
276-
unsigned getInstrBaseReg(SUnit *SU) {
277-
DenseMap<SUnit *, std::pair<unsigned, int64_t>>::iterator It =
276+
unsigned getInstrBaseReg(SUnit *SU) const {
277+
DenseMap<SUnit *, std::pair<unsigned, int64_t>>::const_iterator It =
278278
InstrChanges.find(SU);
279279
if (It != InstrChanges.end())
280280
return It->second.first;
@@ -639,16 +639,20 @@ class SMSchedule {
639639
computeUnpipelineableNodes(SwingSchedulerDAG *SSD,
640640
TargetInstrInfo::PipelinerLoopInfo *PLI);
641641

642+
std::deque<SUnit *>
643+
reorderInstructions(const SwingSchedulerDAG *SSD,
644+
const std::deque<SUnit *> &Instrs) const;
645+
642646
bool
643647
normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD,
644648
TargetInstrInfo::PipelinerLoopInfo *PLI);
645649
bool isValidSchedule(SwingSchedulerDAG *SSD);
646650
void finalizeSchedule(SwingSchedulerDAG *SSD);
647-
void orderDependence(SwingSchedulerDAG *SSD, SUnit *SU,
648-
std::deque<SUnit *> &Insts);
649-
bool isLoopCarried(SwingSchedulerDAG *SSD, MachineInstr &Phi);
650-
bool isLoopCarriedDefOfUse(SwingSchedulerDAG *SSD, MachineInstr *Def,
651-
MachineOperand &MO);
651+
void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU,
652+
std::deque<SUnit *> &Insts) const;
653+
bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const;
654+
bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def,
655+
MachineOperand &MO) const;
652656
void print(raw_ostream &os) const;
653657
void dump() const;
654658
};

0 commit comments

Comments
 (0)