Skip to content

Commit a987b50

Browse files
committed
[llvm-exegesis] Introduced --print-gen-assembly=<> for number of lines to print
1 parent 989d7b0 commit a987b50

File tree

2 files changed

+56
-68
lines changed

2 files changed

+56
-68
lines changed
Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,12 @@
11
REQUIRES: aarch64-registered-target
22

3-
RUN: llvm-exegesis -mcpu=neoverse-v2 --benchmark-phase=measure --min-instructions=100 --mode=latency --debug-only="preview-gen-assembly" --opcode-name=ADDVv4i16v 2>&1 | FileCheck %s -check-prefix=PREVIEW
3+
RUN: llvm-exegesis -mcpu=neoverse-v2 --benchmark-phase=measure --min-instructions=100 --mode=latency --print-gen-assembly=10 --opcode-name=ADDVv4i16v 2>&1 | FileCheck %s -check-prefix=PREVIEW
44

55
PREVIEW: Generated assembly snippet:
66
PREVIEW-NEXT: ```
7-
PREVIEW: {{.*}} movi d{{[0-9]+}}, #0000000000000000
8-
PREVIEW-NEXT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
9-
PREVIEW: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
7+
PREVIEW: {{[04]}}: {{.*}} movi d{{[0-9]+}}, #0000000000000000
8+
PREVIEW-NEXT: {{[48]}}: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
109
PREVIEW: ... ({{[0-9]+}} more instructions)
1110
PREVIEW-NEXT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
1211
PREVIEW: {{.*}} ret
13-
PREVIEW-NEXT:```
14-
15-
RUN: llvm-exegesis -mcpu=neoverse-v2 --benchmark-phase=measure --min-instructions=100 --mode=latency --debug-only="print-gen-assembly" --opcode-name=ADDVv4i16v 2>&1 | FileCheck %s -check-prefix=PRINT
16-
17-
PRINT: Generated assembly snippet:
18-
PRINT-NEXT: ```
19-
PRINT: {{.*}} movi d{{[0-9]+}}, #0000000000000000
20-
PRINT: {{.*}} addv h{{[0-9]+}}, v{{[0-9]+}}.4h
21-
PRINT: {{.*}} ret
22-
PRINT-NEXT: ```
12+
PREVIEW-NEXT:```

llvm/tools/llvm-exegesis/lib/BenchmarkRunner.cpp

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/Twine.h"
2222
#include "llvm/Config/llvm-config.h" // for LLVM_ON_UNIX
2323
#include "llvm/MC/TargetRegistry.h"
24+
#include "llvm/Support/CommandLine.h"
2425
#include "llvm/Support/CrashRecoveryContext.h"
2526
#include "llvm/Support/Debug.h"
2627
#include "llvm/Support/Error.h"
@@ -59,6 +60,12 @@
5960
namespace llvm {
6061
namespace exegesis {
6162

63+
static cl::opt<int> PrintGenAssembly(
64+
"print-gen-assembly", cl::Optional, cl::init(0),
65+
cl::desc("Print generated assembly snippets. -1 prints all lines, "
66+
"positive N prints first N lines with truncated middle part"),
67+
cl::cat(BenchmarkOptions));
68+
6269
BenchmarkRunner::BenchmarkRunner(const LLVMState &State, Benchmark::ModeE Mode,
6370
BenchmarkPhaseSelectorE BenchmarkPhaseSelector,
6471
ExecutionModeE ExecutionMode,
@@ -595,35 +602,36 @@ class SubProcessFunctionExecutorImpl
595602
};
596603
#endif // __linux__
597604

605+
// Structure to hold instruction information for assembly printing
606+
struct InstructionInfo {
607+
std::string Text;
608+
uint64_t Address;
609+
std::string HexBytes;
610+
};
611+
598612
// Helper function to print generated assembly snippets
599-
void printGeneratedAssembly(
600-
const std::vector<std::pair<std::string, std::pair<uint64_t, std::string>>>
601-
&Instructions,
602-
bool Preview, size_t PreviewFirst = 10, size_t PreviewLast = 3) {
603-
dbgs() << "```\n";
604-
size_t N = Instructions.size();
605-
// Print first "PreviewFirst" lines or all if less
606-
for (size_t i = 0; i < std::min(size_t(PreviewFirst), N); ++i)
607-
dbgs() << format_hex_no_prefix(Instructions[i].second.first, 0) << ":\t"
608-
<< Instructions[i].second.second << Instructions[i].first << '\n';
609-
610-
if (N > (PreviewFirst + PreviewLast)) {
611-
if (Preview)
612-
dbgs() << "...\t(" << (N - PreviewFirst - PreviewLast)
613-
<< " more instructions)\n";
614-
else {
615-
// Print all middle lines
616-
for (size_t i = PreviewFirst; i < N - PreviewLast; ++i)
617-
dbgs() << format_hex_no_prefix(Instructions[i].second.first, 0) << ":\t"
618-
<< Instructions[i].second.second << Instructions[i].first
619-
<< '\n';
620-
}
621-
// Print last "PreviewLast" lines
622-
for (size_t i = N - PreviewLast; i < N; ++i)
623-
dbgs() << format_hex_no_prefix(Instructions[i].second.first, 0) << ":\t"
624-
<< Instructions[i].second.second << Instructions[i].first << '\n';
625-
}
626-
dbgs() << "```\n";
613+
void printInstructions(const std::vector<InstructionInfo> &Instructions,
614+
int InitialLinesCount, int LastLinesCount) {
615+
int N = Instructions.size();
616+
outs() << "Generated assembly snippet:\n```\n";
617+
618+
// Print initial lines
619+
for (int i = 0; i < InitialLinesCount; ++i)
620+
outs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
621+
<< Instructions[i].HexBytes << Instructions[i].Text << '\n';
622+
623+
// Show truncation message if needed
624+
int SkippedInstructions = N - InitialLinesCount - LastLinesCount;
625+
if (SkippedInstructions > 0)
626+
outs() << "...\t(" << SkippedInstructions << " more instructions)\n";
627+
628+
// Print last min(PreviewLast, N - PreviewFirst) lines
629+
int LastLinesToPrint = std::min(
630+
LastLinesCount, N > InitialLinesCount ? N - InitialLinesCount : 0);
631+
for (int i = N - LastLinesToPrint; i < N; ++i)
632+
outs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
633+
<< Instructions[i].HexBytes << Instructions[i].Text << '\n';
634+
outs() << "```\n";
627635
}
628636

