summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/CodeGen/TargetSchedule.h2
-rw-r--r--llvm/include/llvm/MC/MCSchedule.h7
-rw-r--r--llvm/lib/CodeGen/TargetSchedule.cpp16
-rw-r--r--llvm/lib/CodeGen/TargetSubtargetInfo.cpp4
-rw-r--r--llvm/lib/MC/MCSchedule.cpp43
-rw-r--r--llvm/utils/TableGen/SubtargetEmitter.cpp27
6 files changed, 93 insertions, 6 deletions
diff --git a/llvm/include/llvm/CodeGen/TargetSchedule.h b/llvm/include/llvm/CodeGen/TargetSchedule.h
index 3df1e8b0b01..fa3c64fd689 100644
--- a/llvm/include/llvm/CodeGen/TargetSchedule.h
+++ b/llvm/include/llvm/CodeGen/TargetSchedule.h
@@ -185,6 +185,7 @@ public:
/// if converter after moving it to TargetSchedModel).
unsigned computeInstrLatency(const MachineInstr *MI,
bool UseDefaultDefLatency = true) const;
+ unsigned computeInstrLatency(const MCInst &MI) const;
unsigned computeInstrLatency(unsigned Opcode) const;
@@ -196,6 +197,7 @@ public:
/// Compute the reciprocal throughput of the given instruction.
Optional<double> computeReciprocalThroughput(const MachineInstr *MI) const;
+ Optional<double> computeReciprocalThroughput(const MCInst &MI) const;
Optional<double> computeReciprocalThroughput(unsigned Opcode) const;
};
diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h
index 641d2cd82da..5aa51d416fe 100644
--- a/llvm/include/llvm/MC/MCSchedule.h
+++ b/llvm/include/llvm/MC/MCSchedule.h
@@ -25,6 +25,7 @@ namespace llvm {
struct InstrItinerary;
class MCSubtargetInfo;
class MCInstrInfo;
+class MCInst;
class InstrItineraryData;
/// Define a kind of processor resource that will be modeled by the scheduler.
@@ -357,6 +358,8 @@ struct MCSchedModel {
const MCSchedClassDesc &SCDesc);
int computeInstrLatency(const MCSubtargetInfo &STI, unsigned SClass) const;
+ int computeInstrLatency(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
+ const MCInst &Inst) const;
// Returns the reciprocal throughput information from a MCSchedClassDesc.
static Optional<double>
@@ -366,6 +369,10 @@ struct MCSchedModel {
static Optional<double>
getReciprocalThroughput(unsigned SchedClass, const InstrItineraryData &IID);
+ Optional<double>
+ getReciprocalThroughput(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
+ const MCInst &Inst) const;
+
/// Returns the default initialized model.
static const MCSchedModel &GetDefaultSchedModel() { return Default; }
static const MCSchedModel Default;
diff --git a/llvm/lib/CodeGen/TargetSchedule.cpp b/llvm/lib/CodeGen/TargetSchedule.cpp
index 5b6f72fbb35..2709df5697b 100644
--- a/llvm/lib/CodeGen/TargetSchedule.cpp
+++ b/llvm/lib/CodeGen/TargetSchedule.cpp
@@ -261,7 +261,13 @@ 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();
- return SchedModel.computeInstrLatency(*STI, SCIdx);
+ return capLatency(SchedModel.computeInstrLatency(*STI, SCIdx));
+}
+
+unsigned TargetSchedModel::computeInstrLatency(const MCInst &Inst) const {
+ if (hasInstrSchedModel())
+ return capLatency(SchedModel.computeInstrLatency(*STI, *TII, Inst));
+ return computeInstrLatency(Inst.getOpcode());
}
unsigned
@@ -342,3 +348,11 @@ TargetSchedModel::computeReciprocalThroughput(unsigned Opcode) const {
}
return Optional<double>();
}
+
+Optional<double>
+TargetSchedModel::computeReciprocalThroughput(const MCInst &MI) const {
+ if (hasInstrSchedModel())
+ return SchedModel.getReciprocalThroughput(*STI, *TII, MI);
+ return computeReciprocalThroughput(MI.getOpcode());
+}
+
diff --git a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp
index 6231402f043..97ca707a738 100644
--- a/llvm/lib/CodeGen/TargetSubtargetInfo.cpp
+++ b/llvm/lib/CodeGen/TargetSubtargetInfo.cpp
@@ -102,7 +102,7 @@ std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const {
TSchedModel.init(this);
unsigned Latency;
if (TSchedModel.hasInstrSchedModel())
- Latency = TSchedModel.computeInstrLatency(MCI.getOpcode());
+ Latency = TSchedModel.computeInstrLatency(MCI);
else if (TSchedModel.hasInstrItineraries()) {
auto *ItinData = TSchedModel.getInstrItineraries();
Latency = ItinData->getStageLatency(
@@ -110,7 +110,7 @@ std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const {
} else
return std::string();
Optional<double> RThroughput =
- TSchedModel.computeReciprocalThroughput(MCI.getOpcode());
+ TSchedModel.computeReciprocalThroughput(MCI);
return createSchedInfoStr(Latency, RThroughput);
}
diff --git a/llvm/lib/MC/MCSchedule.cpp b/llvm/lib/MC/MCSchedule.cpp
index 216aa05422e..e3fa76ee03c 100644
--- a/llvm/lib/MC/MCSchedule.cpp
+++ b/llvm/lib/MC/MCSchedule.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
@@ -64,6 +65,26 @@ int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
llvm_unreachable("unsupported variant scheduling class");
}
+int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI,
+ const MCInstrInfo &MCII,
+ const MCInst &Inst) const {
+ unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
+ const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
+ if (!SCDesc->isValid())
+ return 0;
+
+ unsigned CPUID = getProcessorID();
+ while (SCDesc->isVariant()) {
+ SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID);
+ SCDesc = getSchedClassDesc(SchedClass);
+ }
+
+ if (SchedClass)
+ return MCSchedModel::computeInstrLatency(STI, *SCDesc);
+
+ llvm_unreachable("unsupported variant scheduling class");
+}
+
Optional<double>
MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
const MCSchedClassDesc &SCDesc) {
@@ -82,6 +103,28 @@ MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
}
Optional<double>
+MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI,
+ const MCInstrInfo &MCII,
+ const MCInst &Inst) const {
+ Optional<double> Throughput;
+ unsigned SchedClass = MCII.get(Inst.getOpcode()).getSchedClass();
+ const MCSchedClassDesc *SCDesc = getSchedClassDesc(SchedClass);
+ if (!SCDesc->isValid())
+ return Throughput;
+
+ unsigned CPUID = getProcessorID();
+ while (SCDesc->isVariant()) {
+ SchedClass = STI.resolveVariantSchedClass(SchedClass, &Inst, CPUID);
+ SCDesc = getSchedClassDesc(SchedClass);
+ }
+
+ if (SchedClass)
+ return MCSchedModel::getReciprocalThroughput(STI, *SCDesc);
+
+ llvm_unreachable("unsupported variant scheduling class");
+}
+
+Optional<double>
MCSchedModel::getReciprocalThroughput(unsigned SchedClass,
const InstrItineraryData &IID) {
Optional<double> Throughput;
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 9e1edd61dc7..f66fa18d807 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -1587,8 +1587,15 @@ void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName,
// Emit target predicates.
emitSchedModelHelpersImpl(OS);
+
+ OS << "} // " << ClassName << "::resolveSchedClass\n\n";
- OS << "} // " << ClassName << "::resolveSchedClass\n";
+ OS << "unsigned " << ClassName
+ << "\n::resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,"
+ << " unsigned CPUID) const {\n"
+ << " return " << Target << "_MC"
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID);\n"
+ << "} // " << ClassName << "::resolveVariantSchedClass\n";
}
void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName,
@@ -1655,6 +1662,13 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
}
void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
+ OS << "namespace " << Target << "_MC {\n"
+ << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,\n"
+ << " const MCInst *MI, unsigned CPUID) {\n";
+ emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
+ OS << "}\n";
+ OS << "} // end of namespace " << Target << "_MC\n\n";
+
OS << "struct " << Target
<< "GenMCSubtargetInfo : public MCSubtargetInfo {\n";
OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT, \n"
@@ -1668,8 +1682,9 @@ void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) {
<< " MCSubtargetInfo(TT, CPU, FS, PF, PD, ProcSched,\n"
<< " WPR, WL, RA, IS, OC, FP) { }\n\n"
<< " unsigned resolveVariantSchedClass(unsigned SchedClass,\n"
- << " const MCInst *MI, unsigned CPUID) const override {\n";
- emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true);
+ << " const MCInst *MI, unsigned CPUID) const override {\n"
+ << " return " << Target << "_MC"
+ << "::resolveVariantSchedClassImpl(SchedClass, MI, CPUID); \n";
OS << " }\n";
OS << "};\n";
}
@@ -1754,6 +1769,10 @@ void SubtargetEmitter::run(raw_ostream &OS) {
std::string ClassName = Target + "GenSubtargetInfo";
OS << "namespace llvm {\n";
OS << "class DFAPacketizer;\n";
+ OS << "namespace " << Target << "_MC {\n"
+ << "unsigned resolveVariantSchedClassImpl(unsigned SchedClass,"
+ << " const MCInst *MI, unsigned CPUID);\n"
+ << "}\n\n";
OS << "struct " << ClassName << " : public TargetSubtargetInfo {\n"
<< " explicit " << ClassName << "(const Triple &TT, StringRef CPU, "
<< "StringRef FS);\n"
@@ -1761,6 +1780,8 @@ void SubtargetEmitter::run(raw_ostream &OS) {
<< " unsigned resolveSchedClass(unsigned SchedClass, "
<< " const MachineInstr *DefMI,"
<< " const TargetSchedModel *SchedModel) const override;\n"
+ << " unsigned resolveVariantSchedClass(unsigned SchedClass,"
+ << " const MCInst *MI, unsigned CPUID) const override;\n"
<< " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)"
<< " const;\n";
if (TGT.getHwModes().getNumModeIds() > 1)
OpenPOWER on IntegriCloud