Go to the documentation of this file.
33 #define DEBUG_TYPE "pre-RA-sched"
35 STATISTIC(NumNoops ,
"Number of noops inserted");
36 STATISTIC(NumStalls,
"Number of pipeline stalls");
57 std::vector<SUnit*> PendingQueue;
73 ~ScheduleDAGVLIW()
override {
75 delete AvailableQueue;
78 void Schedule()
override;
82 void releaseSuccessors(
SUnit *SU);
83 void scheduleNodeTopDown(
SUnit *SU,
unsigned CurCycle);
84 void listScheduleTopDown();
89 void ScheduleDAGVLIW::Schedule() {
91 <<
" '" <<
BB->getName() <<
"' **********\n");
98 listScheduleTopDown();
109 void ScheduleDAGVLIW::releaseSucc(
SUnit *SU,
const SDep &
D) {
110 SUnit *SuccSU =
D.getSUnit();
114 dbgs() <<
"*** Scheduling failed! ***\n";
116 dbgs() <<
" has been released too many times!\n";
120 assert(!
D.isWeak() &&
"unexpected artificial DAG edge");
129 PendingQueue.push_back(SuccSU);
133 void ScheduleDAGVLIW::releaseSuccessors(
SUnit *SU) {
137 "The list-td scheduler doesn't yet support physreg dependencies!");
139 releaseSucc(SU, Succ);
146 void ScheduleDAGVLIW::scheduleNodeTopDown(
SUnit *SU,
unsigned CurCycle) {
151 assert(CurCycle >= SU->
getDepth() &&
"Node scheduled above its depth!");
154 releaseSuccessors(SU);
161 void ScheduleDAGVLIW::listScheduleTopDown() {
162 unsigned CurCycle = 0;
165 releaseSuccessors(&EntrySU);
168 for (
SUnit &SU : SUnits) {
170 if (SU.
Preds.empty()) {
171 AvailableQueue->
push(&SU);
178 std::vector<SUnit*> NotReady;
180 while (!AvailableQueue->
empty() || !PendingQueue.empty()) {
183 for (
unsigned i = 0,
e = PendingQueue.size();
i !=
e; ++
i) {
184 if (PendingQueue[
i]->getDepth() == CurCycle) {
185 AvailableQueue->
push(PendingQueue[
i]);
186 PendingQueue[
i]->isAvailable =
true;
187 PendingQueue[
i] = PendingQueue.back();
188 PendingQueue.pop_back();
192 assert(PendingQueue[
i]->getDepth() > CurCycle &&
"Negative latency?");
198 if (AvailableQueue->
empty()) {
205 SUnit *FoundSUnit =
nullptr;
207 bool HasNoopHazards =
false;
208 while (!AvailableQueue->
empty()) {
209 SUnit *CurSUnit = AvailableQueue->
pop();
214 FoundSUnit = CurSUnit;
221 NotReady.push_back(CurSUnit);
225 if (!NotReady.empty()) {
232 scheduleNodeTopDown(FoundSUnit, CurCycle);
239 }
else if (!HasNoopHazards) {
259 VerifyScheduledSequence(
false);
virtual void scheduledNode(SUnit *)
As each node is scheduled, this method is invoked.
This is an optimization pass for GlobalISel generic memory operations.
ScheduleDAGSDNodes - A ScheduleDAG for scheduling SDNode-based DAGs.
virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const
Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...
bool isAvailable
True once available.
virtual const TargetInstrInfo * getInstrInfo() const
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
SmallVector< SDep, 4 > Succs
All sunit successors.
unsigned getDepth() const
Returns the depth of this node, which is the length of the maximum path up to any node which has no p...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned short Latency
Node latency.
void setDepthToAtLeast(unsigned NewDepth)
If NewDepth is greater than this node's depth value, sets it to be the new depth value.
virtual bool empty() const =0
STATISTIC(NumFunctions, "Total number of functions")
virtual void push(SUnit *U)=0
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
bool isScheduled
True once scheduled.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ScheduleDAGSDNodes * createVLIWDAGScheduler(SelectionDAGISel *IS, CodeGenOpt::Level OptLevel)
createVLIWDAGScheduler - Scheduler for VLIW targets.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
virtual void EmitInstruction(SUnit *)
EmitInstruction - This callback is invoked when an instruction is emitted, to advance the hazard stat...
bool isAssignedRegDep() const
Tests if this is a Data dependence that is associated with a register.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual void releaseState()=0
virtual void EmitNoop()
EmitNoop - This callback is invoked when a noop was added to the instruction stream.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
virtual void AdvanceCycle()
AdvanceCycle - This callback is invoked whenever the next top-down instruction to be scheduled cannot...
void push_all(const std::vector< SUnit * > &Nodes)
SmallVector< SDep, 4 > Preds
All sunit predecessors.
Scheduling unit. This is a node in the scheduling DAG.
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
This interface is used to plug different priorities computation algorithms into the list scheduler.
HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...
static RegisterScheduler VLIWScheduler("vliw-td", "VLIW scheduler", createVLIWDAGScheduler)
virtual HazardType getHazardType(SUnit *, int Stalls=0)
getHazardType - Return the hazard type of emitting this node.
virtual void initNodes(std::vector< SUnit > &SUnits)=0