[NFC][llvm-exegesis] Also promote getSchedClassPoint() into ResolvedSchedClass.

Summary:
It doesn't need anything from Analysis::SchedClassCluster class,
and takes ResolvedSchedClass as param, so this seems rather fitting.

Reviewers: courbet, gchatelet

Reviewed By: courbet

Subscribers: tschuett, llvm-commits

Tags: #llvm

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

llvm-svn: 357263
This commit is contained in:
Roman Lebedev 2019-03-29 14:58:01 +00:00
parent d6827ce3a3
commit 4d81e87765
4 changed files with 83 additions and 86 deletions

View File

@ -348,84 +348,6 @@ void Analysis::SchedClassCluster::addPoint(
Centroid.addPoint(Point.Measurements);
}
// 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> Analysis::SchedClassCluster::getSchedClassPoint(
InstructionBenchmark::ModeE Mode, const llvm::MCSubtargetInfo &STI,
const ResolvedSchedClass &RSC,
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 < RSC.SCDesc->NumWriteLatencyEntries; ++I) {
const llvm::MCWriteLatencyEntry *const WLE =
STI.getWriteLatencyEntry(RSC.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(RSC.IdealizedProcResPressure.begin(),
RSC.IdealizedProcResPressure.end(),
[ProcResIdx](const std::pair<uint16_t, float> &WPR) {
return WPR.first == ProcResIdx;
});
Measure.PerInstructionValue =
ProcResPressureIt == RSC.IdealizedProcResPressure.end()
? 0.0
: ProcResPressureIt->second;
} else if (Key == "NumMicroOps") {
Measure.PerInstructionValue = RSC.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, *RSC.SCDesc);
} else {
llvm_unreachable("unimplemented measurement matching mode");
}
return SchedClassPoint;
}
bool Analysis::SchedClassCluster::measurementsMatch(
const llvm::MCSubtargetInfo &STI, const ResolvedSchedClass &RSC,
const InstructionBenchmarkClustering &Clustering,
@ -440,7 +362,7 @@ bool Analysis::SchedClassCluster::measurementsMatch(
Centroid.getAsPoint();
const std::vector<BenchmarkMeasure> SchedClassPoint =
getSchedClassPoint(Mode, STI, RSC, Centroid.getStats());
RSC.getAsPoint(Mode, STI, Centroid.getStats());
if (SchedClassPoint.empty())
return false; // In Uops mode validate() may not be enough.

View File

@ -67,12 +67,6 @@ private:
// Return the cluster centroid.
const SchedClassClusterCentroid &getCentroid() const { return Centroid; }
std::vector<BenchmarkMeasure>
getSchedClassPoint(InstructionBenchmark::ModeE Mode,
const llvm::MCSubtargetInfo &STI,
const ResolvedSchedClass &SC,
ArrayRef<PerInstructionStats> Representative) const;
// Returns true if the cluster representative measurements match that of SC.
bool
measurementsMatch(const llvm::MCSubtargetInfo &STI,

View File

@ -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

View File

@ -7,13 +7,14 @@
//===----------------------------------------------------------------------===//
///
/// \file
/// Analysis output for benchmark results.
/// Resolution of MCInst sched class into expanded form for further analysis.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_TOOLS_LLVM_EXEGESIS_SCHEDCLASSRESOLUTION_H
#define LLVM_TOOLS_LLVM_EXEGESIS_SCHEDCLASSRESOLUTION_H
#include "BenchmarkResult.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
@ -44,6 +45,10 @@ struct ResolvedSchedClass {
const llvm::MCInstrInfo &InstrInfo,
const llvm::MCInst &MCI);
std::vector<BenchmarkMeasure>
getAsPoint(InstructionBenchmark::ModeE Mode, const llvm::MCSubtargetInfo &STI,
ArrayRef<PerInstructionStats> Representative) const;
const unsigned SchedClassId;
const llvm::MCSchedClassDesc *const SCDesc;
const bool WasVariant; // Whether the original class was variant.