diff options
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/SchedClassResolution.cpp | 76 |
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 |