diff options
author | Clement Courbet <courbet@google.com> | 2022-09-12 10:13:14 +0200 |
---|---|---|
committer | Clement Courbet <courbet@google.com> | 2022-09-22 11:11:18 +0200 |
commit | cc61c822e05c51e494c50d1e72f963750116ef08 (patch) | |
tree | eb6984e1d1433752236b96cb18156335d98300b9 /llvm/tools/llvm-exegesis/lib/Analysis.cpp | |
parent | 983cb53845efde4b2a142a3e520ebe30c6673515 (diff) | |
download | llvm-cc61c822e05c51e494c50d1e72f963750116ef08.zip llvm-cc61c822e05c51e494c50d1e72f963750116ef08.tar.gz llvm-cc61c822e05c51e494c50d1e72f963750116ef08.tar.bz2 |
[llvm-exegesis] Support analyzing results from a different target.
We were using the native triple to parse the benchmarks. Use the triple
from the benchmarks file.
Right now this still only allows analyzing files produced by the current
target until D133605 is in.
This also makes the `Analysis` class much less ad-hoc.
Differential Revision: https://reviews.llvm.org/D133697
Diffstat (limited to 'llvm/tools/llvm-exegesis/lib/Analysis.cpp')
-rw-r--r-- | llvm/tools/llvm-exegesis/lib/Analysis.cpp | 82 |
1 files changed, 37 insertions, 45 deletions
diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp index b12f872..d1ec125 100644 --- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp +++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp @@ -102,6 +102,7 @@ template <typename EscapeTag, EscapeTag Tag> void Analysis::writeSnippet(raw_ostream &OS, ArrayRef<uint8_t> Bytes, const char *Separator) const { SmallVector<std::string, 3> Lines; + const auto &SI = State_.getSubtargetInfo(); // Parse the asm snippet and print it. while (!Bytes.empty()) { MCInst MI; @@ -114,7 +115,7 @@ void Analysis::writeSnippet(raw_ostream &OS, ArrayRef<uint8_t> Bytes, } SmallString<128> InstPrinterStr; // FIXME: magic number. raw_svector_ostream OSS(InstPrinterStr); - InstPrinter_->printInst(&MI, 0, "", *SubtargetInfo_, OSS); + InstPrinter_->printInst(&MI, 0, "", SI, OSS); Bytes = Bytes.drop_front(MISize); Lines.emplace_back(InstPrinterStr.str().trim()); } @@ -136,10 +137,10 @@ void Analysis::printInstructionRowCsv(const size_t PointId, const MCInst &MCI = Point.keyInstruction(); unsigned SchedClassId; std::tie(SchedClassId, std::ignore) = ResolvedSchedClass::resolveSchedClassId( - *SubtargetInfo_, *InstrInfo_, MCI); + State_.getSubtargetInfo(), State_.getInstrInfo(), MCI); #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) const MCSchedClassDesc *const SCDesc = - SubtargetInfo_->getSchedModel().getSchedClassDesc(SchedClassId); + State_.getSubtargetInfo().getSchedModel().getSchedClassDesc(SchedClassId); writeEscaped<kEscapeCsv>(OS, SCDesc->Name); #else OS << SchedClassId; @@ -151,38 +152,30 @@ void Analysis::printInstructionRowCsv(const size_t PointId, OS << "\n"; } -Analysis::Analysis(const Target &Target, - std::unique_ptr<MCSubtargetInfo> SubtargetInfo, - std::unique_ptr<MCInstrInfo> InstrInfo, +Analysis::Analysis(const LLVMState &State, const InstructionBenchmarkClustering &Clustering, double AnalysisInconsistencyEpsilon, - bool AnalysisDisplayUnstableOpcodes, - const std::string &ForceCpuName) - : Clustering_(Clustering), SubtargetInfo_(std::move(SubtargetInfo)), - InstrInfo_(std::move(InstrInfo)), + bool AnalysisDisplayUnstableOpcodes) + : Clustering_(Clustering), State_(State), AnalysisInconsistencyEpsilonSquared_(AnalysisInconsistencyEpsilon * AnalysisInconsistencyEpsilon), AnalysisDisplayUnstableOpcodes_(AnalysisDisplayUnstableOpcodes) { if (Clustering.getPoints().empty()) return; - const InstructionBenchmark &FirstPoint = Clustering.getPoints().front(); - const std::string CpuName = - ForceCpuName.empty() ? FirstPoint.CpuName : ForceCpuName; - RegInfo_.reset(Target.createMCRegInfo(FirstPoint.LLVMTriple)); MCTargetOptions MCOptions; - AsmInfo_.reset( - Target.createMCAsmInfo(*RegInfo_, FirstPoint.LLVMTriple, MCOptions)); - SubtargetInfo_.reset( - Target.createMCSubtargetInfo(FirstPoint.LLVMTriple, CpuName, "")); - InstPrinter_.reset(Target.createMCInstPrinter( - Triple(FirstPoint.LLVMTriple), 0 /*default variant*/, *AsmInfo_, - *InstrInfo_, *RegInfo_)); - - Context_ = - std::make_unique<MCContext>(Triple(FirstPoint.LLVMTriple), AsmInfo_.get(), - RegInfo_.get(), SubtargetInfo_.get()); - Disasm_.reset(Target.createMCDisassembler(*SubtargetInfo_, *Context_)); + const auto &TM = State.getTargetMachine(); + const auto &Triple = TM.getTargetTriple(); + AsmInfo_.reset(TM.getTarget().createMCAsmInfo(State_.getRegInfo(), + Triple.str(), MCOptions)); + InstPrinter_.reset(TM.getTarget().createMCInstPrinter( + Triple, 0 /*default variant*/, *AsmInfo_, State_.getInstrInfo(), + State_.getRegInfo())); + + Context_ = std::make_unique<MCContext>( + Triple, AsmInfo_.get(), &State_.getRegInfo(), &State_.getSubtargetInfo()); + Disasm_.reset(TM.getTarget().createMCDisassembler(State_.getSubtargetInfo(), + *Context_)); assert(Disasm_ && "cannot create MCDisassembler. missing call to " "InitializeXXXTargetDisassembler ?"); } @@ -232,14 +225,14 @@ Analysis::makePointsPerSchedClass() const { unsigned SchedClassId; bool WasVariant; std::tie(SchedClassId, WasVariant) = - ResolvedSchedClass::resolveSchedClassId(*SubtargetInfo_, *InstrInfo_, - MCI); + ResolvedSchedClass::resolveSchedClassId(State_.getSubtargetInfo(), + State_.getInstrInfo(), MCI); const auto IndexIt = SchedClassIdToIndex.find(SchedClassId); if (IndexIt == SchedClassIdToIndex.end()) { // Create a new entry. SchedClassIdToIndex.emplace(SchedClassId, Entries.size()); - ResolvedSchedClassAndPoints Entry( - ResolvedSchedClass(*SubtargetInfo_, SchedClassId, WasVariant)); + ResolvedSchedClassAndPoints Entry(ResolvedSchedClass( + State_.getSubtargetInfo(), SchedClassId, WasVariant)); Entry.PointIds.push_back(PointId); Entries.push_back(std::move(Entry)); } else { @@ -284,11 +277,11 @@ void Analysis::printPointHtml(const InstructionBenchmark &Point, OS << "\">"; switch (Point.Mode) { case InstructionBenchmark::Latency: - writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_); + writeLatencySnippetHtml(OS, Point.Key.Instructions, State_.getInstrInfo()); break; case InstructionBenchmark::Uops: case InstructionBenchmark::InverseThroughput: - writeParallelSnippetHtml(OS, Point.Key.Instructions, *InstrInfo_); + writeParallelSnippetHtml(OS, Point.Key.Instructions, State_.getInstrInfo()); break; default: llvm_unreachable("invalid mode"); @@ -314,7 +307,8 @@ void Analysis::printSchedClassClustersHtml( OS << "</tr>"; for (const SchedClassCluster &Cluster : Clusters) { OS << "<tr class=\"" - << (Cluster.measurementsMatch(*SubtargetInfo_, RSC, Clustering_, + << (Cluster.measurementsMatch(State_.getSubtargetInfo(), RSC, + Clustering_, AnalysisInconsistencyEpsilonSquared_) ? "good-cluster" : "bad-cluster") @@ -383,15 +377,15 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC, "idealized unit resource (port) pressure assuming ideal " "distribution\">Idealized Resource Pressure</th></tr>"; if (RSC.SCDesc->isValid()) { - const auto &SM = SubtargetInfo_->getSchedModel(); + const auto &SI = State_.getSubtargetInfo(); + const auto &SM = SI.getSchedModel(); OS << "<tr><td>✔</td>"; OS << "<td>" << (RSC.WasVariant ? "✔" : "✕") << "</td>"; OS << "<td>" << RSC.SCDesc->NumMicroOps << "</td>"; // Latencies. OS << "<td><ul>"; for (int I = 0, E = RSC.SCDesc->NumWriteLatencyEntries; I < E; ++I) { - const auto *const Entry = - SubtargetInfo_->getWriteLatencyEntry(RSC.SCDesc, I); + const auto *const Entry = SI.getWriteLatencyEntry(RSC.SCDesc, I); OS << "<li>" << Entry->Cycles; if (RSC.SCDesc->NumWriteLatencyEntries > 1) { // Dismabiguate if more than 1 latency. @@ -403,8 +397,7 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC, // inverse throughput. OS << "<td>"; writeMeasurementValue<kEscapeHtml>( - OS, - MCSchedModel::getReciprocalThroughput(*SubtargetInfo_, *RSC.SCDesc)); + OS, MCSchedModel::getReciprocalThroughput(SI, *RSC.SCDesc)); OS << "</td>"; // WriteProcRes. OS << "<td><ul>"; @@ -419,9 +412,8 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC, OS << "<td><ul>"; for (const auto &Pressure : RSC.IdealizedProcResPressure) { OS << "<li><span class=\"mono\">"; - writeEscaped<kEscapeHtml>(OS, SubtargetInfo_->getSchedModel() - .getProcResource(Pressure.first) - ->Name); + writeEscaped<kEscapeHtml>( + OS, SI.getSchedModel().getProcResource(Pressure.first)->Name); OS << "</span>: "; writeMeasurementValue<kEscapeHtml>(OS, Pressure.second); OS << "</li>"; @@ -550,6 +542,7 @@ Error Analysis::run<Analysis::PrintSchedClassInconsistencies>( writeEscaped<kEscapeHtml>(OS, FirstPoint.CpuName); OS << "</span></h3>"; + const auto &SI = State_.getSubtargetInfo(); for (const auto &RSCAndPoints : makePointsPerSchedClass()) { if (!RSCAndPoints.RSC.SCDesc) continue; @@ -574,10 +567,9 @@ Error Analysis::run<Analysis::PrintSchedClassInconsistencies>( // Print any scheduling class that has at least one cluster that does not // match the checked-in data. - if (all_of(SchedClassClusters, [this, - &RSCAndPoints](const SchedClassCluster &C) { - return C.measurementsMatch(*SubtargetInfo_, RSCAndPoints.RSC, - Clustering_, + if (all_of(SchedClassClusters, [this, &RSCAndPoints, + &SI](const SchedClassCluster &C) { + return C.measurementsMatch(SI, RSCAndPoints.RSC, Clustering_, AnalysisInconsistencyEpsilonSquared_); })) continue; // Nothing weird. |