LLVM  13.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;
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;
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;
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;
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;
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;
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;
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;
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;
123 
124  if (SameBoundary) {
125  // Avoid critical resource consumption and balance the schedule.
126  TryCand.initResourceDelta(DAG, SchedModel);
128  TryCand, Cand, ResourceReduce))
129  return;
131  Cand.ResDelta.DemandedResources, TryCand, Cand,
133  return;
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;
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;
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;
160  }
161 }
162 
164  SchedCandidate &TryCand) const {
165  if (!EnableAddiHeuristic)
166  return false;
167 
168  if (isADDIInstr(TryCand) && !isADDIInstr(Cand)) {
169  TryCand.Reason = Stall;
170  return true;
171  }
172  return false;
173 }
174 
176  SchedCandidate &TryCand) {
177  // From PostGenericScheduler::tryCandidate
178 
179  // Initialize the candidate if needed.
180  if (!Cand.isValid()) {
181  TryCand.Reason = NodeOrder;
182  return;
183  }
184 
185  // Prioritize instructions that read unbuffered resources by stall cycles.
186  if (tryLess(Top.getLatencyStallCycles(TryCand.SU),
187  Top.getLatencyStallCycles(Cand.SU), TryCand, Cand, Stall))
188  return;
189 
190  // Keep clustered nodes together.
191  if (tryGreater(TryCand.SU == DAG->getNextClusterSucc(),
192  Cand.SU == DAG->getNextClusterSucc(), TryCand, Cand, Cluster))
193  return;
194 
195  // Avoid critical resource consumption and balance the schedule.
197  TryCand, Cand, ResourceReduce))
198  return;
200  Cand.ResDelta.DemandedResources, TryCand, Cand,
202  return;
203 
204  // Avoid serializing long latency dependence chains.
205  if (Cand.Policy.ReduceLatency && tryLatency(TryCand, Cand, Top)) {
206  return;
207  }
208 
209  // Fall through to original instruction order.
210  if (TryCand.SU->NodeNum < Cand.SU->NodeNum)
211  TryCand.Reason = NodeOrder;
212 
213  // PostGenericScheduler::tryCandidate end
214 
215  // Add powerpc post ra specific heuristic only when TryCand isn't selected or
216  // selected as node order.
217  if (TryCand.Reason != NodeOrder && TryCand.Reason != NoCand)
218  return;
219 
220  // There are some benefits to schedule the ADDI as early as possible post ra
221  // to avoid stalled by vector instructions which take up all the hw units.
222  // And ADDI is usually used to post inc the loop indvar, which matters the
223  // performance.
224  if (biasAddiCandidate(Cand, TryCand))
225  return;
226 }
227 
229  // Custom PPC PostRA specific behavior here.
231 }
232 
234  // Custom PPC PostRA specific behavior here.
236 }
237 
239  // Custom PPC PostRA specific initialization here.
241 }
242 
244  // Custom PPC PostRA specific scheduling here.
245  return PostGenericScheduler::pickNode(IsTopNode);
246 }
247 
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
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:238
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:2837
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:3509
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:243
llvm::GenericSchedulerBase::ResourceDemand
@ ResourceDemand
Definition: MachineScheduler.h:814
PPCMCTargetDesc.h
PPCMachineScheduler.h
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:2853
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:228
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:233
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:2821
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:3046
llvm::SchedBoundary::getLatencyStallCycles
unsigned getLatencyStallCycles(SUnit *SU)
Get the difference between the given SUnit's ready time and the current cycle.
Definition: MachineScheduler.cpp:2074
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
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::PPCPostRASchedStrategy::tryCandidate
void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand) override
Apply a set of heuristics to a new candidate for PostRA scheduling.
Definition: PPCMachineScheduler.cpp:175
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:3096
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:2623
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::PPCPreRASchedStrategy::tryCandidate
void tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const override
Apply a set of heuristics to a new candidate.
Definition: PPCMachineScheduler.cpp:49
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:3600
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:3085
llvm::cl::desc
Definition: CommandLine.h:414
llvm::GenericSchedulerBase::SchedCandidate::isValid
bool isValid() const
Definition: MachineScheduler.h:890
llvm::PPCPostRASchedStrategy::biasAddiCandidate
bool biasAddiCandidate(SchedCandidate &Cand, SchedCandidate &TryCand) const
Definition: PPCMachineScheduler.cpp:163
llvm::GenericSchedulerBase::PhysReg
@ PhysReg
Definition: MachineScheduler.h:813