Skip to content

Commit

Permalink
Revert "[llvm-exegesis] Support analyzing results from a different ta…
Browse files Browse the repository at this point in the history
…rget."

Breaks MIPS compile.

This reverts commit cc61c82.
  • Loading branch information
legrosbuffle committed Sep 22, 2022
1 parent ab25ea6 commit 7daf60e
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 160 deletions.
82 changes: 45 additions & 37 deletions llvm/tools/llvm-exegesis/lib/Analysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ 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;
Expand All @@ -115,7 +114,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, "", SI, OSS);
InstPrinter_->printInst(&MI, 0, "", *SubtargetInfo_, OSS);
Bytes = Bytes.drop_front(MISize);
Lines.emplace_back(InstPrinterStr.str().trim());
}
Expand All @@ -137,10 +136,10 @@ void Analysis::printInstructionRowCsv(const size_t PointId,
const MCInst &MCI = Point.keyInstruction();
unsigned SchedClassId;
std::tie(SchedClassId, std::ignore) = ResolvedSchedClass::resolveSchedClassId(
State_.getSubtargetInfo(), State_.getInstrInfo(), MCI);
*SubtargetInfo_, *InstrInfo_, MCI);
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
const MCSchedClassDesc *const SCDesc =
State_.getSubtargetInfo().getSchedModel().getSchedClassDesc(SchedClassId);
SubtargetInfo_->getSchedModel().getSchedClassDesc(SchedClassId);
writeEscaped<kEscapeCsv>(OS, SCDesc->Name);
#else
OS << SchedClassId;
Expand All @@ -152,30 +151,38 @@ void Analysis::printInstructionRowCsv(const size_t PointId,
OS << "\n";
}