629637
// Function to extract and print assembly from snippet
@@ -635,23 +643,20 @@ Error printAssembledSnippet(const LLVMState &State,
635643
return make_error<Failure>("Failed to extract function bytes: " +
636644
toString(std::move(Err)));
637645

638-
DisassemblerHelper DisHelper(State);
639-
size_t Offset = 0;
640-
const size_t FunctionBytesSize = FunctionBytes.size();
641-
642646
// Decode all instructions first
643-
std::vector<std::pair<std::string, std::pair<uint64_t, std::string>>>
644-
Instructions;
647+
DisassemblerHelper DisHelper(State);
645648
uint64_t Address = 0;
649+
std::vector<InstructionInfo> Instructions;
650+
const size_t FunctionBytesSize = FunctionBytes.size();
646651

647-
while (Offset < FunctionBytesSize) {
652+
while (Address < FunctionBytesSize) {
648653
MCInst Inst;
649654
uint64_t Size;
650-
ArrayRef<uint8_t> Bytes(FunctionBytes.data() + Offset,
651-
FunctionBytesSize - Offset);
655+
ArrayRef<uint8_t> Bytes(FunctionBytes.data() + Address,
656+
FunctionBytesSize - Address);
652657

653658
if (!DisHelper.decodeInst(Inst, Size, Bytes)) {
654-
Instructions.push_back({"<decode error>", {Address, ""}});
659+
Instructions.push_back({"<decode error>", Address, ""});
655660
break;
656661
}
657662

@@ -666,26 +671,19 @@ Error printAssembledSnippet(const LLVMState &State,
666671
for (int i = Size - 1; i >= 0; --i)
667672
HexOS << format_hex_no_prefix(Bytes[i], 2);
668673

669-
Instructions.push_back({OS.str(), {Address, HexOS.str()}});
670-
Offset += Size;
674+
Instructions.push_back({OS.str(), Address, HexOS.str()});
671675
Address += Size;
672676
}
673677

674-
// Preview generated assembly snippet
675-
{
676-
#undef DEBUG_TYPE
677-
#define DEBUG_TYPE "preview-gen-assembly"
678-
LLVM_DEBUG(dbgs() << "Generated assembly snippet:\n");
679-
LLVM_DEBUG(printGeneratedAssembly(Instructions, true));
680-
#undef DEBUG_TYPE
681-
#define DEBUG_TYPE "print-gen-assembly"
682-
}
683-
// Print generated assembly snippet
684-
{
685-
LLVM_DEBUG(dbgs() << "Generated assembly snippet:\n");
686-
LLVM_DEBUG(printGeneratedAssembly(Instructions, false));
687-
}
678+
if (PrintGenAssembly == 0 || PrintGenAssembly < -1)
679+
return Error::success();
688680

681+
int InitialLinesCount = PrintGenAssembly;
682+
int LastLinesCount = 3;
683+
if (PrintGenAssembly == -1 ||
684+
PrintGenAssembly > static_cast<int>(Instructions.size()))
685+
InitialLinesCount = Instructions.size() - LastLinesCount;
686+
printInstructions(Instructions, InitialLinesCount, LastLinesCount);
689687
return Error::success();
690688
}
691689
} // namespace

0 commit comments

Comments
 (0)