[llvm] r329675 - [MC][TableGen] Add optional libpfm counter names for ProcResUnits.

Clement Courbet via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 10 01:16:37 PDT 2018


Author: courbet
Date: Tue Apr 10 01:16:37 2018
New Revision: 329675

URL: http://llvm.org/viewvc/llvm-project?rev=329675&view=rev
Log:
[MC][TableGen] Add optional libpfm counter names for ProcResUnits.

Summary:
Subtargets can define the libpfm counter names that can be used to
measure cycles and uops issued on ProcResUnits.
This allows making llvm-exegesis available on more targets.
Fixes PR36984.

Reviewers: gchatelet, RKSimon, andreadb, craig.topper

Subscribers: llvm-commits

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

Added:
    llvm/trunk/lib/Target/X86/X86PfmCounters.td
Modified:
    llvm/trunk/include/llvm/MC/MCSchedule.h
    llvm/trunk/include/llvm/Target/TargetSchedule.td
    llvm/trunk/lib/Target/X86/X86.td
    llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
    llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
    llvm/trunk/utils/TableGen/CodeGenSchedule.cpp
    llvm/trunk/utils/TableGen/CodeGenSchedule.h
    llvm/trunk/utils/TableGen/SubtargetEmitter.cpp

Modified: llvm/trunk/include/llvm/MC/MCSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCSchedule.h?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCSchedule.h (original)
+++ llvm/trunk/include/llvm/MC/MCSchedule.h Tue Apr 10 01:16:37 2018
@@ -172,6 +172,18 @@ struct MCExtraProcessorInfo {
   unsigned NumRegisterFiles;
   const MCRegisterCostEntry *RegisterCostTable;
   unsigned NumRegisterCostEntries;
+
+  struct PfmCountersInfo {
+    // An optional name of a performance counter that can be used to measure
+    // cycles.
+    const char *CycleCounter;
+
+    // For each MCProcResourceDesc defined by the processor, an optional list of
+    // names of performance counters that can be used to measure the resource
+    // utilization.
+    const char **IssueCounters;
+  };
+  PfmCountersInfo PfmCounters;
 };
 
 /// Machine model for scheduling, bundling, and heuristics.

Modified: llvm/trunk/include/llvm/Target/TargetSchedule.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSchedule.td?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSchedule.td (original)
+++ llvm/trunk/include/llvm/Target/TargetSchedule.td Tue Apr 10 01:16:37 2018
@@ -182,7 +182,8 @@ class ProcResourceKind;
 //
 // SchedModel ties these units to a processor for any stand-alone defs
 // of this class.
