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:
parent
c06f38fb25
commit
354266bbab
@ -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;
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user