[MC] Moved all the remaining logic that computed instruction latency and reciprocal throughput from TargetSchedModel to MCSchedModel.

TargetSchedModel now always delegates to MCSchedModel the computation of
instruction latency and reciprocal throughput.
No functional change intended.

llvm-svn: 330099
This commit is contained in:
Andrea Di Biagio 2018-04-15 17:32:17 +00:00
parent d226d58b43
commit 053618b18b
5 changed files with 65 additions and 58 deletions

View File

@ -194,8 +194,8 @@ public:
const MachineInstr *DepMI) const;
/// \brief Compute the reciprocal throughput of the given instruction.
Optional<double> computeInstrRThroughput(const MachineInstr *MI) const;
Optional<double> computeInstrRThroughput(unsigned Opcode) const;
Optional<double> computeReciprocalThroughput(const MachineInstr *MI) const;
Optional<double> computeReciprocalThroughput(unsigned Opcode) const;
};
} // end namespace llvm

View File

@ -23,6 +23,8 @@ namespace llvm {
struct InstrItinerary;
class MCSubtargetInfo;
class MCInstrInfo;
class InstrItineraryData;
/// Define a kind of processor resource that will be modeled by the scheduler.
struct MCProcResourceDesc {
@ -300,16 +302,25 @@ struct MCSchedModel {
static int computeInstrLatency(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc);
/// Returns the reciprocal throughput information from a MCSchedClassDesc.
int computeInstrLatency(const MCSubtargetInfo &STI, unsigned SClass) const;
// Returns the reciprocal throughput information from a MCSchedClassDesc.
static Optional<double>
getReciprocalThroughput(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc);
static Optional<double>
getReciprocalThroughput(unsigned SchedClass, const InstrItineraryData &IID);
Optional<double> computeReciprocalThroughput(const MCSubtargetInfo &STI,
const MCInstrInfo &MCII,
unsigned Opcode) const;
/// Returns the default initialized model.
static const MCSchedModel &GetDefaultSchedModel() { return Default; }
static const MCSchedModel Default;
};
} // End llvm namespace
} // namespace llvm
#endif

View File