-class ProcResourceUnits<ProcResourceKind kind, int num> {
+class ProcResourceUnits<ProcResourceKind kind, int num,
+                        list<string> pfmCounters> {
   ProcResourceKind Kind = kind;
   int NumUnits = num;
   ProcResourceKind Super = ?;
@@ -197,8 +198,8 @@ def EponymousProcResourceKind : ProcReso
 
 // Subtargets typically define processor resource kind and number of
 // units in one place.
-class ProcResource<int num> : ProcResourceKind,
-  ProcResourceUnits<EponymousProcResourceKind, num>;
+class ProcResource<int num, list<string> pfmCounters = []> : ProcResourceKind,
+  ProcResourceUnits<EponymousProcResourceKind, num, pfmCounters>;
 
 class ProcResGroup<list<ProcResource> resources> : ProcResourceKind {
   list<ProcResource> Resources = resources;
@@ -476,3 +477,23 @@ class RetireControlUnit<int bufferSize,
   SchedMachineModel SchedModel = ?;
 }
 
+// Allow the definition of hardware counters.
+class PfmCounter {
+  SchedMachineModel SchedModel = ?;
+}
+
+// Each processor can define how to measure cycles by defining a
+// PfmCycleCounter.
+class PfmCycleCounter<string counter> : PfmCounter {
+  string Counter = counter;
+}
+
+// Each ProcResourceUnits can define how to measure issued uops by defining
+// a PfmIssueCounter.
+class PfmIssueCounter<ProcResourceUnits resource, list<string> counters>
+    : PfmCounter{
+  // The resource units on which uops are issued.
+  ProcResourceUnits Resource = resource;
+  // The list of counters that measure issue events.
+  list<string> Counters = counters;
+}

Modified: llvm/trunk/lib/Target/X86/X86.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86.td?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86.td (original)
+++ llvm/trunk/lib/Target/X86/X86.td Tue Apr 10 01:16:37 2018
@@ -1132,3 +1132,9 @@ def X86 : Target {
   let AssemblyWriters = [ATTAsmWriter, IntelAsmWriter];
   let AllowRegisterRenaming = 1;
 }
+
+//===----------------------------------------------------------------------===//
+// Pfm Counters
+//===----------------------------------------------------------------------===//
+
+include "X86PfmCounters.td"

Added: llvm/trunk/lib/Target/X86/X86PfmCounters.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86PfmCounters.td?rev=329675&view=auto
==============================================================================
--- llvm/trunk/lib/Target/X86/X86PfmCounters.td (added)
+++ llvm/trunk/lib/Target/X86/X86PfmCounters.td Tue Apr 10 01:16:37 2018
@@ -0,0 +1,71 @@
+//===-- X86PfmCounters.td - X86 Hardware Counters ----------*- tablegen -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This describes the available hardware counters for various subtargets.
+//
+//===----------------------------------------------------------------------===//
+
+let SchedModel = SandyBridgeModel in {
+def SBCycleCounter : PfmCycleCounter<"unhalted_core_cycles">;
+def SBPort0Counter : PfmIssueCounter<SBPort0, ["uops_dispatched_port:port_0"]>;
+def SBPort1Counter : PfmIssueCounter<SBPort1, ["uops_dispatched_port:port_1"]>;
+def SBPort23Counter : PfmIssueCounter<SBPort23,
+                                      ["uops_dispatched_port:port_2",
+				       "uops_dispatched_port:port_3"]>;
+def SBPort4Counter : PfmIssueCounter<SBPort4, ["uops_dispatched_port:port_4"]>;
+def SBPort5Counter : PfmIssueCounter<SBPort5, ["uops_dispatched_port:port_5"]>;
+}
+
+let SchedModel = HaswellModel in {
+def HWCycleCounter : PfmCycleCounter<"unhalted_core_cycles">;
+def HWPort0Counter : PfmIssueCounter<HWPort0, ["uops_dispatched_port:port_0"]>;
+def HWPort1Counter : PfmIssueCounter<HWPort1, ["uops_dispatched_port:port_1"]>;
+def HWPort2Counter : PfmIssueCounter<HWPort2, ["uops_dispatched_port:port_2"]>;
+def HWPort3Counter : PfmIssueCounter<HWPort3, ["uops_dispatched_port:port_3"]>;
+def HWPort4Counter : PfmIssueCounter<HWPort4, ["uops_dispatched_port:port_4"]>;
+def HWPort5Counter : PfmIssueCounter<HWPort5, ["uops_dispatched_port:port_5"]>;
+def HWPort6Counter : PfmIssueCounter<HWPort6, ["uops_dispatched_port:port_6"]>;
+def HWPort7Counter : PfmIssueCounter<HWPort7, ["uops_dispatched_port:port_7"]>;
+}
+
+let SchedModel = BroadwellModel in {
+def BWCycleCounter : PfmCycleCounter<"unhalted_core_cycles">;
+def BWPort0Counter : PfmIssueCounter<BWPort0, ["uops_dispatched_port:port_0"]>;
+def BWPort1Counter : PfmIssueCounter<BWPort1, ["uops_dispatched_port:port_1"]>;
+def BWPort2Counter : PfmIssueCounter<BWPort2, ["uops_dispatched_port:port_2"]>;
+def BWPort3Counter : PfmIssueCounter<BWPort3, ["uops_dispatched_port:port_3"]>;
+def BWPort4Counter : PfmIssueCounter<BWPort4, ["uops_dispatched_port:port_4"]>;
+def BWPort5Counter : PfmIssueCounter<BWPort5, ["uops_dispatched_port:port_5"]>;
+def BWPort6Counter : PfmIssueCounter<BWPort6, ["uops_dispatched_port:port_6"]>;
+def BWPort7Counter : PfmIssueCounter<BWPort7, ["uops_dispatched_port:port_7"]>;
+}
+
+let SchedModel = SkylakeClientModel in {
+def SKLCycleCounter : PfmCycleCounter<"unhalted_core_cycles">;
+def SKLPort0Counter : PfmIssueCounter<SKLPort0, ["uops_dispatched_port:port_0"]>;
+def SKLPort1Counter : PfmIssueCounter<SKLPort1, ["uops_dispatched_port:port_1"]>;
+def SKLPort2Counter : PfmIssueCounter<SKLPort2, ["uops_dispatched_port:port_2"]>;
+def SKLPort3Counter : PfmIssueCounter<SKLPort3, ["uops_dispatched_port:port_3"]>;
+def SKLPort4Counter : PfmIssueCounter<SKLPort4, ["uops_dispatched_port:port_4"]>;
+def SKLPort5Counter : PfmIssueCounter<SKLPort5, ["uops_dispatched_port:port_5"]>;
+def SKLPort6Counter : PfmIssueCounter<SKLPort6, ["uops_dispatched_port:port_6"]>;
+def SKLPort7Counter : PfmIssueCounter<SKLPort7, ["uops_dispatched_port:port_7"]>;
+}
+
+let SchedModel = SkylakeServerModel in {
+def SKXCycleCounter : PfmCycleCounter<"unhalted_core_cycles">;
+def SKXPort0Counter : PfmIssueCounter<SKXPort0, ["uops_dispatched_port:port_0"]>;
+def SKXPort1Counter : PfmIssueCounter<SKXPort1, ["uops_dispatched_port:port_1"]>;
+def SKXPort2Counter : PfmIssueCounter<SKXPort2, ["uops_dispatched_port:port_2"]>;
+def SKXPort3Counter : PfmIssueCounter<SKXPort3, ["uops_dispatched_port:port_3"]>;
+def SKXPort4Counter : PfmIssueCounter<SKXPort4, ["uops_dispatched_port:port_4"]>;
+def SKXPort5Counter : PfmIssueCounter<SKXPort5, ["uops_dispatched_port:port_5"]>;
+def SKXPort6Counter : PfmIssueCounter<SKXPort6, ["uops_dispatched_port:port_6"]>;
+def SKXPort7Counter : PfmIssueCounter<SKXPort7, ["uops_dispatched_port:port_7"]>;
+}

Modified: llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Latency.cpp Tue Apr 10 01:16:37 2018
@@ -76,10 +76,15 @@ LatencyBenchmarkRunner::runMeasurements(
   // measure several times and take the minimum value.
   constexpr const int NumMeasurements = 30;
   int64_t MinLatency = std::numeric_limits<int64_t>::max();
-  // FIXME: Read the perf event from the MCSchedModel (see PR36984).
-  const pfm::PerfEvent CyclesPerfEvent("UNHALTED_CORE_CYCLES");
+  const char *CounterName = State.getSubtargetInfo()
+                                .getSchedModel()
+                                .getExtraProcessorInfo()
+                                .PfmCounters.CycleCounter;
+  if (!CounterName)
+    llvm::report_fatal_error("sched model does not define a cycle counter");
+  const pfm::PerfEvent CyclesPerfEvent(CounterName);
   if (!CyclesPerfEvent.valid())
-    llvm::report_fatal_error("invalid perf event 'UNHALTED_CORE_CYCLES'");
+    llvm::report_fatal_error("invalid perf event");
   for (size_t I = 0; I < NumMeasurements; ++I) {
     pfm::Counter Counter(CyclesPerfEvent);
     Counter.start();

Modified: llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp (original)
+++ llvm/trunk/tools/llvm-exegesis/lib/Uops.cpp Tue Apr 10 01:16:37 2018
@@ -38,43 +38,6 @@ static llvm::Error makeError(llvm::Twine
                                              llvm::inconvertibleErrorCode());
 }
 
-// FIXME: Read the counter names from the ProcResourceUnits when PR36984 is
-// fixed.
-static const std::string *getEventNameFromProcResName(const char *ProcResName) {
-  static const std::unordered_map<std::string, std::string> Entries = {
-      {"SBPort0", "UOPS_DISPATCHED_PORT:PORT_0"},
-      {"SBPort1", "UOPS_DISPATCHED_PORT:PORT_1"},
-      {"SBPort4", "UOPS_DISPATCHED_PORT:PORT_4"},
-      {"SBPort5", "UOPS_DISPATCHED_PORT:PORT_5"},
-      {"HWPort0", "UOPS_DISPATCHED_PORT:PORT_0"},
-      {"HWPort1", "UOPS_DISPATCHED_PORT:PORT_1"},
-      {"HWPort2", "UOPS_DISPATCHED_PORT:PORT_2"},
-      {"HWPort3", "UOPS_DISPATCHED_PORT:PORT_3"},
-      {"HWPort4", "UOPS_DISPATCHED_PORT:PORT_4"},
-      {"HWPort5", "UOPS_DISPATCHED_PORT:PORT_5"},
-      {"HWPort6", "UOPS_DISPATCHED_PORT:PORT_6"},
-      {"HWPort7", "UOPS_DISPATCHED_PORT:PORT_7"},
-      {"SKLPort0", "UOPS_DISPATCHED_PORT:PORT_0"},
-      {"SKLPort1", "UOPS_DISPATCHED_PORT:PORT_1"},
-      {"SKLPort2", "UOPS_DISPATCHED_PORT:PORT_2"},
-      {"SKLPort3", "UOPS_DISPATCHED_PORT:PORT_3"},
-      {"SKLPort4", "UOPS_DISPATCHED_PORT:PORT_4"},
-      {"SKLPort5", "UOPS_DISPATCHED_PORT:PORT_5"},
-      {"SKLPort6", "UOPS_DISPATCHED_PORT:PORT_6"},
-      {"SKXPort7", "UOPS_DISPATCHED_PORT:PORT_7"},
-      {"SKXPort0", "UOPS_DISPATCHED_PORT:PORT_0"},
-      {"SKXPort1", "UOPS_DISPATCHED_PORT:PORT_1"},
-      {"SKXPort2", "UOPS_DISPATCHED_PORT:PORT_2"},
-      {"SKXPort3", "UOPS_DISPATCHED_PORT:PORT_3"},
-      {"SKXPort4", "UOPS_DISPATCHED_PORT:PORT_4"},
-      {"SKXPort5", "UOPS_DISPATCHED_PORT:PORT_5"},
-      {"SKXPort6", "UOPS_DISPATCHED_PORT:PORT_6"},
-      {"SKXPort7", "UOPS_DISPATCHED_PORT:PORT_7"},
-  };
-  const auto It = Entries.find(ProcResName);
-  return It == Entries.end() ? nullptr : &It->second;
-}
-
 static std::vector<llvm::MCInst> generateIndependentAssignments(
     const LLVMState &State, const llvm::MCInstrDesc &InstrDesc,
     llvm::SmallVector<Variable, 8> Vars, int MaxAssignments) {
@@ -228,19 +191,19 @@ UopsBenchmarkRunner::runMeasurements(con
   std::vector<BenchmarkMeasure> Result;
   for (unsigned ProcResIdx = 1;
        ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) {
-    const llvm::MCProcResourceDesc &ProcRes =
-        *SchedModel.getProcResource(ProcResIdx);
-    const std::string *const EventName =
-        getEventNameFromProcResName(ProcRes.Name);
-    if (!EventName)
+    const char *const PfmCounters = SchedModel.getExtraProcessorInfo()
+                                        .PfmCounters.IssueCounters[ProcResIdx];
+    if (!PfmCounters)
       continue;
-    pfm::Counter Counter{pfm::PerfEvent(*EventName)};
+    // FIXME: Sum results when there are several counters for a single ProcRes
+    // (e.g. P23 on SandyBridge).
+    pfm::Counter Counter{pfm::PerfEvent(PfmCounters)};
     Counter.start();
     Function();
     Counter.stop();
     Result.push_back({llvm::itostr(ProcResIdx),
                       static_cast<double>(Counter.read()) / NumRepetitions,
-                      ProcRes.Name});
+                      SchedModel.getProcResource(ProcResIdx)->Name});
   }
   return Result;
 }

Modified: llvm/trunk/utils/TableGen/CodeGenSchedule.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenSchedule.cpp?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenSchedule.cpp (original)
+++ llvm/trunk/utils/TableGen/CodeGenSchedule.cpp Tue Apr 10 01:16:37 2018
@@ -239,6 +239,11 @@ void CodeGenSchedModels::collectOptional
 
   // Collect processor RetireControlUnit descriptors if available.
   collectRetireControlUnits();
+
+  // Find pfm counter definitions for each processor.
+  collectPfmCounters();
+
+  checkCompleteness();
 }
 
 /// Gather all processor models.
@@ -1537,6 +1542,23 @@ void CodeGenSchedModels::collectRegister
   }
 }
 
