[llvm] [llvm-exegesis] Debug generated disassembly (PR #142540)

Lakshay Kumar via llvm-commits llvm-commits at lists.llvm.org
Tue Jul 1 03:59:49 PDT 2025


================
@@ -655,6 +660,96 @@ BenchmarkRunner::getRunnableConfiguration(
     if (Error E = Snippet.takeError())
       return std::move(E);
     RC.ObjectFile = getObjectFromBuffer(*Snippet);
+
+    // Print the assembled snippet by disassembling the binary data
+    // Extract the actual function bytes from the object file
+    std::vector<uint8_t> FunctionBytes;
+    if (auto Err = getBenchmarkFunctionBytes(*Snippet, FunctionBytes)) {
+      dbgs() << "Failed to extract function bytes: " << toString(std::move(Err))
+             << "\n";
+    } else {
+      DisassemblerHelper DisHelper(State);
+      ArrayRef<uint8_t> Bytes(FunctionBytes);
+
+      // Decode all instructions first
+      struct InstructionInfo {
+        std::string Text;
+        uint64_t Address;
+        std::string HexBytes;
+      };
+      std::vector<InstructionInfo> Instructions;
+      uint64_t Address = 0;
+
+      while (!Bytes.empty()) {
+        MCInst Inst;
+        uint64_t Size;
+        if (DisHelper.decodeInst(Inst, Size, Bytes)) {
+          // Format instruction text
+          std::string InstStr;
+          raw_string_ostream OS(InstStr);
+          DisHelper.printInst(&Inst, OS);
+
+          // Create hex string for this instruction (big-endian order)
+          std::string HexStr;
+          raw_string_ostream HexOS(HexStr);
+          for (int i = Size - 1; i >= 0; --i) {
+            HexOS << format_hex_no_prefix(Bytes[i], 2);
+          }
+
+          Instructions.push_back({OS.str(), Address, HexOS.str()});
+          Bytes = Bytes.slice(Size);
+          Address += Size;
+        } else {
+          Instructions.push_back({"<decode error>", Address, ""});
+          break;
+        }
+      }
+
+      auto printSnippet = [&](bool Preview, size_t PreviewFirst = 10,
+                              size_t PreviewLast = 3) {
+        dbgs() << "```\n";
+        size_t N = Instructions.size();
+        // Print first "PreviewFirst" lines or all if less
+        for (size_t i = 0; i < std::min(size_t(PreviewFirst), N); ++i) {
+          dbgs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
+                 << Instructions[i].HexBytes << Instructions[i].Text << '\n';
+        }
+        if (N > (PreviewFirst + PreviewLast)) {
+          if (Preview) {
+            dbgs() << "...\t(" << (N - PreviewFirst - PreviewLast)
+                   << " more instructions)\n";
+          } else {
+            // Print all middle lines
+            for (size_t i = PreviewFirst; i < N - PreviewLast; ++i) {
+              dbgs() << format_hex_no_prefix(Instructions[i].Address, 0)
+                     << ":\t" << Instructions[i].HexBytes
+                     << Instructions[i].Text << '\n';
+            }
+          }
+          // Print last "PreviewLast" lines
+          for (size_t i = N - PreviewLast; i < N; ++i) {
+            dbgs() << format_hex_no_prefix(Instructions[i].Address, 0) << ":\t"
+                   << Instructions[i].HexBytes << Instructions[i].Text << '\n';
+          }
+        }
+        dbgs() << "```\n";
+      };
+
+      // Preview generated assembly snippet
+      {
----------------
lakshayk-nv wrote:

> And --debug-only="preview-gen-assembly" only works with a debug build?
>>
Not sure, Let me get back to you on this.

>I would prefer to just flip a switch and option, similar to --dump-object-to-disk, so that this works in any build.
>>
Based on above we have look into this.

https://github.com/llvm/llvm-project/pull/142540


More information about the llvm-commits mailing list