LLVM  14.0.0git
PPCMachineScheduler.cpp
Go to the documentation of this file.
1 //===- PPCMachineScheduler.cpp - MI Scheduler for PowerPC -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "PPCMachineScheduler.h"
11 
12 using namespace llvm;
13 
14 static cl::opt<bool>
15 DisableAddiLoadHeuristic("disable-ppc-sched-addi-load",
16  cl::desc("Disable scheduling addi instruction before"
17  "load for ppc"), cl::Hidden);
18 static cl::opt<bool>
19  EnableAddiHeuristic("ppc-postra-bias-addi",
20  cl::desc("Enable scheduling addi instruction as early"
21  "as possible post ra"),
22  cl::Hidden, cl::init(true));
23 
24 static bool isADDIInstr(const GenericScheduler::SchedCandidate &Cand) {
25  return Cand.SU->getInstr()->getOpcode() == PPC::ADDI ||
26  Cand.SU->getInstr()->getOpcode() == PPC::ADDI8;
27 }
28 
29 bool PPCPreRASchedStrategy::biasAddiLoadCandidate(SchedCandidate &Cand,
30  SchedCandidate &TryCand,
31  SchedBoundary &Zone) const {
33  return false;
34 
35  SchedCandidate &FirstCand = Zone.isTop() ? TryCand : Cand;
36  SchedCandidate &SecondCand = Zone.isTop() ? Cand : TryCand;
37  if (isADDIInstr(FirstCand) && SecondCand.SU->getInstr()->mayLoad()) {
38  TryCand.Reason = Stall;
39  return true;
40  }
41  if (FirstCand.SU->getInstr()->mayLoad() && isADDIInstr(SecondCand)) {
42  TryCand.Reason = NoCand;
43  return true;
44  }
45 
46  return false;
47 }
48 
50  SchedCandidate &TryCand,
51  SchedBoundary *Zone) const {
52  // From GenericScheduler::tryCandidate
53 
54  // Initialize the candidate if needed.
55  if (!Cand.isValid()) {
56  TryCand.Reason = NodeOrder;
57  return true;
58  }
59 
60  // Bias PhysReg Defs and copies to their uses and defined respectively.
61  if (tryGreater(biasPhysReg(TryCand.SU, TryCand.AtTop),
62  biasPhysReg(Cand.SU, Cand.AtTop), TryCand, Cand, PhysReg))
63  return TryCand.Reason != NoCand;
64 
65  // Avoid exceeding the target's limit.
66  if (DAG->isTrackingPressure() &&
67  tryPressure(TryCand.RPDelta.Excess, Cand.RPDelta.Excess, TryCand, Cand,
68  RegExcess, TRI, DAG->MF))
69  return TryCand.Reason != NoCand;
70 
71  // Avoid increasing the max critical pressure in the scheduled region.
72  if (DAG->isTrackingPressure() &&
74  TryCand, Cand, RegCritical, TRI, DAG->MF))
75  return TryCand.Reason != NoCand;
76 
77  // We only compare a subset of features when comparing nodes between
78  // Top and Bottom boundary. Some properties are simply incomparable, in many
79  // other instances we should only override the other boundary if something
80  // is a clear good pick on one boundary. Skip heuristics that are more
81  // "tie-breaking" in nature.
82  bool SameBoundary = Zone != nullptr;
83  if (SameBoundary) {
84  // For loops that are acyclic path limited, aggressively schedule for
85  // latency. Within an single cycle, whenever CurrMOps > 0, allow normal
86  // heuristics to take precedence.
87  if (Rem.IsAcyclicLatencyLimited && !Zone->getCurrMOps() &&
88  tryLatency(TryCand, Cand, *Zone))
89  return TryCand.Reason != NoCand;
90 
91  // Prioritize instructions that read unbuffered resources by stall cycles.
92  if (tryLess(Zone->getLatencyStallCycles(TryCand.SU),
93  Zone->getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
94  return TryCand.Reason != NoCand;
95  }
96 
97  // Keep clustered nodes together to encourage downstream peephole
98  // optimizations which may reduce resource requirements.
99  //
100  // This is a best effort to set things up for a post-RA pass. Optimizations
101  // like generating loads of multiple registers should ideally be done within
102  // the scheduler pass by combining the loads during DAG postprocessing.
103  const SUnit *CandNextClusterSU =
105  const SUnit *TryCandNextClusterSU =
107  if (tryGreater(TryCand.SU == TryCandNextClusterSU,
108  Cand.SU == CandNextClusterSU, TryCand, Cand, Cluster))
109  return TryCand.Reason != NoCand;
110 
111  if (SameBoundary) {
112  // Weak edges are for clustering and other constraints.
113  if (tryLess(getWeakLeft(TryCand.SU, TryCand.AtTop),
114  getWeakLeft(Cand.SU, Cand.AtTop), TryCand, Cand, Weak))
115  return TryCand.Reason != NoCand;
116  }
117 
118  // Avoid increasing the max pressure of the entire region.
119  if (DAG->isTrackingPressure() &&
120  tryPressure(TryCand.RPDelta.CurrentMax, Cand.RPDelta.CurrentMax, TryCand,
121  Cand, RegMax, TRI, DAG->MF))
122  return TryCand.Reason != NoCand;
123 
124  if (SameBoundary) {
125  // Avoid critical resource consumption and balance the schedule.
126  TryCand.initResourceDelta(DAG, SchedModel);
128  TryCand, Cand, ResourceReduce))
129  return TryCand.Reason != NoCand;
131  Cand.ResDelta.DemandedResources, TryCand, Cand,
133  return TryCand.Reason != NoCand;
134 
135  // Avoid serializing long latency dependence chains.
136  // For acyclic path limited loops, latency was already checked above.
138  !Rem.IsAcyclicLatencyLimited && tryLatency(TryCand, Cand, *Zone))
139  return TryCand.Reason != NoCand;
140 
141  // Fall through to original instruction order.
142  if ((Zone->isTop() && TryCand.SU->NodeNum < Cand.SU->NodeNum) ||
143  (!Zone->isTop() && TryCand.SU->NodeNum > Cand.SU->NodeNum)) {
144  TryCand.Reason = NodeOrder;
145  }
146  }
147 
148  // GenericScheduler::tryCandidate end
149 
150  // Add powerpc specific heuristic only when TryCand isn't selected or
151  // selected as node order.
152  if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
153  return true;
154 
155  // There are some benefits to schedule the ADDI before the load to hide the
156  // latency, as RA may create a true dependency between the load and addi.
157  if (SameBoundary) {
158  if (biasAddiLoadCandidate(Cand, TryCand, *Zone))
159  return TryCand.Reason != NoCand;
160  }
161 
162  return TryCand.Reason != NoCand;
163 }
164 
166  SchedCandidate &TryCand) const {
167  if (!EnableAddiHeuristic)
168  return false;
169 
170  if (isADDIInstr(TryCand) && !isADDIInstr(Cand)) {
171  TryCand.Reason = Stall;
172  return true;
173  }
174  return false;
175 }
176 
178  SchedCandidate &TryCand) {
179  // From PostGenericScheduler::tryCandidate
180 
181  // Initialize the candidate if needed.
182  if (!Cand.isValid()) {
183  TryCand.Reason = NodeOrder;
184  return true;
185  }
186 
187  // Prioritize instructions that read unbuffered resources by stall cycles.
188  if (tryLess(Top.getLatencyStallCycles(TryCand.SU),
189  Top.getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
190  return TryCand.Reason != NoCand;
191 
192  // Keep clustered nodes together.
193  if (tryGreater(TryCand.SU == DAG->getNextClusterSucc(),
194  Cand.SU == DAG->getNextClusterSucc(), TryCand, Cand, Cluster))
195  return TryCand.Reason != NoCand;
196 
197  // Avoid critical resource consumption and balance the schedule.
199  TryCand, Cand, ResourceReduce))
200  return TryCand.Reason != NoCand;
202  Cand.ResDelta.DemandedResources, TryCand, Cand,
204  return TryCand.Reason != NoCand;
205 
206  // Avoid serializing long latency dependence chains.
207  if (Cand.Policy.ReduceLatency && tryLatency(TryCand, Cand, Top)) {
208  return TryCand.Reason != NoCand;
209  }
210 
211  // Fall through to original instruction order.
212  if (TryCand.SU->NodeNum < Cand.SU->NodeNum)
213  TryCand.Reason = NodeOrder;
214 
215  // PostGenericScheduler::tryCandidate end
216 
217  // Add powerpc post ra specific heuristic only when TryCand isn't selected or
218  // selected as node order.
219  if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
220  return true;
221 
222  // There are some benefits to schedule the ADDI as early as possible post ra
223  // to avoid stalled by vector instructions which take up all the hw units.
224  // And ADDI is usually used to post inc the loop indvar, which matters the
225  // performance.
226  if (biasAddiCandidate(Cand, TryCand))
227  return TryCand.Reason != NoCand;
228 
229  return TryCand.Reason != NoCand;
230 }
231 
233  // Custom PPC PostRA specific behavior here.
235 }
236 
238  // Custom PPC PostRA specific behavior here.
240 }
241 
243  // Custom PPC PostRA specific initialization here.
245 }
246 
248  // Custom PPC PostRA specific scheduling here.
249  return PostGenericScheduler::pickNode(IsTopNode);
250 }
251 
llvm::GenericSchedulerBase::SchedResourceDelta::DemandedResources
unsigned DemandedResources
Definition: MachineScheduler.h:845
llvm::GenericSchedulerBase::Weak
@ Weak
Definition: MachineScheduler.h:813
llvm::GenericSchedulerBase::TRI
const TargetRegisterInfo * TRI
Definition: MachineScheduler.h:909
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::GenericSchedulerBase::NodeOrder
@ NodeOrder
Definition: MachineScheduler.h:815
llvm::PPCPostRASchedStrategy::initialize
void initialize(ScheduleDAGMI *Dag) override
Initialize the strategy after building the DAG for a new region.
Definition: PPCMachineScheduler.cpp:242
llvm::GenericSchedulerBase::Cluster
@ Cluster
Definition: MachineScheduler.h:813
llvm::GenericSchedulerBase::Stall
@ Stall
Definition: MachineScheduler.h:813
llvm::GenericSchedulerBase::SchedModel
const TargetSchedModel * SchedModel
Definition: MachineScheduler.h:908
llvm::tryGreater
bool tryGreater(int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason)
Definition: MachineScheduler.cpp:2838
llvm::GenericSchedulerBase::SchedCandidate::RPDelta
RegPressureDelta RPDelta
Definition: MachineScheduler.h:873
llvm::PostGenericScheduler::initialize
void initialize(ScheduleDAGMI *Dag) override
Initialize the strategy after building the DAG for a new region.
Definition: MachineScheduler.cpp:3512
llvm::GenericSchedulerBase::RegCritical
@ RegCritical
Definition: MachineScheduler.h:813
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::GenericSchedulerBase::SchedCandidate::Reason
CandReason Reason
Definition: MachineScheduler.h:867
llvm::PPCPostRASchedStrategy::pickNode
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule.
Definition: PPCMachineScheduler.cpp:247
llvm::GenericSchedulerBase::ResourceDemand
@ ResourceDemand
Definition: MachineScheduler.h:814
PPCMCTargetDesc.h
PPCMachineScheduler.h
llvm::PPCPreRASchedStrategy::tryCandidate
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const override
Apply a set of heuristics to a new candidate.
Definition: PPCMachineScheduler.cpp:49
llvm::tgtok::Dag
@ Dag
Definition: TGLexer.h:50
llvm::SchedBoundary::isTop
bool isTop() const
Definition: MachineScheduler.h:702
llvm::RegPressureDelta::CurrentMax
PressureChange CurrentMax
Definition: RegisterPressure.h:242
llvm::tryLatency
bool tryLatency(GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, SchedBoundary &Zone)
Definition: MachineScheduler.cpp:2854
llvm::SUnit::NodeNum
unsigned NodeNum
Entry # of node in the node vector.
Definition: ScheduleDAG.h:264
llvm::SchedRemainder::IsAcyclicLatencyLimited
bool IsAcyclicLatencyLimited
Definition: MachineScheduler.h:587
llvm::GenericSchedulerBase::RegMax
@ RegMax
Definition: MachineScheduler.h:814
llvm::MachineSchedPolicy::DisableLatencyHeuristic
bool DisableLatencyHeuristic
Definition: MachineScheduler.h:188
isADDIInstr
static bool isADDIInstr(const GenericScheduler::SchedCandidate &Cand)
Definition: PPCMachineScheduler.cpp:24
llvm::RegPressureDelta::Excess
PressureChange Excess
Definition: RegisterPressure.h:240
DisableAddiLoadHeuristic
static cl::opt< bool > DisableAddiLoadHeuristic("disable-ppc-sched-addi-load", cl::desc("Disable scheduling addi instruction before" "load for ppc"), cl::Hidden)
llvm::PostGenericScheduler::Top
SchedBoundary Top
Definition: MachineScheduler.h:1036
llvm::PPCPostRASchedStrategy::enterMBB
void enterMBB(MachineBasicBlock *MBB) override
Tell the strategy that MBB is about to be processed.
Definition: PPCMachineScheduler.cpp:232
llvm::GenericSchedulerBase::SchedCandidate::SU
SUnit * SU
Definition: MachineScheduler.h:864
llvm::GenericScheduler::RegionPolicy
MachineSchedPolicy RegionPolicy
Definition: MachineScheduler.h:998
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::GenericSchedulerBase::Rem
SchedRemainder Rem
Definition: MachineScheduler.h:911
llvm::PPCPostRASchedStrategy::leaveMBB
void leaveMBB() override
Tell the strategy that current MBB is done.
Definition: PPCMachineScheduler.cpp:237
llvm::tryLess
bool tryLess(int TryVal, int CandVal, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason)
Return true if this heuristic determines order.
Definition: MachineScheduler.cpp:2822
llvm::cl::opt< bool >
llvm::GenericSchedulerBase::SchedCandidate
Store the state used by GenericScheduler heuristics, required for the lifetime of one invocation of p...
Definition: MachineScheduler.h:860
llvm::GenericSchedulerBase::NoCand
@ NoCand
Definition: MachineScheduler.h:813
llvm::MachineSchedStrategy::enterMBB
virtual void enterMBB(MachineBasicBlock *MBB)
Tell the strategy that MBB is about to be processed.
Definition: MachineScheduler.h:232
llvm::tryPressure
bool tryPressure(const PressureChange &TryP, const PressureChange &CandP, GenericSchedulerBase::SchedCandidate &TryCand, GenericSchedulerBase::SchedCandidate &Cand, GenericSchedulerBase::CandReason Reason, const TargetRegisterInfo *TRI, const MachineFunction &MF)
Definition: MachineScheduler.cpp:3047
llvm::SchedBoundary::getLatencyStallCycles
unsigned getLatencyStallCycles(SUnit *SU)
Get the difference between the given SUnit's ready time and the current cycle.
Definition: MachineScheduler.cpp:2073
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::SchedBoundary::getCurrMOps
unsigned getCurrMOps() const
Micro-ops issued in the current cycle.
Definition: MachineScheduler.h:710
llvm::RegPressureDelta::CriticalMax
PressureChange CriticalMax
Definition: RegisterPressure.h:241
llvm::GenericSchedulerBase::SchedCandidate::Policy
CandPolicy Policy
Definition: MachineScheduler.h:861
llvm::GenericSchedulerBase::SchedResourceDelta::CritResources
unsigned CritResources
Definition: MachineScheduler.h:842
llvm::PostGenericScheduler::DAG
ScheduleDAGMI * DAG
Definition: MachineScheduler.h:1035
llvm::ScheduleDAGMI
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
Definition: MachineScheduler.h:266
llvm::GenericScheduler::DAG
ScheduleDAGMILive * DAG
Definition: MachineScheduler.h:996
llvm::ScheduleDAG::MF
MachineFunction & MF
Machine function.
Definition: ScheduleDAG.h:560
llvm::biasPhysReg
int biasPhysReg(const SUnit *SU, bool isTop)
Minimize physical register live ranges.
Definition: MachineScheduler.cpp:3097
llvm::PPCPostRASchedStrategy::tryCandidate
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand) override
Apply a set of heuristics to a new candidate for PostRA scheduling.
Definition: PPCMachineScheduler.cpp:177
llvm::GenericSchedulerBase::SchedCandidate::ResDelta
SchedResourceDelta ResDelta
Definition: MachineScheduler.h:876
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
llvm::GenericSchedulerBase::SchedCandidate::initResourceDelta
void initResourceDelta(const ScheduleDAGMI *DAG, const TargetSchedModel *SchedModel)
Definition: MachineScheduler.cpp:2622
llvm::MachineSchedStrategy::leaveMBB
virtual void leaveMBB()
Tell the strategy that current MBB is done.
Definition: MachineScheduler.h:235
llvm::GenericSchedulerBase::CandPolicy::ReduceLatency
bool ReduceLatency
Definition: MachineScheduler.h:823
llvm::GenericSchedulerBase::RegExcess
@ RegExcess
Definition: MachineScheduler.h:813
llvm::GenericSchedulerBase::SchedCandidate::AtTop
bool AtTop
Definition: MachineScheduler.h:870
llvm::ScheduleDAGMI::getNextClusterPred
const SUnit * getNextClusterPred() const
Definition: MachineScheduler.h:345
llvm::ScheduleDAGMI::getNextClusterSucc
const SUnit * getNextClusterSucc() const
Definition: MachineScheduler.h:347
llvm::ScheduleDAGMILive::isTrackingPressure
bool isTrackingPressure() const
Return true if register pressure tracking is enabled.
Definition: MachineScheduler.h:440
llvm::SchedBoundary
Each Scheduling boundary is associated with ready queues.
Definition: MachineScheduler.h:608
llvm::PostGenericScheduler::pickNode
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule.
Definition: MachineScheduler.cpp:3607
llvm::GenericSchedulerBase::ResourceReduce
@ ResourceReduce
Definition: MachineScheduler.h:814
EnableAddiHeuristic
static cl::opt< bool > EnableAddiHeuristic("ppc-postra-bias-addi", cl::desc("Enable scheduling addi instruction as early" "as possible post ra"), cl::Hidden, cl::init(true))
llvm::SUnit
Scheduling unit. This is a node in the scheduling DAG.
Definition: ScheduleDAG.h:242
llvm::getWeakLeft
unsigned getWeakLeft(const SUnit *SU, bool isTop)
Definition: MachineScheduler.cpp:3086
llvm::cl::desc
Definition: CommandLine.h:412
llvm::GenericSchedulerBase::SchedCandidate::isValid
bool isValid() const
Definition: MachineScheduler.h:890
llvm::PPCPostRASchedStrategy::biasAddiCandidate
bool biasAddiCandidate(SchedCandidate &Cand, SchedCandidate &TryCand) const
Definition: PPCMachineScheduler.cpp:165
llvm::GenericSchedulerBase::PhysReg
@ PhysReg
Definition: MachineScheduler.h:813