summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCSchedule.h4
-rw-r--r--llvm/include/llvm/Target/TargetSchedule.td7
-rw-r--r--llvm/lib/Target/X86/X86PfmCounters.td1
-rw-r--r--llvm/tools/llvm-exegesis/lib/BenchmarkResult.h5
-rw-r--r--llvm/tools/llvm-exegesis/lib/Latency.cpp3
-rw-r--r--llvm/tools/llvm-exegesis/lib/Uops.cpp35
-rw-r--r--llvm/utils/TableGen/CodeGenSchedule.cpp9
-rw-r--r--llvm/utils/TableGen/CodeGenSchedule.h4
-rw-r--r--llvm/utils/TableGen/SubtargetEmitter.cpp7
9 files changed, 59 insertions, 16 deletions
diff --git a/llvm/include/llvm/MC/MCSchedule.h b/llvm/include/llvm/MC/MCSchedule.h
index f2f1dfb3691..9f53a468903 100644
--- a/llvm/include/llvm/MC/MCSchedule.h
+++ b/llvm/include/llvm/MC/MCSchedule.h
@@ -182,6 +182,10 @@ struct MCExtraProcessorInfo {
// cycles.
const char *CycleCounter;
+ // An optional name of a performance counter that can be used to measure
+ // uops.
+ const char *UopsCounter;
+
// For each MCProcResourceDesc defined by the processor, an optional list of
// names of performance counters that can be used to measure the resource
// utilization.
diff --git a/llvm/include/llvm/Target/TargetSchedule.td b/llvm/include/llvm/Target/TargetSchedule.td
index 577b14f43f1..7d7ce2dabe0 100644
--- a/llvm/include/llvm/Target/TargetSchedule.td
+++ b/llvm/include/llvm/Target/TargetSchedule.td
@@ -550,3 +550,10 @@ class PfmIssueCounter<ProcResourceUnits resource, list<string> counters>
// The list of counters that measure issue events.
list<string> Counters = counters;
}
+
+// Each processor can define how to measure NumMicroOps by defining a
+// PfmUopsCounter.
+class PfmUopsCounter<string counter> : PfmCounter {
+ string Counter = counter;
+}
+
diff --git a/llvm/lib/Target/X86/X86PfmCounters.td b/llvm/lib/Target/X86/X86PfmCounters.td
index 093fbafa3fb..894c6e8c252 100644
--- a/llvm/lib/Target/X86/X86PfmCounters.td
+++ b/llvm/lib/Target/X86/X86PfmCounters.td
@@ -32,6 +32,7 @@ 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"]>;
+def HWUopsCounter : PfmUopsCounter<"uops_issued:any">;
}
let SchedModel = BroadwellModel in {
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
index e4e29ef1523..0fcf4e9fe6d 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
@@ -41,6 +41,10 @@ struct InstructionBenchmarkKey {
};
struct BenchmarkMeasure {
+ // A helper to create an unscaled BenchmarkMeasure.
+ static BenchmarkMeasure Create(std::string Key, double Value) {
+ return {Key, Value, Value, Key};
+ }
std::string Key;
// This is the per-instruction value, i.e. measured quantity scaled per
// instruction.
@@ -48,6 +52,7 @@ struct BenchmarkMeasure {
// This is the per-snippet value, i.e. measured quantity for one repetition of
// the whole snippet.
double PerSnippetValue;
+ // FIXME: remove, use `Key` instead.
std::string DebugString;
};
diff --git a/llvm/tools/llvm-exegesis/lib/Latency.cpp b/llvm/tools/llvm-exegesis/lib/Latency.cpp
index 3c402c4700c..9eeb2644f06 100644
--- a/llvm/tools/llvm-exegesis/lib/Latency.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Latency.cpp
@@ -130,8 +130,7 @@ LatencyBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
if (Value < MinLatency)
MinLatency = Value;
}
- return {{"latency", static_cast<double>(MinLatency),
- static_cast<double>(MinLatency), ""}};
+ return {BenchmarkMeasure::Create("latency", MinLatency)};
}
} // namespace exegesis
diff --git a/llvm/tools/llvm-exegesis/lib/Uops.cpp b/llvm/tools/llvm-exegesis/lib/Uops.cpp
index dbecbfe5441..d7ac880d051 100644
--- a/llvm/tools/llvm-exegesis/lib/Uops.cpp
+++ b/llvm/tools/llvm-exegesis/lib/Uops.cpp
@@ -255,23 +255,18 @@ UopsBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
ScratchSpace &Scratch) const {
const auto &SchedModel = State.getSubtargetInfo().getSchedModel();
- std::vector<BenchmarkMeasure> Result;
- for (unsigned ProcResIdx = 1;
- ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) {
- const char *const PfmCounters = SchedModel.getExtraProcessorInfo()
- .PfmCounters.IssueCounters[ProcResIdx];
- if (!PfmCounters)
- continue;
+ const auto RunMeasurement = [&Function,
+ &Scratch](const char *const Counters) {
// We sum counts when there are several counters for a single ProcRes
// (e.g. P23 on SandyBridge).
int64_t CounterValue = 0;
llvm::SmallVector<llvm::StringRef, 2> CounterNames;
- llvm::StringRef(PfmCounters).split(CounterNames, ',');
+ llvm::StringRef(Counters).split(CounterNames, ',');
for (const auto &CounterName : CounterNames) {
pfm::PerfEvent UopPerfEvent(CounterName);
if (!UopPerfEvent.valid())
llvm::report_fatal_error(
- llvm::Twine("invalid perf event ").concat(PfmCounters));
+ llvm::Twine("invalid perf event ").concat(Counters));
pfm::Counter Counter(UopPerfEvent);
Scratch.clear();
Counter.start();
@@ -279,10 +274,24 @@ UopsBenchmarkRunner::runMeasurements(const ExecutableFunction &Function,
Counter.stop();
CounterValue += Counter.read();
}
- Result.push_back({llvm::itostr(ProcResIdx),
- static_cast<double>(CounterValue),
- static_cast<double>(CounterValue),
- SchedModel.getProcResource(ProcResIdx)->Name});
+ return CounterValue;
+ };
+
+ std::vector<BenchmarkMeasure> Result;
+ const auto& PfmCounters = SchedModel.getExtraProcessorInfo().PfmCounters;
+ // Uops per port.
+ for (unsigned ProcResIdx = 1;
+ ProcResIdx < SchedModel.getNumProcResourceKinds(); ++ProcResIdx) {
+ const char *const Counters = PfmCounters.IssueCounters[ProcResIdx];
+ if (!Counters)
+ continue;
+ const double CounterValue = RunMeasurement(Counters);
+ Result.push_back(BenchmarkMeasure::Create(SchedModel.getProcResource(ProcResIdx)->Name, CounterValue));
+ }
+ // NumMicroOps.
+ if (const char *const UopsCounter = PfmCounters.UopsCounter) {
+ const double CounterValue = RunMeasurement(UopsCounter);
+ Result.push_back(BenchmarkMeasure::Create("NumMicroOps", CounterValue));
}
return Result;
}
diff --git a/llvm/utils/TableGen/CodeGenSchedule.cpp b/llvm/utils/TableGen/CodeGenSchedule.cpp
index 545e8292033..625944bcfe9 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.cpp
+++ b/llvm/utils/TableGen/CodeGenSchedule.cpp
@@ -1787,6 +1787,15 @@ void CodeGenSchedModels::collectPfmCounters() {
}
PM.PfmCycleCounterDef = Def;
}
+ for (Record *Def : Records.getAllDerivedDefinitions("PfmUopsCounter")) {
+ CodeGenProcModel &PM = getProcModel(Def->getValueAsDef("SchedModel"));
+ if (PM.PfmUopsCounterDef) {
+ PrintFatalError(Def->getLoc(),
+ "multiple uops counters for " +
+ Def->getValueAsDef("SchedModel")->getName());
+ }
+ PM.PfmUopsCounterDef = Def;
+ }
}
// Collect and sort WriteRes, ReadAdvance, and ProcResources.
diff --git a/llvm/utils/TableGen/CodeGenSchedule.h b/llvm/utils/TableGen/CodeGenSchedule.h
index 3ed753c8ffe..c2af28bbaa0 100644
--- a/llvm/utils/TableGen/CodeGenSchedule.h
+++ b/llvm/utils/TableGen/CodeGenSchedule.h
@@ -242,6 +242,7 @@ struct CodeGenProcModel {
// List of PfmCounters.
RecVec PfmIssueCounterDefs;
Record *PfmCycleCounterDef = nullptr;
+ Record *PfmUopsCounterDef = nullptr;
CodeGenProcModel(unsigned Idx, std::string Name, Record *MDef,
Record *IDef) :
@@ -259,7 +260,8 @@ struct CodeGenProcModel {
bool hasExtraProcessorInfo() const {
return RetireControlUnit || !RegisterFiles.empty() ||
!PfmIssueCounterDefs.empty() ||
- PfmCycleCounterDef != nullptr;
+ PfmCycleCounterDef != nullptr ||
+ PfmUopsCounterDef != nullptr;
}
unsigned getProcResourceIdx(Record *PRDef) const;
diff --git a/llvm/utils/TableGen/SubtargetEmitter.cpp b/llvm/utils/TableGen/SubtargetEmitter.cpp
index 33257b63f6e..100399f52ff 100644
--- a/llvm/utils/TableGen/SubtargetEmitter.cpp
+++ b/llvm/utils/TableGen/SubtargetEmitter.cpp
@@ -743,6 +743,13 @@ static void EmitPfmCounters(const CodeGenProcModel &ProcModel,
else
OS << " nullptr, // No cycle counter.\n";
+ // Emit the uops counter.
+ if (ProcModel.PfmUopsCounterDef)
+ OS << " \"" << ProcModel.PfmUopsCounterDef->getValueAsString("Counter")
+ << "\", // Uops counter.\n";
+ else
+ OS << " nullptr, // No uops counter.\n";
+
// Emit a reference to issue counters table.
if (HasPfmIssueCounters)
OS << " " << ProcModel.ModelName << "PfmIssueCounters\n";
OpenPOWER on IntegriCloud