Analysis::Analysis(const LLVMState &State,
Analysis::Analysis(const Target &Target,
std::unique_ptr<MCSubtargetInfo> SubtargetInfo,
std::unique_ptr<MCInstrInfo> InstrInfo,
const InstructionBenchmarkClustering &Clustering,
double AnalysisInconsistencyEpsilon,
bool AnalysisDisplayUnstableOpcodes)
: Clustering_(Clustering), State_(State),
bool AnalysisDisplayUnstableOpcodes,
const std::string &ForceCpuName)
: Clustering_(Clustering), SubtargetInfo_(std::move(SubtargetInfo)),
InstrInfo_(std::move(InstrInfo)),
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;
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_));
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_));
assert(Disasm_ && "cannot create MCDisassembler. missing call to "
"InitializeXXXTargetDisassembler ?");
}
Expand Down Expand Up @@ -225,14 +232,14 @@ Analysis::makePointsPerSchedClass() const {
unsigned SchedClassId;
bool WasVariant;
std::tie(SchedClassId, WasVariant) =
ResolvedSchedClass::resolveSchedClassId(State_.getSubtargetInfo(),
State_.getInstrInfo(), MCI);
ResolvedSchedClass::resolveSchedClassId(*SubtargetInfo_, *InstrInfo_,
MCI);
const auto IndexIt = SchedClassIdToIndex.find(SchedClassId);
if (IndexIt == SchedClassIdToIndex.end()) {
// Create a new entry.
SchedClassIdToIndex.emplace(SchedClassId, Entries.size());
ResolvedSchedClassAndPoints Entry(ResolvedSchedClass(
State_.getSubtargetInfo(), SchedClassId, WasVariant));
ResolvedSchedClassAndPoints Entry(
ResolvedSchedClass(*SubtargetInfo_, SchedClassId, WasVariant));
Entry.PointIds.push_back(PointId);
Entries.push_back(std::move(Entry));
} else {
Expand Down Expand Up @@ -277,11 +284,11 @@ void Analysis::printPointHtml(const InstructionBenchmark &Point,
OS << "\">";
switch (Point.Mode) {
case InstructionBenchmark::Latency:
writeLatencySnippetHtml(OS, Point.Key.Instructions, State_.getInstrInfo());
writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
break;
case InstructionBenchmark::Uops:
case InstructionBenchmark::InverseThroughput:
writeParallelSnippetHtml(OS, Point.Key.Instructions, State_.getInstrInfo());
writeParallelSnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
break;
default:
llvm_unreachable("invalid mode");
Expand All @@ -307,8 +314,7 @@ void Analysis::printSchedClassClustersHtml(
OS << "</tr>";
for (const SchedClassCluster &Cluster : Clusters) {
OS << "<tr class=\""
<< (Cluster.measurementsMatch(State_.getSubtargetInfo(), RSC,
Clustering_,
<< (Cluster.measurementsMatch(*SubtargetInfo_, RSC, Clustering_,
AnalysisInconsistencyEpsilonSquared_)
? "good-cluster"
: "bad-cluster")
Expand Down Expand Up @@ -377,15 +383,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 &SI = State_.getSubtargetInfo();
const auto &SM = SI.getSchedModel();
const auto &SM = SubtargetInfo_->getSchedModel();
OS << "<tr><td>&#10004;</td>";
OS << "<td>" << (RSC.WasVariant ? "&#10004;" : "&#10005;") << "</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 = SI.getWriteLatencyEntry(RSC.SCDesc, I);
const auto *const Entry =
SubtargetInfo_->getWriteLatencyEntry(RSC.SCDesc, I);
OS << "<li>" << Entry->Cycles;
if (RSC.SCDesc->NumWriteLatencyEntries > 1) {
// Dismabiguate if more than 1 latency.
Expand All @@ -397,7 +403,8 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC,
// inverse throughput.
OS << "<td>";
writeMeasurementValue<kEscapeHtml>(
OS, MCSchedModel::getReciprocalThroughput(SI, *RSC.SCDesc));
OS,
MCSchedModel::getReciprocalThroughput(*SubtargetInfo_, *RSC.SCDesc));
OS << "</td>";
// WriteProcRes.
OS << "<td><ul>";
Expand All @@ -412,8 +419,9 @@ void Analysis::printSchedClassDescHtml(const ResolvedSchedClass &RSC,
OS << "<td><ul>";
for (const auto &Pressure : RSC.IdealizedProcResPressure) {
OS << "<li><span class=\"mono\">";
writeEscaped<kEscapeHtml>(
OS, SI.getSchedModel().getProcResource(Pressure.first)->Name);
writeEscaped<kEscapeHtml>(OS, SubtargetInfo_->getSchedModel()
.getProcResource(Pressure.first)
->Name);
OS << "</span>: ";
writeMeasurementValue<kEscapeHtml>(OS, Pressure.second);
OS << "</li>";
Expand Down Expand Up @@ -542,7 +550,6 @@ 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;
Expand All @@ -567,9 +574,10 @@ 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,
&SI](const SchedClassCluster &C) {
return C.measurementsMatch(SI, RSCAndPoints.RSC, Clustering_,
if (all_of(SchedClassClusters, [this,
&RSCAndPoints](const SchedClassCluster &C) {
return C.measurementsMatch(*SubtargetInfo_, RSCAndPoints.RSC,
Clustering_,
AnalysisInconsistencyEpsilonSquared_);
}))
continue; // Nothing weird.
Expand Down
10 changes: 7 additions & 3 deletions llvm/tools/llvm-exegesis/lib/Analysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@ namespace exegesis {
// A helper class to analyze benchmark results for a target.
class Analysis {
public:
Analysis(const LLVMState &State,
Analysis(const Target &Target, std::unique_ptr<MCSubtargetInfo> SubtargetInfo,
std::unique_ptr<MCInstrInfo> InstrInfo,
const InstructionBenchmarkClustering &Clustering,
double AnalysisInconsistencyEpsilon,
bool AnalysisDisplayUnstableOpcodes);
bool AnalysisDisplayUnstableOpcodes,
const std::string &ForceCpuName = "");

// Prints a csv of instructions for each cluster.
struct PrintClusters {};
Expand Down Expand Up @@ -111,8 +113,10 @@ class Analysis {
const char *Separator) const;

const InstructionBenchmarkClustering &Clustering_;
const LLVMState &State_;
std::unique_ptr<MCContext> Context_;
std::unique_ptr<MCSubtargetInfo> SubtargetInfo_;
std::unique_ptr<MCInstrInfo> InstrInfo_;
std::unique_ptr<MCRegisterInfo> RegInfo_;
std::unique_ptr<MCAsmInfo> AsmInfo_;
std::unique_ptr<MCInstPrinter> InstPrinter_;
std::unique_ptr<MCDisassembler> Disasm_;
Expand Down
86 changes: 32 additions & 54 deletions llvm/tools/llvm-exegesis/lib/BenchmarkResult.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,69 +327,47 @@ struct MappingContextTraits<exegesis::InstructionBenchmark, YamlContext> {
}
};

template <> struct MappingTraits<exegesis::InstructionBenchmark::TripleAndCpu> {
static void mapping(IO &Io,
exegesis::InstructionBenchmark::TripleAndCpu &Obj) {
assert(!Io.outputting() && "can only read TripleAndCpu");
// Read triple.
Io.mapRequired("llvm_triple", Obj.LLVMTriple);
Io.mapRequired("cpu_name", Obj.CpuName);
// Drop everything else.
}
};

} // namespace yaml

namespace exegesis {

Expected<std::set<InstructionBenchmark::TripleAndCpu>>
InstructionBenchmark::readTriplesAndCpusFromYamls(MemoryBufferRef Buffer) {
// We're only mapping a field, drop other fields and silence the corresponding
// warnings.
yaml::Input Yin(
Buffer, nullptr, +[](const SMDiagnostic &, void *Context) {});
Yin.setAllowUnknownKeys(true);
std::set<TripleAndCpu> Result;
yaml::EmptyContext Context;
while (Yin.setCurrentDocument()) {
TripleAndCpu TC;
yamlize(Yin, TC, /*unused*/ true, Context);
if (Yin.error())
return errorCodeToError(Yin.error());
Result.insert(TC);
Yin.nextDocument();
}
return Result;
}

Expected<InstructionBenchmark>
InstructionBenchmark::readYaml(const LLVMState &State, MemoryBufferRef Buffer) {
yaml::Input Yin(Buffer);
YamlContext Context(State);
InstructionBenchmark Benchmark;
if (Yin.setCurrentDocument())
yaml::yamlize(Yin, Benchmark, /*unused*/ true, Context);
if (!Context.getLastError().empty())
return make_error<Failure>(Context.getLastError());
return Benchmark;
InstructionBenchmark::readYaml(const LLVMState &State, StringRef Filename) {
if (auto ExpectedMemoryBuffer =
errorOrToExpected(MemoryBuffer::getFile(Filename, /*IsText=*/true))) {
yaml::Input Yin(*ExpectedMemoryBuffer.get());
YamlContext Context(State);
InstructionBenchmark Benchmark;
if (Yin.setCurrentDocument())
yaml::yamlize(Yin, Benchmark, /*unused*/ true, Context);
if (!Context.getLastError().empty())
return make_error<Failure>(Context.getLastError());
return Benchmark;
} else {
return ExpectedMemoryBuffer.takeError();
}
}

Expected<std::vector<InstructionBenchmark>>
InstructionBenchmark::readYamls(const LLVMState &State,
MemoryBufferRef Buffer) {
yaml::Input Yin(Buffer);
YamlContext Context(State);
std::vector<InstructionBenchmark> Benchmarks;
while (Yin.setCurrentDocument()) {
Benchmarks.emplace_back();
yamlize(Yin, Benchmarks.back(), /*unused*/ true, Context);
if (Yin.error())
return errorCodeToError(Yin.error());
if (!Context.getLastError().empty())
return make_error<Failure>(Context.getLastError());
Yin.nextDocument();
InstructionBenchmark::readYamls(const LLVMState &State, StringRef Filename) {
if (auto ExpectedMemoryBuffer =
errorOrToExpected(MemoryBuffer::getFile(Filename, /*IsText=*/true))) {
yaml::Input Yin(*ExpectedMemoryBuffer.get());
YamlContext Context(State);
std::vector<InstructionBenchmark> Benchmarks;
while (Yin.setCurrentDocument()) {
Benchmarks.emplace_back();
yamlize(Yin, Benchmarks.back(), /*unused*/ true, Context);
if (Yin.error())
return errorCodeToError(Yin.error());
if (!Context.getLastError().empty())
return make_error<Failure>(Context.getLastError());
Yin.nextDocument();
}
return Benchmarks;
} else {
return ExpectedMemoryBuffer.takeError();
}
return Benchmarks;
}

Error InstructionBenchmark::writeYamlTo(const LLVMState &State,
Expand Down
18 changes: 2 additions & 16 deletions llvm/tools/llvm-exegesis/lib/BenchmarkResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,10 @@
#include "RegisterValue.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstBuilder.h"
#include "llvm/Support/YAMLTraits.h"
#include <limits>
#include <set>
#include <string>
#include <unordered_map>
#include <vector>
Expand Down Expand Up @@ -80,22 +78,10 @@ struct InstructionBenchmark {
enum ResultAggregationModeE { Min, Max, Mean, MinVariance };
// Read functions.
static Expected<InstructionBenchmark> readYaml(const LLVMState &State,
MemoryBufferRef Buffer);
StringRef Filename);

static Expected<std::vector<InstructionBenchmark>>
readYamls(const LLVMState &State, MemoryBufferRef Buffer);

// Given a set of serialized instruction benchmarks, returns the set of
// triples and CPUs that appear in the list of benchmarks.
struct TripleAndCpu {
std::string LLVMTriple;
std::string CpuName;
bool operator<(const TripleAndCpu &O) const {
return std::tie(LLVMTriple, CpuName) < std::tie(O.LLVMTriple, O.CpuName);
}
};
static Expected<std::set<TripleAndCpu>>
readTriplesAndCpusFromYamls(MemoryBufferRef Buffer);
readYamls(const LLVMState &State, StringRef Filename);

class Error readYamlFrom(const LLVMState &State, StringRef InputContent);

Expand Down
Loading

0 comments on commit 7daf60e

Please sign in to comment.