forked from OSchip/llvm-project
Implement ComputeLatency for MachineInstr ScheduleDAGs. Factor
some of the latency computation logic out of the SDNode ScheduleDAG code into a TargetInstrItineraries helper method to help with this. llvm-svn: 59761
This commit is contained in:
parent
39acb29ff8
commit
7b7ca502fa
|
@ -53,6 +53,10 @@ namespace llvm {
|
|||
/// input.
|
||||
virtual void BuildSchedUnits();
|
||||
|
||||
/// ComputeLatency - Compute node latency.
|
||||
///
|
||||
virtual void ComputeLatency(SUnit *SU);
|
||||
|
||||
virtual MachineBasicBlock *EmitSchedule();
|
||||
|
||||
/// Schedule - Order nodes according to selected style, filling
|
||||
|
|
|
@ -73,6 +73,24 @@ struct InstrItineraryData {
|
|||
unsigned StageIdx = Itineratries[ItinClassIndx].Last;
|
||||
return Stages + StageIdx;
|
||||
}
|
||||
|
||||
/// getLatency - Return the scheduling latency of the given class. A
|
||||
/// simple latency value for an instruction is an over-simplification
|
||||
/// for some architectures, but it's a reasonable first approximation.
|
||||
///
|
||||
unsigned getLatency(unsigned ItinClassIndx) const {
|
||||
// If the target doesn't provide latency information, use a simple
|
||||
// non-zero default value for all instructions.
|
||||
if (isEmpty())
|
||||
return 1;
|
||||
|
||||
// Just sum the cycle count for each stage.
|
||||
unsigned Latency = 0;
|
||||
for (const InstrStage *IS = begin(ItinClassIndx), *E = end(ItinClassIndx);
|
||||
IS != E; ++IS)
|
||||
Latency += IS->Cycles;
|
||||
return Latency;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ void ScheduleDAGInstrs::BuildSchedUnits() {
|
|||
assert(TRI->isPhysicalRegister(Reg) && "Virtual register encountered!");
|
||||
std::vector<SUnit *> &UseList = Uses[Reg];
|
||||
SUnit *&Def = Defs[Reg];
|
||||
// Optionally add output and anti dependences
|
||||
// Optionally add output and anti dependences.
|
||||
if (Def && Def != SU)
|
||||
Def->addPred(SU, /*isCtrl=*/true, /*isSpecial=*/false,
|
||||
/*PhyReg=*/Reg, Cost);
|
||||
|
@ -102,6 +102,15 @@ void ScheduleDAGInstrs::BuildSchedUnits() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScheduleDAGInstrs::ComputeLatency(SUnit *SU) {
|
||||
const InstrItineraryData &InstrItins = TM.getInstrItineraryData();
|
||||
|
||||
// Compute the latency for the node. We use the sum of the latencies for
|
||||
// all nodes flagged together into this SUnit.
|
||||
SU->Latency =
|
||||
InstrItins.getLatency(SU->getInstr()->getDesc().getSchedClass());
|
||||
}
|
||||
|
||||
void ScheduleDAGInstrs::dumpNode(const SUnit *SU) const {
|
||||
SU->getInstr()->dump();
|
||||
}
|
||||
|
|
|
@ -193,15 +193,17 @@ void ScheduleDAGSDNodes::ComputeLatency(SUnit *SU) {
|
|||
}
|
||||
|
||||
SU->Latency = 0;
|
||||
for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode()) {
|
||||
bool SawMachineOpcode = false;
|
||||
for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
|
||||
if (N->isMachineOpcode()) {
|
||||
unsigned SchedClass = TII->get(N->getMachineOpcode()).getSchedClass();
|
||||
const InstrStage *S = InstrItins.begin(SchedClass);
|
||||
const InstrStage *E = InstrItins.end(SchedClass);
|
||||
for (; S != E; ++S)
|
||||
SU->Latency += S->Cycles;
|
||||
SawMachineOpcode = true;
|
||||
SU->Latency +=
|
||||
InstrItins.getLatency(TII->get(N->getMachineOpcode()).getSchedClass());
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that CopyToReg and similar nodes have a non-zero latency.
|
||||
if (!SawMachineOpcode)
|
||||
SU->Latency = 1;
|
||||
}
|
||||
|
||||
/// CountResults - The results of target nodes have register or immediate
|
||||
|
|
Loading…
Reference in New Issue