[llvm] r333650 - [MCSchedule] Add the ability to compute the latency and throughput information for MCInst.

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Thu May 31 06:30:42 PDT 2018


Author: adibiagio
Date: Thu May 31 06:30:42 2018
New Revision: 333650

URL: http://llvm.org/viewvc/llvm-project?rev=333650&view=rev
Log:
[MCSchedule] Add the ability to compute the latency and throughput information for MCInst.

This patch extends the MCSchedModel API with new methods that can be used to
obtain the latency and reciprocal througput information for an MCInst.

Scheduling models have recently gained the ability to resolve variant scheduling
classes associated with MCInst objects. Before, models were only able to resolve
a variant scheduling class from a MachineInstr object.

This patch is mainly required by D47374 to avoid regressing a pair of x86
specific -print-schedule tests for btver2. Patch D47374 introduces a new variant
class to teach the btver scheduling model (x86 target) how to correctly compute
the latency profile for some zero-idioms using the new scheduling predicates.

The new methods added by this patch would be mainly used by llc when flag
-print-schedule is specified. In particular, tests that contain inline assembly
require that code is parsed at code emission stage into a sequence of MCInst.
That forces the print-schedule functionality to query the latency/rthroughput
information for MCInst instructions too. If we don't expose this new API, then
we lose "-print-schedule" test coverage as soon as variant scheduling classes
are added to the x86 models.

The tablegen SubtargetEmitter changes teaches how to query latency profile
information using a object that derives from TargetSubtargetInfo. Note that this
should really have been part of r333286. To avoid code duplication, the logic
that "resolves" variant scheduling classes for MCInst, has been moved to a
common place in MC. That logic is used by the "resolveVariantSchedClass" methods
redefined in override by the tablegen'd GenSubtargetInfo classes.

Differential Revision: https://reviews.llvm.org/D47536

Modified:
    llvm/trunk/include/llvm/CodeGen/TargetSchedule.h
    llvm/trunk/include/llvm/MC/MCSchedule.h
    llvm/trunk/lib/CodeGen/TargetSchedule.cpp
    llvm/trunk/lib/CodeGen/TargetSubtargetInfo.cpp
    llvm/trunk/lib/MC/MCSchedule.cpp
    llvm/trunk/utils/TableGen/SubtargetEmitter.cpp

Modified: llvm/trunk/include/llvm/CodeGen/TargetSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetSchedule.h?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetSchedule.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetSchedule.h Thu May 31 06:30:42 2018
@@ -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;
 };
 

Modified: llvm/trunk/include/llvm/MC/MCSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSchedule.h?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSchedule.h (original)
+++ llvm/trunk/include/llvm/MC/MCSchedule.h Thu May 31 06:30:42 2018
@@ -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;

Modified: llvm/trunk/lib/CodeGen/TargetSchedule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetSchedule.cpp?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetSchedule.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetSchedule.cpp Thu May 31 06:30:42 2018
@@ -261,7 +261,13 @@ TargetSchedModel::computeInstrLatency(co
 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::computeReciprocalThrou
   }
   return Optional<double>();
 }
+
+Optional<double>
+TargetSchedModel::computeReciprocalThroughput(const MCInst &MI) const {
+  if (hasInstrSchedModel())
+    return SchedModel.getReciprocalThroughput(*STI, *TII, MI);
+  return computeReciprocalThroughput(MI.getOpcode());
+}
+

Modified: llvm/trunk/lib/CodeGen/TargetSubtargetInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetSubtargetInfo.cpp?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetSubtargetInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetSubtargetInfo.cpp Thu May 31 06:30:42 2018
@@ -102,7 +102,7 @@ std::string TargetSubtargetInfo::getSche
   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::getSche
   } else
     return std::string();
   Optional<double> RThroughput =
-      TSchedModel.computeReciprocalThroughput(MCI.getOpcode());
+      TSchedModel.computeReciprocalThroughput(MCI);
   return createSchedInfoStr(Latency, RThroughput);
 }
 

Modified: llvm/trunk/lib/MC/MCSchedule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCSchedule.cpp?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCSchedule.cpp (original)
+++ llvm/trunk/lib/MC/MCSchedule.cpp Thu May 31 06:30:42 2018
@@ -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(co
   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(co
 }
 
 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;

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=333650&r1=333649&r2=333650&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Thu May 31 06:30:42 2018
@@ -1587,8 +1587,15 @@ void SubtargetEmitter::EmitSchedModelHel
 
   // 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::ParseFeaturesFunc
 }
 
 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::emitGenMCSubtarge
      << "      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 &
   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 &
      << "  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)




More information about the llvm-commits mailing list