forked from OSchip/llvm-project
[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:
parent
d6827ce3a3
commit
4d81e87765
|
@ -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.
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue