diff options
-rw-r--r-- | llvm/include/llvm/CodeGen/TargetSchedule.h | 4 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSchedule.h | 15 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetSchedule.cpp | 45 | ||||
-rw-r--r-- | llvm/lib/CodeGen/TargetSubtargetInfo.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/MC/MCSchedule.cpp | 51 |
5 files changed, 63 insertions, 56 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetSchedule.h b/llvm/include/llvm/CodeGen/TargetSchedule.h index dfff34a0f72..5d4b5802b45 100644 --- a/llvm/include/llvm/CodeGen/TargetSchedule.h +++ b/llvm/include/llvm/CodeGen/TargetSchedule.h @@ -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 diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h index 2c2b92ce54b..f832385c5f1 100644 --- a/llvm/include/llvm/MC/MCSchedule.h +++ b/llvm/include/llvm/MC/MCSchedule.h @@ -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 diff --git a/llvm/lib/CodeGen/TargetSchedule.cpp b/llvm/lib/CodeGen/TargetSchedule.cpp index b8f284880af..5b6f72fbb35 100644 --- a/llvm/lib/CodeGen/TargetSchedule.cpp +++ b/llvm/lib/CodeGen/TargetSchedule.cpp @@ -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; - } +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()) diff --git a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp index 2b9cc64143d..6231402f043 100644 --- a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp +++ b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp @@ -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); } diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp index b71b530f091..216aa05422e 100644 --- a/llvm/lib/MC/MCSchedule.cpp +++ b/llvm/lib/MC/MCSchedule.cpp @@ -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; } + 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; } |