@ -260,16 +260,8 @@ TargetSchedModel::computeInstrLatency(const MCSchedClassDesc &SCDesc) const {
unsigned TargetSchedModel::computeInstrLatency(unsigned Opcode) const {
assert(hasInstrSchedModel() && "Only call this function with a SchedModel");
unsigned SCIdx = TII->get(Opcode).getSchedClass();
const MCSchedClassDesc *SCDesc = SchedModel.getSchedClassDesc(SCIdx);
if (!SCDesc->isValid())
return 0;
if (!SCDesc->isVariant())
return computeInstrLatency(*SCDesc);
llvm_unreachable("No MI sched latency");
return SchedModel.computeInstrLatency(*STI, SCIdx);
}
unsigned
@ -324,42 +316,25 @@ computeOutputLatency(const MachineInstr *DefMI, unsigned DefOperIdx,
return 0;
}
static Optional<double>
getRThroughputFromItineraries(unsigned schedClass,
const InstrItineraryData *IID){
Optional<double> Throughput;
for (const InstrStage *IS = IID->beginStage(schedClass),
*E = IID->endStage(schedClass);
IS != E; ++IS) {
if (IS->getCycles()) {
double Temp = countPopulation(IS->getUnits()) * 1.0 / IS->getCycles();
Throughput = Throughput.hasValue()
? std::min(Throughput.getValue(), Temp)
: Temp;
}
}
if (Throughput.hasValue())
// We need reciprocal throughput that's why we return such value.
return 1 / Throughput.getValue();
return Throughput;
}
Optional<double>
TargetSchedModel::computeInstrRThroughput(const MachineInstr *MI) const {
if (hasInstrItineraries())
return getRThroughputFromItineraries(MI->getDesc().getSchedClass(),
getInstrItineraries());
TargetSchedModel::computeReciprocalThroughput(const MachineInstr *MI) const {
if (hasInstrItineraries()) {
unsigned SchedClass = MI->getDesc().getSchedClass();
return MCSchedModel::getReciprocalThroughput(SchedClass,
*getInstrItineraries());
}
if (hasInstrSchedModel())
return MCSchedModel::getReciprocalThroughput(*STI, *resolveSchedClass(MI));
return Optional<double>();
}
Optional<double>
TargetSchedModel::computeInstrRThroughput(unsigned Opcode) const {
TargetSchedModel::computeReciprocalThroughput(unsigned Opcode) const {
unsigned SchedClass = TII->get(Opcode).getSchedClass();
if (hasInstrItineraries())
return getRThroughputFromItineraries(SchedClass, getInstrItineraries());
return MCSchedModel::getReciprocalThroughput(SchedClass,
*getInstrItineraries());
if (hasInstrSchedModel()) {
const MCSchedClassDesc &SCDesc = *SchedModel.getSchedClassDesc(SchedClass);
if (SCDesc.isValid() && !SCDesc.isVariant())

View File

@ -90,7 +90,7 @@ std::string TargetSubtargetInfo::getSchedInfoStr(const MachineInstr &MI) const {
TargetSchedModel TSchedModel;
TSchedModel.init(this);
unsigned Latency = TSchedModel.computeInstrLatency(&MI);
Optional<double> RThroughput = TSchedModel.computeInstrRThroughput(&MI);
Optional<double> RThroughput = TSchedModel.computeReciprocalThroughput(&MI);
return createSchedInfoStr(Latency, RThroughput);
}
@ -110,7 +110,7 @@ std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const {
} else
return std::string();
Optional<double> RThroughput =
TSchedModel.computeInstrRThroughput(MCI.getOpcode());
TSchedModel.computeReciprocalThroughput(MCI.getOpcode());
return createSchedInfoStr(Latency, RThroughput);
}

View File

@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSchedule.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include <type_traits>
@ -51,26 +53,45 @@ int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
return Latency;
}
int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
unsigned SchedClass) const {
const MCSchedClassDesc &SCDesc = *getSchedClassDesc(SchedClass);
if (!SCDesc.isValid())
return 0;
if (!SCDesc.isVariant())
return MCSchedModel::computeInstrLatency(STI, SCDesc);
llvm_unreachable("unsupported variant scheduling class");
}
Optional<double>
MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
Optional<double> Throughput;
const MCSchedModel &SchedModel = STI.getSchedModel();
for (const MCWriteProcResEntry *WPR = STI.getWriteProcResBegin(&SCDesc),
*WEnd = STI.getWriteProcResEnd(&SCDesc);
WPR != WEnd; ++WPR) {
if (WPR->Cycles) {
unsigned NumUnits =
SchedModel.getProcResource(WPR->ProcResourceIdx)->NumUnits;
double Temp = NumUnits * 1.0 / WPR->Cycles;
Throughput =
Throughput.hasValue() ? std::min(Throughput.getValue(), Temp) : Temp;
}
const MCSchedModel &SM = STI.getSchedModel();
const MCWriteProcResEntry *I = STI.getWriteProcResBegin(&SCDesc);
const MCWriteProcResEntry *E = STI.getWriteProcResEnd(&SCDesc);
for (; I != E; ++I) {
if (!I->Cycles)
continue;
unsigned NumUnits = SM.getProcResource(I->ProcResourceIdx)->NumUnits;
double Temp = NumUnits * 1.0 / I->Cycles;
Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
}
if (Throughput.hasValue())
return 1 / Throughput.getValue();
return Throughput;
return Throughput ? 1 / Throughput.getValue() : Throughput;
}
Optional<double>
MCSchedModel::getReciprocalThroughput(unsigned SchedClass,
const InstrItineraryData &IID) {
Optional<double> Throughput;
const InstrStage *I = IID.beginStage(SchedClass);
const InstrStage *E = IID.endStage(SchedClass);
for (; I != E; ++I) {
if (!I->getCycles())
continue;
double Temp = countPopulation(I->getUnits()) * 1.0 / I->getCycles();
Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp;
}
return Throughput ? 1 / Throughput.getValue() : Throughput;
}