mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[llvm-exegesis] Use BenchmarkResult::Instructions instead of OpcodeName
Summary: Get rid of OpcodeName. To remove the opcode name from an old file: ``` cat old_file | sed '/opcode_name.*/d' ``` Reviewers: gchatelet Subscribers: tschuett, llvm-commits Differential Revision: https://reviews.llvm.org/D48121 llvm-svn: 334691
This commit is contained in:
parent
51b6fc883d
commit
abd471f672
@ -20,7 +20,7 @@ static const char kCsvSep = ',';
|
||||
|
||||
namespace {
|
||||
|
||||
enum EscapeTag { kEscapeCsv, kEscapeHtml };
|
||||
enum EscapeTag { kEscapeCsv, kEscapeHtml, kEscapeHtmlString };
|
||||
|
||||
template <EscapeTag Tag>
|
||||
void writeEscaped(llvm::raw_ostream &OS, const llvm::StringRef S);
|
||||
@ -56,6 +56,16 @@ void writeEscaped<kEscapeHtml>(llvm::raw_ostream &OS, const llvm::StringRef S) {
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
void writeEscaped<kEscapeHtmlString>(llvm::raw_ostream &OS, const llvm::StringRef S) {
|
||||
for (const char C : S) {
|
||||
if (C == '"')
|
||||
OS << "\\\"";
|
||||
else
|
||||
OS << C;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
template <EscapeTag Tag>
|
||||
@ -75,6 +85,19 @@ static void writeMeasurementValue(llvm::raw_ostream &OS, const double Value) {
|
||||
writeEscaped<Tag>(OS, llvm::formatv("{0:F}", Value).str());
|
||||
}
|
||||
|
||||
template <EscapeTag Tag>
|
||||
static void writeSnippet(llvm::raw_ostream &OS,
|
||||
const std::vector<llvm::MCInst> &Instructions,
|
||||
const llvm::MCInstrInfo &InstrInfo,
|
||||
const char* Separator) {
|
||||
// FIXME: Print operands.
|
||||
llvm::SmallVector<llvm::StringRef, 3> Opcodes;
|
||||
for (const llvm::MCInst &Instr : Instructions) {
|
||||
Opcodes.push_back(InstrInfo.getName(Instr.getOpcode()));
|
||||
}
|
||||
writeEscaped<Tag>(OS, llvm::join(Opcodes, Separator));
|
||||
}
|
||||
|
||||
// Prints a row representing an instruction, along with scheduling info and
|
||||
// point coordinates (measurements).
|
||||
void Analysis::printInstructionRowCsv(const size_t PointId,
|
||||
@ -82,25 +105,22 @@ void Analysis::printInstructionRowCsv(const size_t PointId,
|
||||
const InstructionBenchmark &Point = Clustering_.getPoints()[PointId];
|
||||
writeClusterId<kEscapeCsv>(OS, Clustering_.getClusterIdForPoint(PointId));
|
||||
OS << kCsvSep;
|
||||
writeEscaped<kEscapeCsv>(OS, Point.Key.OpcodeName);
|
||||
writeSnippet<kEscapeCsv>(OS, Point.Key.Instructions, *InstrInfo_, "; ");
|
||||
OS << kCsvSep;
|
||||
writeEscaped<kEscapeCsv>(OS, Point.Key.Config);
|
||||
OS << kCsvSep;
|
||||
const auto OpcodeIt = MnemonicToOpcode_.find(Point.Key.OpcodeName);
|
||||
if (OpcodeIt != MnemonicToOpcode_.end()) {
|
||||
const unsigned SchedClassId =
|
||||
InstrInfo_->get(OpcodeIt->second).getSchedClass();
|
||||
assert(!Point.Key.Instructions.empty());
|
||||
// FIXME: Resolve variant classes.
|
||||
const unsigned SchedClassId =
|
||||
InstrInfo_->get(Point.Key.Instructions[0].getOpcode()).getSchedClass();
|
||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
|
||||
const auto &SchedModel = SubtargetInfo_->getSchedModel();
|
||||
const llvm::MCSchedClassDesc *const SCDesc =
|
||||
SchedModel.getSchedClassDesc(SchedClassId);
|
||||
writeEscaped<kEscapeCsv>(OS, SCDesc->Name);
|
||||
const auto &SchedModel = SubtargetInfo_->getSchedModel();
|
||||
const llvm::MCSchedClassDesc *const SCDesc =
|
||||
SchedModel.getSchedClassDesc(SchedClassId);
|
||||
writeEscaped<kEscapeCsv>(OS, SCDesc->Name);
|
||||
#else
|
||||
OS << SchedClassId;
|
||||
OS << SchedClassId;
|
||||
#endif
|
||||
}
|
||||
// FIXME: Print the sched class once InstructionBenchmark separates key into
|
||||
// (mnemonic, mode, opaque).
|
||||
for (const auto &Measurement : Point.Measurements) {
|
||||
OS << kCsvSep;
|
||||
writeMeasurementValue<kEscapeCsv>(OS, Measurement.Value);
|
||||
@ -118,10 +138,6 @@ Analysis::Analysis(const llvm::Target &Target,
|
||||
const InstructionBenchmark &FirstPoint = Clustering.getPoints().front();
|
||||
SubtargetInfo_.reset(Target.createMCSubtargetInfo(FirstPoint.LLVMTriple,
|
||||
FirstPoint.CpuName, ""));
|
||||
|
||||
// Build an index of mnemonic->opcode.
|
||||
for (int I = 0, E = InstrInfo_->getNumOpcodes(); I < E; ++I)
|
||||
MnemonicToOpcode_.emplace(InstrInfo_->getName(I), I);
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -158,16 +174,42 @@ Analysis::makePointsPerSchedClass() const {
|
||||
const InstructionBenchmark &Point = Points[PointId];
|
||||
if (!Point.Error.empty())
|
||||
continue;
|
||||
const auto OpcodeIt = MnemonicToOpcode_.find(Point.Key.OpcodeName);
|
||||
if (OpcodeIt == MnemonicToOpcode_.end())
|
||||
continue;
|
||||
const unsigned SchedClassId =
|
||||
InstrInfo_->get(OpcodeIt->second).getSchedClass();
|
||||
PointsPerSchedClass[SchedClassId].push_back(PointId);
|
||||
assert(!Point.Key.Instructions.empty());
|
||||
const auto Opcode = Point.Key.Instructions[0].getOpcode();
|
||||
// FIXME: Resolve variant classes.
|
||||
PointsPerSchedClass[InstrInfo_->get(Opcode).getSchedClass()].push_back(
|
||||
PointId);
|
||||
}
|
||||
return PointsPerSchedClass;
|
||||
}
|
||||
|
||||
// Uops repeat the same opcode over again. Just show this opcode and show the
|
||||
// whole snippet only on hover.
|
||||
static void writeUopsSnippetHtml(llvm::raw_ostream &OS,
|
||||
const std::vector<llvm::MCInst> &Instructions,
|
||||
const llvm::MCInstrInfo &InstrInfo) {
|
||||
if (Instructions.empty())
|
||||
return;
|
||||
writeEscaped<kEscapeHtml>(OS, InstrInfo.getName(Instructions[0].getOpcode()));
|
||||
if (Instructions.size() > 1)
|
||||
OS << " (x" << Instructions.size() << ")";
|
||||
}
|
||||
|
||||
// Latency tries to find a serial path. Just show the opcode path and show the
|
||||
// whole snippet only on hover.
|
||||
static void writeLatencySnippetHtml(llvm::raw_ostream &OS,
|
||||
const std::vector<llvm::MCInst> &Instructions,
|
||||
const llvm::MCInstrInfo &InstrInfo) {
|
||||
bool First = true;
|
||||
for (const llvm::MCInst &Instr : Instructions) {
|
||||
if (First)
|
||||
First = false;
|
||||
else
|
||||
OS << " → ";
|
||||
writeEscaped<kEscapeHtml>(OS, InstrInfo.getName(Instr.getOpcode()));
|
||||
}
|
||||
}
|
||||
|
||||
void Analysis::printSchedClassClustersHtml(
|
||||
const std::vector<SchedClassCluster> &Clusters, const SchedClass &SC,
|
||||
llvm::raw_ostream &OS) const {
|
||||
@ -195,8 +237,19 @@ void Analysis::printSchedClassClustersHtml(
|
||||
OS << "</td><td><ul>";
|
||||
for (const size_t PointId : Cluster.getPointIds()) {
|
||||
const auto &Point = Points[PointId];
|
||||
OS << "<li><span class=\"mono\">";
|
||||
writeEscaped<kEscapeHtml>(OS, Point.Key.OpcodeName);
|
||||
OS << "<li><span class=\"mono\" title=\"";
|
||||
writeSnippet<kEscapeHtmlString>(OS, Point.Key.Instructions, *InstrInfo_, "\n");
|
||||
OS << "\">";
|
||||
switch (Point.Mode) {
|
||||
case InstructionBenchmark::Latency:
|
||||
writeLatencySnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
|
||||
break;
|
||||
case InstructionBenchmark::Uops:
|
||||
writeUopsSnippetHtml(OS, Point.Key.Instructions, *InstrInfo_);
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("invalid mode");
|
||||
}
|
||||
OS << "</span> <span class=\"mono\">";
|
||||
writeEscaped<kEscapeHtml>(OS, Point.Key.Config);
|
||||
OS << "</span></li>";
|
||||
|
@ -140,8 +140,7 @@ struct ScalarEnumerationTraits<exegesis::InstructionBenchmark::ModeE> {
|
||||
|
||||
template <> struct MappingTraits<exegesis::InstructionBenchmarkKey> {
|
||||
static void mapping(IO &Io, exegesis::InstructionBenchmarkKey &Obj) {
|
||||
Io.mapRequired("opcode_name", Obj.OpcodeName);
|
||||
Io.mapOptional("instructions", Obj.Instructions);
|
||||
Io.mapRequired("instructions", Obj.Instructions);
|
||||
Io.mapOptional("config", Obj.Config);
|
||||
}
|
||||
};
|
||||
|
@ -32,7 +32,6 @@ struct BenchmarkResultContext; // Forward declaration.
|
||||
|
||||
struct InstructionBenchmarkKey {
|
||||
// The LLVM opcode name.
|
||||
std::string OpcodeName; // FIXME: Deprecated, use Instructions below.
|
||||
std::vector<llvm::MCInst> Instructions;
|
||||
// An opaque configuration, that can be used to separate several benchmarks of
|
||||
// the same instruction under different configurations.
|
||||
|
@ -62,7 +62,6 @@ InstructionBenchmark
|
||||
BenchmarkRunner::runOne(const BenchmarkConfiguration &Configuration,
|
||||
unsigned Opcode, unsigned NumRepetitions) const {
|
||||
InstructionBenchmark InstrBenchmark;
|
||||
InstrBenchmark.Key.OpcodeName = State.getInstrInfo().getName(Opcode);
|
||||
InstrBenchmark.Mode = getMode();
|
||||
InstrBenchmark.CpuName = State.getCpuName();
|
||||
InstrBenchmark.LLVMTriple = State.getTriple();
|
||||
|
@ -63,7 +63,6 @@ TEST(BenchmarkResultTest, WriteToAndReadFromDisk) {
|
||||
|
||||
InstructionBenchmark ToDisk;
|
||||
|
||||
ToDisk.Key.OpcodeName = "name";
|
||||
ToDisk.Key.Instructions.push_back(llvm::MCInstBuilder(kInstrId)
|
||||
.addReg(kReg1Id)
|
||||
.addReg(kReg2Id)
|
||||
@ -91,7 +90,6 @@ TEST(BenchmarkResultTest, WriteToAndReadFromDisk) {
|
||||
const auto FromDisk =
|
||||
ExitOnErr(InstructionBenchmark::readYaml(Ctx, Filename));
|
||||
|
||||
EXPECT_EQ(FromDisk.Key.OpcodeName, ToDisk.Key.OpcodeName);
|
||||
EXPECT_THAT(FromDisk.Key.Instructions,
|
||||
Pointwise(EqMCInst(), ToDisk.Key.Instructions));
|
||||
EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config);
|
||||
@ -109,7 +107,6 @@ TEST(BenchmarkResultTest, WriteToAndReadFromDisk) {
|
||||
ExitOnErr(InstructionBenchmark::readYamls(Ctx, Filename));
|
||||
ASSERT_EQ(FromDiskVector.size(), size_t{1});
|
||||
const auto FromDisk = FromDiskVector[0];
|
||||
EXPECT_EQ(FromDisk.Key.OpcodeName, ToDisk.Key.OpcodeName);
|
||||
EXPECT_THAT(FromDisk.Key.Instructions,
|
||||
Pointwise(EqMCInst(), ToDisk.Key.Instructions));
|
||||
EXPECT_EQ(FromDisk.Key.Config, ToDisk.Key.Config);
|
||||
|
Loading…
Reference in New Issue
Block a user