[llvm-exegesis] Print the whole snippet in analysis.
Summary:
On hover, the whole asm snippet is displayed, including operands.
This requires the actual assembly output instead of just the MCInsts:
This is because some pseudo-instructions get lowered to actual target
instructions during codegen (e.g. ABS_Fp32 -> SSE or X87).
Reviewers: gchatelet
Subscribers: mgorny, tschuett, llvm-commits
Differential Revision: https://reviews.llvm.org/D48164
llvm-svn: 334805
diff --git a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
index bed802d..188ee2d 100644
--- a/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
+++ b/llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp
@@ -74,24 +74,41 @@
return InstrBenchmark;
}
- for (const auto &MCInst : Snippet)
- InstrBenchmark.Key.Instructions.push_back(MCInst);
+ InstrBenchmark.Key.Instructions = Snippet;
- std::vector<llvm::MCInst> Code;
- for (int I = 0; I < InstrBenchmark.NumRepetitions; ++I)
- Code.push_back(Snippet[I % Snippet.size()]);
+ // Repeat the snippet until there are at least NumInstructions in the
+ // resulting code. The snippet is always repeated at least once.
+ const auto GenerateInstructions = [&Snippet](const int MinInstructions) {
+ std::vector<llvm::MCInst> Code = Snippet;
+ for (int I = 0; I < MinInstructions; ++I)
+ Code.push_back(Snippet[I % Snippet.size()]);
+ return Code;
+ };
- auto ExpectedObjectPath = writeObjectFile(Code);
- if (llvm::Error E = ExpectedObjectPath.takeError()) {
+ // Assemble at least kMinInstructionsForSnippet instructions by repeating the
+ // snippet for debug/analysis. This is so that the user clearly understands
+ // that the inside instructions are repeated.
+ constexpr const int kMinInstructionsForSnippet = 16;
+ {
+ auto EF = createExecutableFunction(
+ GenerateInstructions(kMinInstructionsForSnippet));
+ if (llvm::Error E = EF.takeError()) {
+ InstrBenchmark.Error = llvm::toString(std::move(E));
+ return InstrBenchmark;
+ }
+ const auto FnBytes = EF->getFunctionBytes();
+ InstrBenchmark.AssembledSnippet.assign(FnBytes.begin(), FnBytes.end());
+ }
+
+ // Assemble NumRepetitions instructions repetitions of the snippet for
+ // measurements.
+ auto EF = createExecutableFunction(
+ GenerateInstructions(InstrBenchmark.NumRepetitions));
+ if (llvm::Error E = EF.takeError()) {
InstrBenchmark.Error = llvm::toString(std::move(E));
return InstrBenchmark;
}
-
- // FIXME: Check if TargetMachine or ExecutionEngine can be reused instead of
- // creating one everytime.
- const ExecutableFunction EF(State.createTargetMachine(),
- getObjectFromFile(*ExpectedObjectPath));
- InstrBenchmark.Measurements = runMeasurements(EF, NumRepetitions);
+ InstrBenchmark.Measurements = runMeasurements(*EF, NumRepetitions);
return InstrBenchmark;
}
@@ -110,4 +127,17 @@
return ResultPath.str();
}
+llvm::Expected<ExecutableFunction> BenchmarkRunner::createExecutableFunction(
+ llvm::ArrayRef<llvm::MCInst> Code) const {
+ auto ExpectedObjectPath = writeObjectFile(Code);
+ if (llvm::Error E = ExpectedObjectPath.takeError()) {
+ return std::move(E);
+ }
+
+ // FIXME: Check if TargetMachine or ExecutionEngine can be reused instead of
+ // creating one everytime.
+ return ExecutableFunction(State.createTargetMachine(),
+ getObjectFromFile(*ExpectedObjectPath));
+}
+
} // namespace exegesis