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
struct InstrItinerary;
class MCSubtargetInfo;
+class MCInstrInfo;
+class InstrItineraryData;
/// Define a kind of processor resource that will be modeled by the scheduler.
struct MCProcResourceDesc {
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
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
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;
- }
+Optional<double>
+TargetSchedModel::computeReciprocalThroughput(const MachineInstr *MI) const {
+ if (hasInstrItineraries()) {
+ unsigned SchedClass = MI->getDesc().getSchedClass();
+ return MCSchedModel::getReciprocalThroughput(SchedClass,
+ *getInstrItineraries());
}
- 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());
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())
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);
}
} else
return std::string();
Optional<double> RThroughput =
- TSchedModel.computeInstrRThroughput(MCI.getOpcode());
+ TSchedModel.computeReciprocalThroughput(MCI.getOpcode());
return createSchedInfoStr(Latency, RThroughput);
}
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include <type_traits>
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;
}
+ return Throughput ? 1 / Throughput.getValue() : Throughput;
+}
- if (Throughput.hasValue())
- return 1 / Throughput.getValue();
- return 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;
}