Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
SystemZMachineScheduler.cpp
Go to the documentation of this file.
1//-- SystemZMachineScheduler.cpp - SystemZ Scheduler Interface -*- C++ -*---==//
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// -------------------------- Post RA scheduling ---------------------------- //
10// SystemZPostRASchedStrategy is a scheduling strategy which is plugged into
11// the MachineScheduler. It has a sorted Available set of SUs and a pickNode()
12// implementation that looks to optimize decoder grouping and balance the
13// usage of processor resources. Scheduler states are saved for the end
14// region of each MBB, so that a successor block can learn from it.
15//===----------------------------------------------------------------------===//
16
17#include "SystemZMachineScheduler.h"
18#include "llvm/CodeGen/MachineLoopInfo.h"
19
20using namespacellvm;
21
22#define DEBUG_TYPE "machine-scheduler"
23
24#ifndef NDEBUG
25// Print the set of SUs
26void SystemZPostRASchedStrategy::SUSet::
27dump(SystemZHazardRecognizer &HazardRec) const{
28dbgs() <<"{";
29for (auto &SU : *this) {
30 HazardRec.dumpSU(SU,dbgs());
31if (SU != *rbegin())
32dbgs() <<", ";
33 }
34dbgs() <<"}\n";
35}
36#endif
37
38// Try to find a single predecessor that would be interesting for the
39// scheduler in the top-most region of MBB.
40staticMachineBasicBlock *getSingleSchedPred(MachineBasicBlock *MBB,
41constMachineLoop *Loop) {
42MachineBasicBlock *PredMBB =nullptr;
43if (MBB->pred_size() == 1)
44 PredMBB = *MBB->pred_begin();
45
46// The loop header has two predecessors, return the latch, but not for a
47// single block loop.
48if (MBB->pred_size() == 2 &&Loop !=nullptr &&Loop->getHeader() ==MBB) {
49for (MachineBasicBlock *Pred :MBB->predecessors())
50if (Loop->contains(Pred))
51 PredMBB = (Pred ==MBB ? nullptr : Pred);
52 }
53
54assert ((PredMBB ==nullptr || !Loop ||Loop->contains(PredMBB))
55 &&"Loop MBB should not consider predecessor outside of loop.");
56
57return PredMBB;
58}
59
60void SystemZPostRASchedStrategy::
61advanceTo(MachineBasicBlock::iterator NextBegin) {
62MachineBasicBlock::iterator LastEmittedMI = HazardRec->getLastEmittedMI();
63MachineBasicBlock::iteratorI =
64 ((LastEmittedMI !=nullptr && LastEmittedMI->getParent() == MBB) ?
65 std::next(LastEmittedMI) : MBB->begin());
66
67for (;I != NextBegin; ++I) {
68if (I->isPosition() ||I->isDebugInstr())
69continue;
70 HazardRec->emitInstruction(&*I);
71 }
72}
73
74voidSystemZPostRASchedStrategy::initialize(ScheduleDAGMI *dag) {
75 Available.clear();// -misched-cutoff.
76LLVM_DEBUG(HazardRec->dumpState(););
77}
78
79voidSystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) {
80assert ((SchedStates.find(NextMBB) == SchedStates.end()) &&
81"Entering MBB twice?");
82LLVM_DEBUG(dbgs() <<"** Entering " <<printMBBReference(*NextMBB));
83
84 MBB = NextMBB;
85
86 /// Create a HazardRec for MBB, save it in SchedStates and set HazardRec to
87 /// point to it.
88 HazardRec = SchedStates[MBB] =newSystemZHazardRecognizer(TII, &SchedModel);
89LLVM_DEBUG(constMachineLoop *Loop = MLI->getLoopFor(MBB);
90if (Loop &&Loop->getHeader() == MBB)dbgs() <<" (Loop header)";
91dbgs() <<":\n";);
92
93// Try to take over the state from a single predecessor, if it has been
94// scheduled. If this is not possible, we are done.
95MachineBasicBlock *SinglePredMBB =
96getSingleSchedPred(MBB, MLI->getLoopFor(MBB));
97if (SinglePredMBB ==nullptr ||
98 SchedStates.find(SinglePredMBB) == SchedStates.end())
99return;
100
101LLVM_DEBUG(dbgs() <<"** Continued scheduling from "
102 <<printMBBReference(*SinglePredMBB) <<"\n";);
103
104 HazardRec->copyState(SchedStates[SinglePredMBB]);
105LLVM_DEBUG(HazardRec->dumpState(););
106
107// Emit incoming terminator(s). Be optimistic and assume that branch
108// prediction will generally do "the right thing".
109for (MachineInstr &MI : SinglePredMBB->terminators()) {
110LLVM_DEBUG(dbgs() <<"** Emitting incoming branch: ";MI.dump(););
111bool TakenBranch = (MI.isBranch() &&
112 (TII->getBranchInfo(MI).isIndirect() ||
113 TII->getBranchInfo(MI).getMBBTarget() == MBB));
114 HazardRec->emitInstruction(&MI, TakenBranch);
115if (TakenBranch)
116break;
117 }
118}
119
120voidSystemZPostRASchedStrategy::leaveMBB() {
121LLVM_DEBUG(dbgs() <<"** Leaving " <<printMBBReference(*MBB) <<"\n";);
122
123// Advance to first terminator. The successor block will handle terminators
124// dependent on CFG layout (T/NT branch etc).
125 advanceTo(MBB->getFirstTerminator());
126}
127
128SystemZPostRASchedStrategy::
129SystemZPostRASchedStrategy(constMachineSchedContext *C)
130 : MLI(C->MLI),
131TII(static_cast<constSystemZInstrInfo *>
132 (C->MF->getSubtarget().getInstrInfo())),
133MBB(nullptr), HazardRec(nullptr) {
134constTargetSubtargetInfo *ST = &C->MF->getSubtarget();
135 SchedModel.init(ST);
136}
137
138SystemZPostRASchedStrategy::~SystemZPostRASchedStrategy() {
139// Delete hazard recognizers kept around for each MBB.
140for (autoI : SchedStates) {
141SystemZHazardRecognizer *hazrec =I.second;
142delete hazrec;
143 }
144}
145
146voidSystemZPostRASchedStrategy::initPolicy(MachineBasicBlock::iterator Begin,
147MachineBasicBlock::iteratorEnd,
148unsigned NumRegionInstrs) {
149// Don't emit the terminators.
150if (Begin->isTerminator())
151return;
152
153// Emit any instructions before start of region.
154 advanceTo(Begin);
155}
156
157// Pick the next node to schedule.
158SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) {
159// Only scheduling top-down.
160 IsTopNode =true;
161
162if (Available.empty())
163returnnullptr;
164
165// If only one choice, return it.
166if (Available.size() == 1) {
167LLVM_DEBUG(dbgs() <<"** Only one: ";
168 HazardRec->dumpSU(*Available.begin(),dbgs());dbgs() <<"\n";);
169return *Available.begin();
170 }
171
172// All nodes that are possible to schedule are stored in the Available set.
173LLVM_DEBUG(dbgs() <<"** Available: "; Available.dump(*HazardRec););
174
175 Candidate Best;
176for (auto *SU : Available) {
177
178// SU is the next candidate to be compared against current Best.
179 Candidate c(SU, *HazardRec);
180
181// Remeber which SU is the best candidate.
182if (Best.SU ==nullptr || c < Best) {
183 Best = c;
184LLVM_DEBUG(dbgs() <<"** Best so far: ";);
185 }else
186LLVM_DEBUG(dbgs() <<"** Tried : ";);
187LLVM_DEBUG(HazardRec->dumpSU(c.SU,dbgs()); c.dumpCosts();
188dbgs() <<" Height:" << c.SU->getHeight();dbgs() <<"\n";);
189
190// Once we know we have seen all SUs that affect grouping or use unbuffered
191// resources, we can stop iterating if Best looks good.
192if (!SU->isScheduleHigh && Best.noCost())
193break;
194 }
195
196assert (Best.SU !=nullptr);
197return Best.SU;
198}
199
200SystemZPostRASchedStrategy::Candidate::
201Candidate(SUnit *SU_,SystemZHazardRecognizer &HazardRec) : Candidate() {
202 SU = SU_;
203
204// Check the grouping cost. For a node that must begin / end a
205// group, it is positive if it would do so prematurely, or negative
206// if it would fit naturally into the schedule.
207 GroupingCost = HazardRec.groupingCost(SU);
208
209// Check the resources cost for this SU.
210 ResourcesCost = HazardRec.resourcesCost(SU);
211}
212
213bool SystemZPostRASchedStrategy::Candidate::
214operator<(const Candidate &other) {
215
216// Check decoder grouping.
217if (GroupingCost < other.GroupingCost)
218returntrue;
219if (GroupingCost > other.GroupingCost)
220returnfalse;
221
222// Compare the use of resources.
223if (ResourcesCost < other.ResourcesCost)
224returntrue;
225if (ResourcesCost > other.ResourcesCost)
226returnfalse;
227
228// Higher SU is otherwise generally better.
229if (SU->getHeight() > other.SU->getHeight())
230returntrue;
231if (SU->getHeight() < other.SU->getHeight())
232returnfalse;
233
234// If all same, fall back to original order.
235if (SU->NodeNum < other.SU->NodeNum)
236returntrue;
237
238returnfalse;
239}
240
241voidSystemZPostRASchedStrategy::schedNode(SUnit *SU,bool IsTopNode) {
242LLVM_DEBUG(dbgs() <<"** Scheduling SU(" << SU->NodeNum <<") ";
243if (Available.size() == 1)dbgs() <<"(only one) ";
244 Candidate c(SU, *HazardRec); c.dumpCosts();dbgs() <<"\n";);
245
246// Remove SU from Available set and update HazardRec.
247 Available.erase(SU);
248 HazardRec->EmitInstruction(SU);
249}
250
251voidSystemZPostRASchedStrategy::releaseTopNode(SUnit *SU) {
252// Set isScheduleHigh flag on all SUs that we want to consider first in
253// pickNode().
254constMCSchedClassDesc *SC = HazardRec->getSchedClass(SU);
255bool AffectsGrouping = (SC->isValid() && (SC->BeginGroup || SC->EndGroup));
256 SU->isScheduleHigh = (AffectsGrouping || SU->isUnbuffered);
257
258// Put all released SUs in the Available set.
259 Available.insert(SU);
260}
const
aarch64 promote const
Definition:AArch64PromoteConstant.cpp:230
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
End
bool End
Definition:ELF_riscv.cpp:480
TII
const HexagonInstrInfo * TII
Definition:HexagonCopyToCombine.cpp:125
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
I
#define I(x, y, z)
Definition:MD5.cpp:58
MachineLoopInfo.h
if
if(PassOpts->AAPipeline)
Definition:PassBuilderBindings.cpp:64
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
getSingleSchedPred
static MachineBasicBlock * getSingleSchedPred(MachineBasicBlock *MBB, const MachineLoop *Loop)
Definition:SystemZMachineScheduler.cpp:40
SystemZMachineScheduler.h
llvm::LoopBase::contains
bool contains(const LoopT *L) const
Return true if the specified loop is contained within in this loop.
Definition:GenericLoopInfo.h:124
llvm::LoopBase::getHeader
BlockT * getHeader() const
Definition:GenericLoopInfo.h:90
llvm::LoopInfoBase::getLoopFor
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
Definition:GenericLoopInfo.h:606
llvm::Loop
Represents a single loop in the control flow graph.
Definition:LoopInfo.h:39
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::pred_size
unsigned pred_size() const
Definition:MachineBasicBlock.h:417
llvm::MachineBasicBlock::getFirstTerminator
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Definition:MachineBasicBlock.cpp:244
llvm::MachineBasicBlock::begin
iterator begin()
Definition:MachineBasicBlock.h:355
llvm::MachineBasicBlock::pred_begin
pred_iterator pred_begin()
Definition:MachineBasicBlock.h:405
llvm::MachineBasicBlock::predecessors
iterator_range< pred_iterator > predecessors()
Definition:MachineBasicBlock.h:438
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineLoop
Definition:MachineLoopInfo.h:46
llvm::Pass::dump
void dump() const
Definition:Pass.cpp:136
llvm::SUnit
Scheduling unit. This is a node in the scheduling DAG.
Definition:ScheduleDAG.h:242
llvm::SUnit::NodeNum
unsigned NodeNum
Entry # of node in the node vector.
Definition:ScheduleDAG.h:270
llvm::SUnit::isUnbuffered
bool isUnbuffered
Uses an unbuffered resource.
Definition:ScheduleDAG.h:300
llvm::SUnit::isScheduleHigh
bool isScheduleHigh
True if preferable to schedule high.
Definition:ScheduleDAG.h:297
llvm::ScheduleDAGMI
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
Definition:MachineScheduler.h:285
llvm::SystemZHazardRecognizer
SystemZHazardRecognizer maintains the state for one MBB during scheduling.
Definition:SystemZHazardRecognizer.h:45
llvm::SystemZHazardRecognizer::groupingCost
int groupingCost(SUnit *SU) const
Return the cost of decoder grouping for SU.
Definition:SystemZHazardRecognizer.cpp:340
llvm::SystemZHazardRecognizer::emitInstruction
void emitInstruction(MachineInstr *MI, bool TakenBranch=false)
Wrap a non-scheduled instruction in an SU and emit it.
Definition:SystemZHazardRecognizer.cpp:410
llvm::SystemZHazardRecognizer::getSchedClass
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
Definition:SystemZHazardRecognizer.h:121
llvm::SystemZHazardRecognizer::copyState
void copyState(SystemZHazardRecognizer *Incoming)
Copy counters from end of single predecessor.
Definition:SystemZHazardRecognizer.cpp:451
llvm::SystemZHazardRecognizer::dumpSU
void dumpSU(SUnit *SU, raw_ostream &OS) const
Definition:SystemZHazardRecognizer.cpp:167
llvm::SystemZHazardRecognizer::getLastEmittedMI
MachineBasicBlock::iterator getLastEmittedMI()
Definition:SystemZHazardRecognizer.h:153
llvm::SystemZHazardRecognizer::resourcesCost
int resourcesCost(SUnit *SU)
Return the cost of SU in regards to processor resources usage.
Definition:SystemZHazardRecognizer.cpp:387
llvm::SystemZHazardRecognizer::dumpState
void dumpState() const
Definition:SystemZHazardRecognizer.cpp:248
llvm::SystemZHazardRecognizer::EmitInstruction
void EmitInstruction(SUnit *SU) override
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
Definition:SystemZHazardRecognizer.cpp:271
llvm::SystemZII::Branch::getMBBTarget
MachineBasicBlock * getMBBTarget()
Definition:SystemZInstrInfo.h:142
llvm::SystemZII::Branch::isIndirect
bool isIndirect()
Definition:SystemZInstrInfo.h:140
llvm::SystemZInstrInfo
Definition:SystemZInstrInfo.h:185
llvm::SystemZInstrInfo::getBranchInfo
SystemZII::Branch getBranchInfo(const MachineInstr &MI) const
Definition:SystemZInstrInfo.cpp:1804
llvm::SystemZPostRASchedStrategy::pickNode
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule, or return NULL.
Definition:SystemZMachineScheduler.cpp:158
llvm::SystemZPostRASchedStrategy::leaveMBB
void leaveMBB() override
Tell the strategy that current MBB is done.
Definition:SystemZMachineScheduler.cpp:120
llvm::SystemZPostRASchedStrategy::initPolicy
void initPolicy(MachineBasicBlock::iterator Begin, MachineBasicBlock::iterator End, unsigned NumRegionInstrs) override
Called for a region before scheduling.
Definition:SystemZMachineScheduler.cpp:146
llvm::SystemZPostRASchedStrategy::schedNode
void schedNode(SUnit *SU, bool IsTopNode) override
ScheduleDAGMI has scheduled an instruction - tell HazardRec about it.
Definition:SystemZMachineScheduler.cpp:241
llvm::SystemZPostRASchedStrategy::initialize
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
Definition:SystemZMachineScheduler.cpp:74
llvm::SystemZPostRASchedStrategy::enterMBB
void enterMBB(MachineBasicBlock *NextMBB) override
Tell the strategy that MBB is about to be processed.
Definition:SystemZMachineScheduler.cpp:79
llvm::SystemZPostRASchedStrategy::~SystemZPostRASchedStrategy
virtual ~SystemZPostRASchedStrategy()
Definition:SystemZMachineScheduler.cpp:138
llvm::SystemZPostRASchedStrategy::SystemZPostRASchedStrategy
SystemZPostRASchedStrategy(const MachineSchedContext *C)
Definition:SystemZMachineScheduler.cpp:129
llvm::SystemZPostRASchedStrategy::releaseTopNode
void releaseTopNode(SUnit *SU) override
SU has had all predecessor dependencies resolved.
Definition:SystemZMachineScheduler.cpp:251
llvm::TargetSchedModel::init
void init(const TargetSubtargetInfo *TSInfo)
Initialize the machine model for instruction scheduling.
Definition:TargetSchedule.cpp:50
llvm::TargetSubtargetInfo
TargetSubtargetInfo - Generic base class for all target subtargets.
Definition:TargetSubtargetInfo.h:63
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::printMBBReference
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
Definition:MachineBasicBlock.cpp:122
llvm::MCSchedClassDesc
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition:MCSchedule.h:121
llvm::MachineSchedContext
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
Definition:MachineScheduler.h:136

Generated on Fri Jul 18 2025 14:37:31 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp