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

Lakshay Kumar via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 4 01:19:00 PDT 2025


================
@@ -588,6 +594,100 @@ class SubProcessFunctionExecutorImpl
   const std::optional<int> BenchmarkProcessCPU;
 };
 #endif // __linux__
+
+// Helper function to print generated assembly snippets
+void printGeneratedAssembly(
+    const std::vector<std::pair<std::string, std::pair<uint64_t, std::string>>>
+        &Instructions,
+    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].second.first, 0) << ":\t"
+           << Instructions[i].second.second << Instructions[i].first << '\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].second.first, 0) << ":\t"
+               << Instructions[i].second.second << Instructions[i].first
+               << '\n';
+    }
+    // Print last "PreviewLast" lines
+    for (size_t i = N - PreviewLast; i < N; ++i)
+      dbgs() << format_hex_no_prefix(Instructions[i].second.first, 0) << ":\t"
+             << Instructions[i].second.second << Instructions[i].first << '\n';
+  }
+  dbgs() << "```\n";
+}
+
+// Function to extract and print assembly from snippet
+Error printAssembledSnippet(const LLVMState &State,
+                            const SmallString<0> &Snippet) {
+  // Extract the actual function bytes from the object file
+  std::vector<uint8_t> FunctionBytes;
+  if (auto Err = getBenchmarkFunctionBytes(Snippet, FunctionBytes))
+    return make_error<Failure>("Failed to extract function bytes: " +
+                               toString(std::move(Err)));
+
+  DisassemblerHelper DisHelper(State);
+  size_t Offset = 0;
+  const size_t FunctionBytesSize = FunctionBytes.size();
+
+  // Decode all instructions first
+  std::vector<std::pair<std::string, std::pair<uint64_t, std::string>>>
+      Instructions;
+  uint64_t Address = 0;
+
+  while (Offset < FunctionBytesSize) {
+    MCInst Inst;
+    uint64_t Size;
+    ArrayRef<uint8_t> Bytes(FunctionBytes.data() + Offset,
+                            FunctionBytesSize - Offset);
+
+    if (!DisHelper.decodeInst(Inst, Size, Bytes)) {
+      Instructions.push_back({"<decode error>", {Address, ""}});
+      break;
+    }
+
+    // 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()}});
+    Offset += Size;
+    Address += Size;
+  }
+
+  // Preview generated assembly snippet
+  {
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "preview-gen-assembly"
+    LLVM_DEBUG(dbgs() << "Generated assembly snippet:\n");
+    LLVM_DEBUG(printGeneratedAssembly(Instructions, true));
+#undef DEBUG_TYPE
+#define DEBUG_TYPE "print-gen-assembly"
+  }
+  // Print generated assembly snippet
+  {
----------------
lakshayk-nv wrote:

Removed debug logic, Introduced argument (`--print-gen-assembly`)

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


More information about the llvm-commits mailing list