1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

[SystemZ] Improved debug dumping during post-RA scheduling.

Review: Ulrich Weigand
llvm-svn: 326878
This commit is contained in:
Jonas Paulsson 2018-03-07 08:39:00 +00:00
parent c06f38fb25
commit 354266bbab
4 changed files with 102 additions and 70 deletions

View File

@ -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;

View File

@ -76,7 +76,7 @@ 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).
@ -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; }

View File

@ -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);

View File

@ -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;