1
0
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:
Clement Courbet 2018-06-14 06:57:52 +00:00
parent 51b6fc883d
commit abd471f672
5 changed files with 80 additions and 33 deletions

View File

@ -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 << " &rarr; ";
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>";

View File

@ -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);
}
};

View File

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

View File

@ -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();

View File

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