diff --git a/lib/Target/SystemZ/SystemZHazardRecognizer.cpp b/lib/Target/SystemZ/SystemZHazardRecognizer.cpp index f3721602276..d29711ef65e 100644 --- a/lib/Target/SystemZ/SystemZHazardRecognizer.cpp +++ b/lib/Target/SystemZ/SystemZHazardRecognizer.cpp @@ -59,7 +59,7 @@ getNumDecoderSlots(SUnit *SU) const { return 1; // Normal instruction } -unsigned SystemZHazardRecognizer::getCurrCycleIdx() { +unsigned SystemZHazardRecognizer::getCurrCycleIdx() const { unsigned Idx = CurrGroupSize; if (GrpCount % 2) Idx += 3; @@ -100,30 +100,30 @@ SystemZHazardRecognizer::fitsIntoCurrentGroup(SUnit *SU) const { return true; } -void SystemZHazardRecognizer::nextGroup(bool DbgOutput) { - if (CurrGroupSize > 0) { - DEBUG(dumpCurrGroup("Completed decode group")); - DEBUG(CurGroupDbg = "";); +void SystemZHazardRecognizer::nextGroup() { + if (CurrGroupSize == 0) + return; - GrpCount++; + DEBUG(dumpCurrGroup("Completed decode group")); + DEBUG(CurGroupDbg = "";); - // Reset counter for next group. - CurrGroupSize = 0; + GrpCount++; - // Decrease counters for execution units by one. - for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i) - if (ProcResourceCounters[i] > 0) - ProcResourceCounters[i]--; + // Reset counter for next group. + CurrGroupSize = 0; - // Clear CriticalResourceIdx if it is now below the threshold. - if (CriticalResourceIdx != UINT_MAX && - (ProcResourceCounters[CriticalResourceIdx] <= - ProcResCostLim)) - CriticalResourceIdx = UINT_MAX; - } + // Decrease counters for execution units by one. + for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i) + if (ProcResourceCounters[i] > 0) + ProcResourceCounters[i]--; - DEBUG(if (DbgOutput) - dumpProcResourceCounters();); + // Clear CriticalResourceIdx if it is now below the threshold. + if (CriticalResourceIdx != UINT_MAX && + (ProcResourceCounters[CriticalResourceIdx] <= + ProcResCostLim)) + CriticalResourceIdx = UINT_MAX; + + DEBUG(dumpState();); } #ifndef NDEBUG // Debug output @@ -163,7 +163,7 @@ void SystemZHazardRecognizer::dumpSU(SUnit *SU, raw_ostream &OS) const { } void SystemZHazardRecognizer::dumpCurrGroup(std::string Msg) const { - dbgs() << "+++ " << Msg; + dbgs() << "++ " << Msg; dbgs() << ": "; if (CurGroupDbg.empty()) @@ -188,15 +188,28 @@ void SystemZHazardRecognizer::dumpProcResourceCounters() const { if (!any) return; - dbgs() << "+++ Resource counters:\n"; + dbgs() << "++ | Resource counters: "; for (unsigned i = 0; i < SchedModel->getNumProcResourceKinds(); ++i) - if (ProcResourceCounters[i] > 0) { - dbgs() << "+++ Extra schedule for execution unit " - << SchedModel->getProcResource(i)->Name - << ": " << ProcResourceCounters[i] << "\n"; - any = true; - } + if (ProcResourceCounters[i] > 0) + dbgs() << SchedModel->getProcResource(i)->Name + << ":" << ProcResourceCounters[i] << " "; + dbgs() << "\n"; + + if (CriticalResourceIdx != UINT_MAX) + dbgs() << "++ | Critical resource: " + << SchedModel->getProcResource(CriticalResourceIdx)->Name + << "\n"; } + +void SystemZHazardRecognizer::dumpState() const { + dumpCurrGroup("| Current decoder group"); + dbgs() << "++ | Current cycle index: " + << getCurrCycleIdx() << "\n"; + dumpProcResourceCounters(); + if (LastFPdOpCycleIdx != UINT_MAX) + dbgs() << "++ | Last FPd cycle index: " << LastFPdOpCycleIdx << "\n"; +} + #endif //NDEBUG void SystemZHazardRecognizer::clearProcResCounters() { @@ -213,25 +226,25 @@ static inline bool isBranchRetTrap(MachineInstr *MI) { void SystemZHazardRecognizer:: EmitInstruction(SUnit *SU) { const MCSchedClassDesc *SC = getSchedClass(SU); - DEBUG( dumpCurrGroup("Decode group before emission");); + DEBUG(dbgs() << "++ HazardRecognizer emitting "; dumpSU(SU, dbgs()); + dbgs() << "\n";); + DEBUG(dumpCurrGroup("Decode group before emission");); // If scheduling an SU that must begin a new decoder group, move on // to next group. if (!fitsIntoCurrentGroup(SU)) nextGroup(); - DEBUG( dbgs() << "+++ HazardRecognizer emitting "; dumpSU(SU, dbgs()); - dbgs() << "\n"; - raw_string_ostream cgd(CurGroupDbg); - if (CurGroupDbg.length()) - cgd << ", "; - dumpSU(SU, cgd);); + DEBUG(raw_string_ostream cgd(CurGroupDbg); + if (CurGroupDbg.length()) + cgd << ", "; + dumpSU(SU, cgd);); LastEmittedMI = SU->getInstr(); // After returning from a call, we don't know much about the state. if (SU->isCall) { - DEBUG (dbgs() << "+++ Clearing state after call.\n";); + DEBUG(dbgs() << "++ Clearing state after call.\n";); clearProcResCounters(); LastFPdOpCycleIdx = UINT_MAX; CurrGroupSize += getNumDecoderSlots(SU); @@ -256,9 +269,9 @@ EmitInstruction(SUnit *SU) { (PI->ProcResourceIdx != CriticalResourceIdx && CurrCounter > ProcResourceCounters[CriticalResourceIdx]))) { - DEBUG( dbgs() << "+++ New critical resource: " - << SchedModel->getProcResource(PI->ProcResourceIdx)->Name - << "\n";); + DEBUG(dbgs() << "++ New critical resource: " + << SchedModel->getProcResource(PI->ProcResourceIdx)->Name + << "\n";); CriticalResourceIdx = PI->ProcResourceIdx; } } @@ -266,8 +279,8 @@ EmitInstruction(SUnit *SU) { // Make note of an instruction that uses a blocking resource (FPd). if (SU->isUnbuffered) { LastFPdOpCycleIdx = getCurrCycleIdx(); - DEBUG (dbgs() << "+++ Last FPd cycle index: " - << LastFPdOpCycleIdx << "\n";); + DEBUG(dbgs() << "++ Last FPd cycle index: " + << LastFPdOpCycleIdx << "\n";); } bool GroupEndingBranch = @@ -376,7 +389,7 @@ void SystemZHazardRecognizer::emitInstruction(MachineInstr *MI, EmitInstruction(&SU); if (TakenBranch && CurrGroupSize > 0) - nextGroup(false /*DbgOutput*/); + nextGroup(); assert ((!MI->isTerminator() || isBranchRetTrap(MI)) && "Scheduler: unhandled terminator!"); @@ -386,7 +399,7 @@ void SystemZHazardRecognizer:: copyState(SystemZHazardRecognizer *Incoming) { // Current decoder group CurrGroupSize = Incoming->CurrGroupSize; - DEBUG (CurGroupDbg = Incoming->CurGroupDbg;); + DEBUG(CurGroupDbg = Incoming->CurGroupDbg;); // Processor resources ProcResourceCounters = Incoming->ProcResourceCounters; diff --git a/lib/Target/SystemZ/SystemZHazardRecognizer.h b/lib/Target/SystemZ/SystemZHazardRecognizer.h index 7e1b5fb2e4f..31cdf8cfed5 100644 --- a/lib/Target/SystemZ/SystemZHazardRecognizer.h +++ b/lib/Target/SystemZ/SystemZHazardRecognizer.h @@ -76,8 +76,8 @@ class SystemZHazardRecognizer : public ScheduleHazardRecognizer { /// Two decoder groups per cycle are formed (for z13), meaning 2x3 /// instructions. This function returns a number between 0 and 5, /// representing the current decoder slot of the current cycle. - unsigned getCurrCycleIdx(); - + unsigned getCurrCycleIdx() const; + /// LastFPdOpCycleIdx stores the numbeer returned by getCurrCycleIdx() /// when a stalling operation is scheduled (which uses the FPd resource). unsigned LastFPdOpCycleIdx; @@ -88,7 +88,7 @@ class SystemZHazardRecognizer : public ScheduleHazardRecognizer { unsigned getCurrGroupSize() {return CurrGroupSize;}; /// Start next decoder group. - void nextGroup(bool DbgOutput = true); + void nextGroup(); /// Clear all counters for processor resources. void clearProcResCounters(); @@ -145,6 +145,7 @@ public: void dumpSU(SUnit *SU, raw_ostream &OS) const; void dumpCurrGroup(std::string Msg = "") const; void dumpProcResourceCounters() const; + void dumpState() const; #endif MachineBasicBlock::iterator getLastEmittedMI() { return LastEmittedMI; } diff --git a/lib/Target/SystemZ/SystemZMachineScheduler.cpp b/lib/Target/SystemZ/SystemZMachineScheduler.cpp index 08eb73fc362..cee9d8cf5f9 100644 --- a/lib/Target/SystemZ/SystemZMachineScheduler.cpp +++ b/lib/Target/SystemZ/SystemZMachineScheduler.cpp @@ -71,19 +71,24 @@ advanceTo(MachineBasicBlock::iterator NextBegin) { } } +void SystemZPostRASchedStrategy::initialize(ScheduleDAGMI *dag) { + DEBUG(HazardRec->dumpState();); +} + void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) { assert ((SchedStates.find(NextMBB) == SchedStates.end()) && "Entering MBB twice?"); - DEBUG(dbgs() << "+++ Entering " << printMBBReference(*NextMBB)); + DEBUG(dbgs() << "** Entering " << printMBBReference(*NextMBB)); MBB = NextMBB; + /// Create a HazardRec for MBB, save it in SchedStates and set HazardRec to /// point to it. HazardRec = SchedStates[MBB] = new SystemZHazardRecognizer(TII, &SchedModel); - DEBUG (const MachineLoop *Loop = MLI->getLoopFor(MBB); - if(Loop && Loop->getHeader() == MBB) - dbgs() << " (Loop header)"; - dbgs() << ":\n";); + DEBUG(const MachineLoop *Loop = MLI->getLoopFor(MBB); + if(Loop && Loop->getHeader() == MBB) + dbgs() << " (Loop header)"; + dbgs() << ":\n";); // Try to take over the state from a single predecessor, if it has been // scheduled. If this is not possible, we are done. @@ -93,16 +98,17 @@ void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) { SchedStates.find(SinglePredMBB) == SchedStates.end()) return; - DEBUG(dbgs() << "+++ Continued scheduling from " - << printMBBReference(*SinglePredMBB) << "\n";); + DEBUG(dbgs() << "** Continued scheduling from " + << printMBBReference(*SinglePredMBB) << "\n";); HazardRec->copyState(SchedStates[SinglePredMBB]); + DEBUG(HazardRec->dumpState();); // Emit incoming terminator(s). Be optimistic and assume that branch // prediction will generally do "the right thing". for (MachineBasicBlock::iterator I = SinglePredMBB->getFirstTerminator(); I != SinglePredMBB->end(); I++) { - DEBUG (dbgs() << "+++ Emitting incoming branch: "; I->dump();); + DEBUG(dbgs() << "** Emitting incoming branch: "; I->dump();); bool TakenBranch = (I->isBranch() && (TII->getBranchInfo(*I).Target->isReg() || // Relative branch TII->getBranchInfo(*I).Target->getMBB() == MBB)); @@ -113,7 +119,7 @@ void SystemZPostRASchedStrategy::enterMBB(MachineBasicBlock *NextMBB) { } void SystemZPostRASchedStrategy::leaveMBB() { - DEBUG(dbgs() << "+++ Leaving " << printMBBReference(*MBB) << "\n";); + DEBUG(dbgs() << "** Leaving " << printMBBReference(*MBB) << "\n";); // Advance to first terminator. The successor block will handle terminators // dependent on CFG layout (T/NT branch etc). @@ -159,14 +165,14 @@ SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) { // If only one choice, return it. if (Available.size() == 1) { - DEBUG (dbgs() << "+++ Only one: "; - HazardRec->dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";); + DEBUG(dbgs() << "** Only one: "; + HazardRec->dumpSU(*Available.begin(), dbgs()); dbgs() << "\n";); return *Available.begin(); } // All nodes that are possible to schedule are stored by in the // Available set. - DEBUG(dbgs() << "+++ Available: "; Available.dump(*HazardRec);); + DEBUG(dbgs() << "** Available: "; Available.dump(*HazardRec);); Candidate Best; for (auto *SU : Available) { @@ -177,15 +183,13 @@ SUnit *SystemZPostRASchedStrategy::pickNode(bool &IsTopNode) { // Remeber which SU is the best candidate. if (Best.SU == nullptr || c < Best) { Best = c; - DEBUG(dbgs() << "+++ Best sofar: "; - HazardRec->dumpSU(Best.SU, dbgs()); - if (Best.GroupingCost != 0) - dbgs() << "\tGrouping cost:" << Best.GroupingCost; - if (Best.ResourcesCost != 0) - dbgs() << " Resource cost:" << Best.ResourcesCost; - dbgs() << " Height:" << Best.SU->getHeight(); - dbgs() << "\n";); - } + DEBUG(dbgs() << "** Best so far: ";); + } else + DEBUG(dbgs() << "** Tried : ";); + DEBUG(HazardRec->dumpSU(c.SU, dbgs()); + c.dumpCosts(); + dbgs() << " Height:" << c.SU->getHeight(); + dbgs() << "\n";); // Once we know we have seen all SUs that affect grouping or use unbuffered // resources, we can stop iterating if Best looks good. @@ -206,7 +210,7 @@ Candidate(SUnit *SU_, SystemZHazardRecognizer &HazardRec) : Candidate() { // if it would fit naturally into the schedule. GroupingCost = HazardRec.groupingCost(SU); - // Check the resources cost for this SU. + // Check the resources cost for this SU. ResourcesCost = HazardRec.resourcesCost(SU); } @@ -239,7 +243,12 @@ operator<(const Candidate &other) { } void SystemZPostRASchedStrategy::schedNode(SUnit *SU, bool IsTopNode) { - DEBUG(dbgs() << "+++ Scheduling SU(" << SU->NodeNum << ")\n";); + DEBUG(dbgs() << "** Scheduling SU(" << SU->NodeNum << ") "; + if (Available.size() == 1) + dbgs() << "(only one) "; + Candidate c(SU, *HazardRec); + c.dumpCosts(); + dbgs() << "\n";); // Remove SU from Available set and update HazardRec. Available.erase(SU); diff --git a/lib/Target/SystemZ/SystemZMachineScheduler.h b/lib/Target/SystemZ/SystemZMachineScheduler.h index de1bf4655c5..cb030482596 100644 --- a/lib/Target/SystemZ/SystemZMachineScheduler.h +++ b/lib/Target/SystemZ/SystemZMachineScheduler.h @@ -58,6 +58,15 @@ class SystemZPostRASchedStrategy : public MachineSchedStrategy { bool noCost() const { return (GroupingCost <= 0 && !ResourcesCost); } + +#ifndef NDEBUG + void dumpCosts() { + if (GroupingCost != 0) + dbgs() << " Grouping cost:" << GroupingCost; + if (ResourcesCost != 0) + dbgs() << " Resource cost:" << ResourcesCost; + } +#endif }; // A sorter for the Available set that makes sure that SUs are considered @@ -119,7 +128,7 @@ public: // transferrred over scheduling boundaries. bool doMBBSchedRegionsTopDown() const override { return true; } - void initialize(ScheduleDAGMI *dag) override {} + void initialize(ScheduleDAGMI *dag) override; /// Tell the strategy that MBB is about to be processed. void enterMBB(MachineBasicBlock *NextMBB) override;