summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp')
-rw-r--r--llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp76
1 files changed, 76 insertions, 0 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
index c122ae91306..f7375911235 100644
--- a/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
+++ b/llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp
@@ -239,5 +239,81 @@ ResolvedSchedClass::resolveSchedClassId(
return std::make_pair(SchedClassId, WasVariant);
}
+// Returns a ProxResIdx by id or name.
+static unsigned findProcResIdx(const llvm::MCSubtargetInfo &STI,
+ const llvm::StringRef NameOrId) {
+ // Interpret the key as an ProcResIdx.
+ unsigned ProcResIdx = 0;
+ if (llvm::to_integer(NameOrId, ProcResIdx, 10))
+ return ProcResIdx;
+ // Interpret the key as a ProcRes name.
+ const auto &SchedModel = STI.getSchedModel();
+ for (int I = 0, E = SchedModel.getNumProcResourceKinds(); I < E; ++I) {
+ if (NameOrId == SchedModel.getProcResource(I)->Name)
+ return I;
+ }
+ return 0;
+}
+
+std::vector<BenchmarkMeasure> ResolvedSchedClass::getAsPoint(
+ InstructionBenchmark::ModeE Mode, const llvm::MCSubtargetInfo &STI,
+ ArrayRef<PerInstructionStats> Representative) const {
+ const size_t NumMeasurements = Representative.size();
+
+ std::vector<BenchmarkMeasure> SchedClassPoint(NumMeasurements);
+
+ if (Mode == InstructionBenchmark::Latency) {
+ assert(NumMeasurements == 1 && "Latency is a single measure.");
+ BenchmarkMeasure &LatencyMeasure = SchedClassPoint[0];
+
+ // Find the latency.
+ LatencyMeasure.PerInstructionValue = 0.0;
+
+ for (unsigned I = 0; I < SCDesc->NumWriteLatencyEntries; ++I) {
+ const llvm::MCWriteLatencyEntry *const WLE =
+ STI.getWriteLatencyEntry(SCDesc, I);
+ LatencyMeasure.PerInstructionValue =
+ std::max<double>(LatencyMeasure.PerInstructionValue, WLE->Cycles);
+ }
+ } else if (Mode == InstructionBenchmark::Uops) {
+ for (const auto &I : llvm::zip(SchedClassPoint, Representative)) {
+ BenchmarkMeasure &Measure = std::get<0>(I);
+ const PerInstructionStats &Stats = std::get<1>(I);
+
+ StringRef Key = Stats.key();
+ uint16_t ProcResIdx = findProcResIdx(STI, Key);
+ if (ProcResIdx > 0) {
+ // Find the pressure on ProcResIdx `Key`.
+ const auto ProcResPressureIt = std::find_if(
+ IdealizedProcResPressure.begin(), IdealizedProcResPressure.end(),
+ [ProcResIdx](const std::pair<uint16_t, float> &WPR) {
+ return WPR.first == ProcResIdx;
+ });
+ Measure.PerInstructionValue =
+ ProcResPressureIt == IdealizedProcResPressure.end()
+ ? 0.0
+ : ProcResPressureIt->second;
+ } else if (Key == "NumMicroOps") {
+ Measure.PerInstructionValue = SCDesc->NumMicroOps;
+ } else {
+ llvm::errs() << "expected `key` to be either a ProcResIdx or a ProcRes "
+ "name, got "
+ << Key << "\n";
+ return {};
+ }
+ }
+ } else if (Mode == InstructionBenchmark::InverseThroughput) {
+ assert(NumMeasurements == 1 && "Inverse Throughput is a single measure.");
+ BenchmarkMeasure &RThroughputMeasure = SchedClassPoint[0];
+
+ RThroughputMeasure.PerInstructionValue =
+ MCSchedModel::getReciprocalThroughput(STI, *SCDesc);
+ } else {
+ llvm_unreachable("unimplemented measurement matching mode");
+ }
+
+ return SchedClassPoint;
+}
+
} // namespace exegesis
} // namespace llvm
OpenPOWER on IntegriCloud