+// Collect all the RegisterFile definitions available in this target.
+void CodeGenSchedModels::collectPfmCounters() {
+  for (Record *Def : Records.getAllDerivedDefinitions("PfmIssueCounter")) {
+    CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
+    PM.PfmIssueCounterDefs.emplace_back(Def);
+  }
+  for (Record *Def : Records.getAllDerivedDefinitions("PfmCycleCounter")) {
+    CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
+    if (PM.PfmCycleCounterDef) {
+      PrintFatalError(Def->getLoc(),
+                      "multiple cycle counters for " +
+                          Def->getValueAsDef("SchedModel")->getName());
+    }
+    PM.PfmCycleCounterDef = Def;
+  }
+}
+
 // Collect and sort WriteRes, ReadAdvance, and ProcResources.
 void CodeGenSchedModels::collectProcResources() {
   ProcResourceDefs = Records.getAllDerivedDefinitions("ProcResourceUnits");

Modified: llvm/trunk/utils/TableGen/CodeGenSchedule.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/CodeGenSchedule.h?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/CodeGenSchedule.h (original)
+++ llvm/trunk/utils/TableGen/CodeGenSchedule.h Tue Apr 10 01:16:37 2018
@@ -238,6 +238,10 @@ struct CodeGenProcModel {
   // Optional Retire Control Unit definition.
   Record *RetireControlUnit;
 
+  // List of PfmCounters.
+  RecVec PfmIssueCounterDefs;
+  Record *PfmCycleCounterDef = nullptr;
+
   CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef,
                    Record *IDef) :
     Index(Idx), ModelName(std::move(Name)), ModelDef(MDef), ItinsDef(IDef),
@@ -252,7 +256,9 @@ struct CodeGenProcModel {
   }
 
   bool hasExtraProcessorInfo() const {
-    return RetireControlUnit || !RegisterFiles.empty();
+    return RetireControlUnit || !RegisterFiles.empty() ||
+        !PfmIssueCounterDefs.empty() ||
+        PfmCycleCounterDef != nullptr;
   }
 
   unsigned getProcResourceIdx(Record *PRDef) const;
@@ -444,6 +450,8 @@ private:
 
   void collectRegisterFiles();
 
+  void collectPfmCounters();
+
   void collectOptionalProcessorInfo();
 
   std::string createSchedClassName(Record *ItinClassDef,

Modified: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/utils/TableGen/SubtargetEmitter.cpp?rev=329675&r1=329674&r2=329675&view=diff
==============================================================================
--- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp (original)
+++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp Tue Apr 10 01:16:37 2018
@@ -635,7 +635,7 @@ static void EmitRegisterFileInfo(const C
     OS << ProcModel.ModelName << "RegisterCosts,\n  ";
   else
     OS << "nullptr,\n  ";
-  OS << NumCostEntries << " // Number of register cost entries.\n";
+  OS << NumCostEntries << ", // Number of register cost entries.\n";
 }
 
 unsigned
@@ -686,6 +686,57 @@ SubtargetEmitter::EmitRegisterFileTables
 
   return CostTblIndex;
 }
+static bool EmitPfmIssueCountersTable(const CodeGenProcModel &ProcModel,
+                                      raw_ostream &OS) {
+  std::vector<const Record *> CounterDefs(ProcModel.ProcResourceDefs.size());
+  bool HasCounters = false;
+  for (const Record *CounterDef : ProcModel.PfmIssueCounterDefs) {
+    const Record *&CD = CounterDefs[ProcModel.getProcResourceIdx(
+        CounterDef->getValueAsDef("Resource"))];
+    if (CD) {
+      PrintFatalError(CounterDef->getLoc(),
+                      "multiple issue counters for " +
+                          CounterDef->getValueAsDef("Resource")->getName());
+    }
+    CD = CounterDef;
+    HasCounters = true;
+  }
+  if (!HasCounters) {
+    return false;
+  }
+  OS << "\nstatic const char* " << ProcModel.ModelName
+     << "PfmIssueCounters[] = {\n";
+  for (const Record *CounterDef : CounterDefs) {
+    if (CounterDef) {
+      const auto PfmCounters = CounterDef->getValueAsListOfStrings("Counters");
+      if (PfmCounters.empty())
+        PrintFatalError(CounterDef->getLoc(), "empty counter list");
+      for (const StringRef CounterName : PfmCounters)
+        OS << "  \"" << CounterName << ",\"";
+      OS << ",  //" << CounterDef->getValueAsDef("Resource")->getName() << "\n";
+    } else {
+      OS << "  nullptr,\n";
+    }
+  }
+  OS << "};\n";
+  return true;
+}
+
+static void EmitPfmCounters(const CodeGenProcModel &ProcModel,
+                            const bool HasPfmIssueCounters, raw_ostream &OS) {
+  // Emit the cycle counter.
+  if (ProcModel.PfmCycleCounterDef)
+    OS << "  \"" << ProcModel.PfmCycleCounterDef->getValueAsString("Counter")
+       << "\",  // Cycle counter.\n";
+  else
+    OS << "  nullptr,  // No cycle counter.\n";
+
+  // Emit a reference to issue counters table.
+  if (HasPfmIssueCounters)
+    OS << "  " << ProcModel.ModelName << "PfmIssueCounters\n";
+  else
+    OS << "  nullptr,  // No issue counters.\n";
+}
 
 void SubtargetEmitter::EmitExtraProcessorInfo(const CodeGenProcModel &ProcModel,
                                               raw_ostream &OS) {
@@ -693,6 +744,9 @@ void SubtargetEmitter::EmitExtraProcesso
   // defined register file), and a table of register costs.
   unsigned NumCostEntries = EmitRegisterFileTables(ProcModel, OS);
 
+  // Generate a table of ProcRes counter names.
+  const bool HasPfmIssueCounters = EmitPfmIssueCountersTable(ProcModel, OS);
+
   // Now generate a table for the extra processor info.
   OS << "\nstatic const llvm::MCExtraProcessorInfo " << ProcModel.ModelName
      << "ExtraInfo = {\n  ";
@@ -705,6 +759,8 @@ void SubtargetEmitter::EmitExtraProcesso
   EmitRegisterFileInfo(ProcModel, ProcModel.RegisterFiles.size(),
                        NumCostEntries, OS);
 
+  EmitPfmCounters(ProcModel, HasPfmIssueCounters, OS);
+
   OS << "};\n";
 }
 
@@ -1308,9 +1364,9 @@ void SubtargetEmitter::EmitProcessorMode
     else
       OS << "  nullptr, // No Itinerary\n";
     if (PM.hasExtraProcessorInfo())
-      OS << "  &" << PM.ModelName << "ExtraInfo\n";
+      OS << "  &" << PM.ModelName << "ExtraInfo,\n";
     else
-      OS << "  nullptr  // No extra processor descriptor\n";
+      OS << "  nullptr // No extra processor descriptor\n";
     OS << "};\n";
   }
 }




More information about the llvm-commits mailing list