Skip to content

Reland "[IR] Use persistent metadata IDs for printing" - #220390

Merged
yxsamliu merged 1 commit into
llvm:mainfrom
yxsamliu:amd/dev/yaxunl/PR-216838-persistent-metadata-ids-reland-main
Sep 2, 2026
Merged

yxsamliu merged 1 commit into
llvm:mainfrom
yxsamliu:amd/dev/yaxunl/PR-216838-persistent-metadata-ids-reland-main

Conversation

@yxsamliu

@yxsamliu yxsamliu commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268

@llvmorg-github-actions

llvmorg-github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

@llvm/pr-subscribers-clangir
@llvm/pr-subscribers-flang-codegen
@llvm/pr-subscribers-llvm-ir
@llvm/pr-subscribers-flang-driver
@llvm/pr-subscribers-mlir
@llvm/pr-subscribers-flang-fir-hlfir
@llvm/pr-subscribers-mlir-llvm
@llvm/pr-subscribers-debuginfo
@llvm/pr-subscribers-clang-codegen

@llvm/pr-subscribers-backend-amdgpu

Author: Yaxun (Sam) Liu (yxsamliu)

Changes

This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268


Patch is 164.11 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/220390.diff

75 Files Affected:

  • (modified) clang/lib/CodeGen/BackendUtil.cpp (+5-2)
  • (modified) clang/tools/cir-translate/cir-translate.cpp (+1)
  • (modified) clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp (+4-1)
  • (modified) clang/tools/clang-import-test/clang-import-test.cpp (+3-1)
  • (modified) flang/include/flang/Optimizer/CodeGen/CodeGen.h (+5-3)
  • (modified) flang/lib/Frontend/FrontendActions.cpp (+3-3)
  • (modified) llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h (+11-12)
  • (modified) llvm/include/llvm/IR/IRPrintingPasses.h (+5)
  • (modified) llvm/include/llvm/IR/Metadata.h (+5-5)
  • (modified) llvm/include/llvm/IR/Module.h (+5)
  • (modified) llvm/include/llvm/IR/ModuleSlotTracker.h (+33-19)
  • (modified) llvm/include/llvm/IRPrinter/IRPrintingPasses.h (+5-2)
  • (modified) llvm/lib/CodeGen/MIRParser/MIParser.cpp (+2-2)
  • (modified) llvm/lib/CodeGen/MIRPrintingPass.cpp (+16)
  • (modified) llvm/lib/CodeGen/MachineBasicBlock.cpp (+1-1)
  • (modified) llvm/lib/CodeGen/MachineModuleSlotTracker.cpp (+61-55)
  • (modified) llvm/lib/CodeGen/MachineOperand.cpp (+1-1)
  • (modified) llvm/lib/IR/AsmWriter.cpp (+235-177)
  • (modified) llvm/lib/IR/Core.cpp (+2)
  • (modified) llvm/lib/IR/IRPrintingPasses.cpp (+46-25)
  • (modified) llvm/lib/IR/LLVMContextImpl.cpp (+9)
  • (modified) llvm/lib/IR/LLVMContextImpl.h (+18)
  • (modified) llvm/lib/IR/Metadata.cpp (+17)
  • (modified) llvm/lib/IR/MetadataImpl.h (+2)
  • (modified) llvm/lib/IR/SSAContext.cpp (+1-1)
  • (modified) llvm/lib/IRPrinter/IRPrintingPasses.cpp (+14-6)
  • (modified) llvm/lib/Target/DirectX/DXILPrettyPrinter.cpp (+95-17)
  • (modified) llvm/test/CodeGen/DirectX/DebugInfo/di-globalvariable.ll (+7)
  • (modified) llvm/test/CodeGen/Hexagon/swp-no-alias.mir (+4-4)
  • (modified) llvm/test/CodeGen/MIR/AMDGPU/instr-mmra.mir (+1-1)
  • (modified) llvm/test/CodeGen/MIR/AMDGPU/machine-metadata.mir (+6-6)
  • (modified) llvm/test/CodeGen/MIR/X86/instr-heap-alloc-operands.mir (+1-1)
  • (modified) llvm/test/CodeGen/MIR/X86/instr-pcsections.mir (+1-1)
  • (modified) llvm/test/CodeGen/MIR/X86/instructions-debug-location.mir (+7-7)
  • (modified) llvm/test/CodeGen/MIR/X86/machine-metadata.mir (+18-18)
  • (modified) llvm/test/CodeGen/MIR/X86/mem-cache-hint.mir (+2-2)
  • (modified) llvm/test/CodeGen/MIR/X86/memory-operands.mir (+5-5)
  • (modified) llvm/test/CodeGen/MIR/X86/metadata-operands.mir (+1-1)
  • (modified) llvm/test/CodeGen/MIR/X86/pr38773.mir (+2-2)
  • (modified) llvm/test/CodeGen/MIR/X86/stack-object-debug-info.mir (+2-2)
  • (modified) llvm/test/DebugInfo/MIR/AArch64/no-dbg-value-after-terminator.mir (+1-1)
  • (modified) llvm/test/Other/legacy-callgraph-scc-pass-printer.ll (+12-1)
  • (added) llvm/test/Other/print-changed-persistent-metadata-ids.ll (+77)
  • (added) llvm/test/Other/print-persistent-metadata-ids.ll (+94)
  • (modified) llvm/test/tools/UpdateTestChecks/update_analyze_test_checks/Inputs/loop-distribute.ll.expected (+3-3)
  • (modified) llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-print-basic-details.test (+11-11)
  • (modified) llvm/test/tools/llvm-debuginfo-analyzer/IR/01-ir-select-logical-elements.test (+8-8)
  • (modified) llvm/test/tools/llvm-debuginfo-analyzer/IR/02-ir-logical-lines.test (+2-2)
  • (modified) llvm/test/tools/llvm-debuginfo-analyzer/IR/06-ir-full-logical-view.test (+11-11)
  • (modified) llvm/tools/llvm-dis/llvm-dis.cpp (+1)
  • (modified) llvm/tools/llvm-extract/llvm-extract.cpp (+4-2)
  • (modified) llvm/tools/llvm-link/llvm-link.cpp (+1)
  • (modified) llvm/tools/llvm-reduce/ReducerWorkItem.cpp (+8-1)
  • (modified) llvm/tools/llvm-split/llvm-split.cpp (+4-3)
  • (modified) llvm/tools/llvm-stress/llvm-stress.cpp (+1)
  • (modified) llvm/tools/opt/NewPMDriver.cpp (+2-1)
  • (modified) llvm/tools/opt/optdriver.cpp (+4-3)
  • (modified) llvm/tools/verify-uselistorder/verify-uselistorder.cpp (+5-4)
  • (modified) llvm/unittests/AsmParser/AsmParserTest.cpp (+33)
  • (modified) llvm/unittests/IR/AsmWriterTest.cpp (+124)
  • (modified) llvm/unittests/IR/MetadataTest.cpp (+7-11)
  • (modified) llvm/unittests/IR/ModuleTest.cpp (+55)
  • (modified) llvm/unittests/MIR/MachineMetadata.cpp (+78-29)
  • (modified) mlir/lib/Target/LLVMIR/ConvertToLLVMIR.cpp (+1)
  • (modified) mlir/test/Target/LLVMIR/Import/import-failure.ll (+12-12)
  • (modified) polly/test/ForwardOpTree/atax.ll (+8-8)
  • (modified) polly/test/ForwardOpTree/jacobi-1d.ll (+4-4)
  • (modified) polly/test/ScopInfo/preserve-equiv-class-order-in-basic_block.ll (+2-2)
  • (modified) polly/test/ScopInfo/stmt_split_exit_of_region_stmt.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_no_after_split.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_no_dependence.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_phi_in_beginning_bb.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_phi_in_stmt.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_scalar_dependence.ll (+1-1)
  • (modified) polly/test/ScopInfo/stmt_split_within_loop.ll (+1-1)
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 6aa6bc1bd41e8..086f886be4390 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1166,7 +1166,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
             *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
       } else if (Action == Backend_EmitLL) {
         MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
-                                    /*EmitLTOSummary=*/true));
+                                    /*EmitLTOSummary=*/true,
+                                    /*ShouldRenumberMetadata=*/true));
       }
     } else {
       // Emit a module summary by default for Regular LTO except for ld64
@@ -1184,7 +1185,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
                                       EmitLTOSummary));
       } else if (Action == Backend_EmitLL) {
         MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
-                                    EmitLTOSummary));
+                                    EmitLTOSummary,
+                                    /*ShouldRenumberMetadata=*/true));
       }
     }
 
@@ -1456,6 +1458,7 @@ runThinLTOBackend(CompilerInstance &CI, ModuleSummaryIndex *CombinedIndex,
     break;
   case Backend_EmitLL:
     Conf.PreCodeGenModuleHook = [&](size_t Task, const llvm::Module &Mod) {
+      M->renumberMetadataForAssembly();
       M->print(*OS, nullptr, CGOpts.EmitLLVMUseLists);
       return false;
     };
diff --git a/clang/tools/cir-translate/cir-translate.cpp b/clang/tools/cir-translate/cir-translate.cpp
index 4452741d7433e..a58512e3fca22 100644
--- a/clang/tools/cir-translate/cir-translate.cpp
+++ b/clang/tools/cir-translate/cir-translate.cpp
@@ -165,6 +165,7 @@ void registerToLLVMTranslation() {
                                                       enableOpenMP);
         if (!llvmModule)
           return mlir::failure();
+        llvmModule->renumberMetadataForAssembly();
         llvmModule->print(output, nullptr);
         return mlir::success();
       },
diff --git a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
index 942e35c30e19f..1c745bffe00c0 100644
--- a/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
+++ b/clang/tools/clang-fuzzer/handle-llvm/handle_llvm.cpp
@@ -103,7 +103,10 @@ static void RunOptimizationPasses(raw_ostream &OS, Module &M,
   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
 
   ModulePassManager MPM = PB.buildPerModuleDefaultPipeline(OL);
-  MPM.addPass(PrintModulePass(OS));
+  MPM.addPass(PrintModulePass(OS, /*Banner=*/"",
+                              /*ShouldPreserveUseListOrder=*/false,
+                              /*EmitSummaryIndex=*/false,
+                              /*ShouldRenumberMetadata=*/true));
 
   MPM.run(M, MAM);
 }
diff --git a/clang/tools/clang-import-test/clang-import-test.cpp b/clang/tools/clang-import-test/clang-import-test.cpp
index 8e83687d3e96a..bcb5d2bdb8952 100644
--- a/clang/tools/clang-import-test/clang-import-test.cpp
+++ b/clang/tools/clang-import-test/clang-import-test.cpp
@@ -338,8 +338,10 @@ llvm::Expected<CIAndOrigins> Parse(const std::string &Path,
   if (llvm::Error PE = ParseSource(Path, CI.getCompilerInstance(), Consumers))
     return std::move(PE);
   CI.getDiagnosticClient().EndSourceFile();
-  if (ShouldDumpIR)
+  if (ShouldDumpIR) {
+    CG.GetModule()->renumberMetadataForAssembly();
     CG.GetModule()->print(llvm::outs(), nullptr);
+  }
   if (CI.getDiagnosticClient().getNumErrors())
     return llvm::make_error<llvm::StringError>(
         "Errors occurred while parsing the expression.", std::error_code());
diff --git a/flang/include/flang/Optimizer/CodeGen/CodeGen.h b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
index 1d36788fb84f9..6ef575f5391d9 100644
--- a/flang/include/flang/Optimizer/CodeGen/CodeGen.h
+++ b/flang/include/flang/Optimizer/CodeGen/CodeGen.h
@@ -90,9 +90,11 @@ using LLVMIRLoweringPrinter =
 
 /// Convert the LLVM IR dialect to LLVM-IR proper
 std::unique_ptr<mlir::Pass> createLLVMDialectToLLVMPass(
-    llvm::raw_ostream &output,
-    LLVMIRLoweringPrinter printer =
-        [](llvm::Module &m, llvm::raw_ostream &out) { m.print(out, nullptr); });
+    llvm::raw_ostream &output, LLVMIRLoweringPrinter printer =
+                                   [](llvm::Module &m, llvm::raw_ostream &out) {
+                                     m.renumberMetadataForAssembly();
+                                     m.print(out, nullptr);
+                                   });
 
 /// Populate the given list with patterns that convert from FIR to LLVM.
 void populateFIRToLLVMConversionPatterns(
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 35e0e4004d9a0..108b1b4559d48 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -1094,9 +1094,9 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
             os, /*ShouldPreserveUseListOrder=*/false, emitSummary));
       }
     } else if (action == BackendActionTy::Backend_EmitLL) {
-      mpm.addPass(llvm::PrintModulePass(os, /*Banner=*/"",
-                                        /*ShouldPreserveUseListOrder=*/false,
-                                        emitSummary));
+      mpm.addPass(llvm::PrintModulePass(
+          os, /*Banner=*/"", /*ShouldPreserveUseListOrder=*/false, emitSummary,
+          /*ShouldRenumberMetadata=*/true));
     }
   }
 
diff --git a/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h b/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
index 666b3caf67e27..7f52727cfef81 100644
--- a/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
+++ b/llvm/include/llvm/CodeGen/MachineModuleSlotTracker.h
@@ -10,12 +10,13 @@
 #define LLVM_CODEGEN_MACHINEMODULESLOTTRACKER_H
 
 #include "llvm/ADT/STLFunctionalExtras.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/IR/ModuleSlotTracker.h"
 #include "llvm/Support/Compiler.h"
 
 namespace llvm {
 
-class AbstractSlotTrackerStorage;
 class Function;
 class MachineModuleInfo;
 class MachineFunction;
@@ -24,24 +25,22 @@ class Module;
 using MFGetterFnT = function_ref<MachineFunction *(const Function &)>;
 
 class LLVM_ABI MachineModuleSlotTracker : public ModuleSlotTracker {
-  const Function &TheFunction;
   const MachineFunction *TheMF;
-  unsigned MDNStartSlot = 0, MDNEndSlot = 0;
+  MachineMDNodeListType MachineMDNodes;
+  SmallPtrSet<const DILocation *, 4> InlineDebugLocations;
 
-  void processMachineFunctionMetadata(AbstractSlotTrackerStorage *AST,
-                                      const MachineFunction &MF);
-  void processMachineModule(AbstractSlotTrackerStorage *AST, const Module *M,
-                            bool ShouldInitializeAllMetadata);
-  void processMachineFunction(AbstractSlotTrackerStorage *AST,
-                              const Function *F,
-                              bool ShouldInitializeAllMetadata);
+  void collectMachineFunctionMetadata(
+      SmallVectorImpl<const MDNode *> &Metadata, const MachineFunction &MF,
+      SmallVectorImpl<const MDNode *> *DebugLocations = nullptr) const;
 
 public:
-  MachineModuleSlotTracker(MFGetterFnT Fn, const MachineFunction *MF,
-                           bool ShouldInitializeAllMetadata = true);
+  MachineModuleSlotTracker(MFGetterFnT Fn, const MachineFunction *MF);
   ~MachineModuleSlotTracker() override;
 
+  /// Renumber module and machine metadata for canonical MIR output.
+  void renumberMetadataForAssembly();
   void collectMachineMDNodes(MachineMDNodeListType &L) const;
+  bool shouldPrintDebugLocationInline(const DILocation *DL) const override;
 };
 
 } // namespace llvm
diff --git a/llvm/include/llvm/IR/IRPrintingPasses.h b/llvm/include/llvm/IR/IRPrintingPasses.h
index 1b2d38d6190e9..0eb60f55f74c3 100644
--- a/llvm/include/llvm/IR/IRPrintingPasses.h
+++ b/llvm/include/llvm/IR/IRPrintingPasses.h
@@ -31,6 +31,11 @@ LLVM_ABI ModulePass *
 createPrintModulePass(raw_ostream &OS, const std::string &Banner = "",
                       bool ShouldPreserveUseListOrder = false);
 
+LLVM_ABI ModulePass *createPrintModulePass(raw_ostream &OS,
+                                           const std::string &Banner,
+                                           bool ShouldPreserveUseListOrder,
+                                           bool ShouldRenumberMetadata);
+
 /// Create and return a pass that prints functions to the specified
 /// \c raw_ostream as they are processed.
 LLVM_ABI FunctionPass *createPrintFunctionPass(raw_ostream &OS,
diff --git a/llvm/include/llvm/IR/Metadata.h b/llvm/include/llvm/IR/Metadata.h
index 5b458fa14f0b1..a53cb63ed59cf 100644
--- a/llvm/include/llvm/IR/Metadata.h
+++ b/llvm/include/llvm/IR/Metadata.h
@@ -1079,11 +1079,11 @@ class MDNode : public Metadata {
   /// Explicity set alignment because bitfields by default have an
   /// alignment of 1 on z/OS.
   struct alignas(alignof(size_t)) Header {
-    size_t IsResizable : 1;
-    size_t IsLarge : 1;
-    size_t SmallSize : 4;
-    size_t SmallNumOps : 4;
-    size_t : sizeof(size_t) * CHAR_BIT - 10;
+    uint32_t IsResizable : 1;
+    uint32_t IsLarge : 1;
+    uint32_t SmallSize : 4;
+    uint32_t SmallNumOps : 4;
+    uint32_t MetadataPrintID;
 
     unsigned NumUnresolved = 0;
     using LargeStorageVector = SmallVector<MDOperand, 0>;
diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h
index 6090644f7a12f..1b22ac79f2d51 100644
--- a/llvm/include/llvm/IR/Module.h
+++ b/llvm/include/llvm/IR/Module.h
@@ -987,6 +987,11 @@ class LLVM_ABI Module {
              bool ShouldPreserveUseListOrder = false,
              bool IsForDebug = false) const;
 
+  /// Renumber the IDs stored in metadata nodes into canonical assembly order.
+  /// This mutates the IDs and should only be used immediately before final
+  /// assembly output.
+  void renumberMetadataForAssembly();
+
   /// Dump the module to stderr (for debugging).
   void dump() const;
 
diff --git a/llvm/include/llvm/IR/ModuleSlotTracker.h b/llvm/include/llvm/IR/ModuleSlotTracker.h
index a3882a81e1177..b92bd16084b06 100644
--- a/llvm/include/llvm/IR/ModuleSlotTracker.h
+++ b/llvm/include/llvm/IR/ModuleSlotTracker.h
@@ -9,11 +9,12 @@
 #ifndef LLVM_IR_MODULESLOTTRACKER_H
 #define LLVM_IR_MODULESLOTTRACKER_H
 
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include <functional>
 #include <memory>
 #include <utility>
-#include <vector>
 
 namespace llvm {
 
@@ -21,6 +22,7 @@ class Module;
 class Function;
 class SlotTracker;
 class Value;
+class DILocation;
 class MDNode;
 
 /// Abstract interface of slot tracker storage.
@@ -28,8 +30,6 @@ class LLVM_ABI AbstractSlotTrackerStorage {
 public:
   virtual ~AbstractSlotTrackerStorage();
 
-  virtual unsigned getNextMetadataSlot() = 0;
-
   virtual void createMetadataSlot(const MDNode *) = 0;
   virtual int getMetadataSlot(const MDNode *) = 0;
 };
@@ -43,20 +43,37 @@ class LLVM_ABI AbstractSlotTrackerStorage {
 /// If the IR changes from underneath \a ModuleSlotTracker, strings like
 /// "<badref>" will be printed, or, worse, the wrong slots entirely.
 class LLVM_ABI ModuleSlotTracker {
+public:
+  using MachineMDNodeListType =
+      SmallVector<std::pair<unsigned, const MDNode *>, 0>;
+
+private:
   /// Storage for a slot tracker.
   std::unique_ptr<SlotTracker> MachineStorage;
   bool ShouldCreateStorage = false;
-  bool ShouldInitializeAllMetadata = false;
 
   const Module *M = nullptr;
   const Function *F = nullptr;
   SlotTracker *Machine = nullptr;
 
-  std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>
+  std::function<void(AbstractSlotTrackerStorage *, const Module *)>
       ProcessModuleHookFn;
-  std::function<void(AbstractSlotTrackerStorage *, const Function *, bool)>
+  std::function<void(AbstractSlotTrackerStorage *, const Function *)>
       ProcessFunctionHookFn;
 
+protected:
+  /// Renumber module metadata and then additional metadata for canonical
+  /// assembly output.
+  void renumberMetadataForAssembly(
+      ArrayRef<const MDNode *> AdditionalMetadata,
+      MachineMDNodeListType *AdditionalMetadataNodes = nullptr) const;
+
+  /// Collect metadata reachable from \p AdditionalMetadata but not from the
+  /// module.
+  void collectAdditionalMetadata(
+      ArrayRef<const MDNode *> AdditionalMetadata,
+      MachineMDNodeListType &AdditionalMetadataNodes) const;
+
 public:
   /// Wrap a preinitialized SlotTracker.
   ModuleSlotTracker(SlotTracker &Machine, const Module *M,
@@ -64,13 +81,8 @@ class LLVM_ABI ModuleSlotTracker {
 
   /// Construct a slot tracker from a module.
   ///
-  /// If \a M is \c nullptr, uses a null slot tracker.  Otherwise, initializes
-  /// a slot tracker, and initializes all metadata slots.  \c
-  /// ShouldInitializeAllMetadata defaults to true because this is expected to
-  /// be shared between multiple callers, and otherwise MDNode references will
-  /// not match up.
-  explicit ModuleSlotTracker(const Module *M,
-                             bool ShouldInitializeAllMetadata = true);
+  /// If \a M is \c nullptr, uses a null slot tracker.
+  explicit ModuleSlotTracker(const Module *M);
 
   /// Destructor to clean up storage.
   virtual ~ModuleSlotTracker();
@@ -95,14 +107,16 @@ class LLVM_ABI ModuleSlotTracker {
   int getLocalSlot(const Value *V);
 
   void setProcessHook(
-      std::function<void(AbstractSlotTrackerStorage *, const Module *, bool)>);
-  void setProcessHook(std::function<void(AbstractSlotTrackerStorage *,
-                                         const Function *, bool)>);
+      std::function<void(AbstractSlotTrackerStorage *, const Module *)>);
+  void setProcessHook(
+      std::function<void(AbstractSlotTrackerStorage *, const Function *)>);
 
-  using MachineMDNodeListType =
-      std::vector<std::pair<unsigned, const MDNode *>>;
+  void collectMDNodes(MachineMDNodeListType &L) const;
 
-  void collectMDNodes(MachineMDNodeListType &L, unsigned LB, unsigned UB) const;
+  /// Return whether a debug location should be printed inline instead of by ID.
+  virtual bool shouldPrintDebugLocationInline(const DILocation *) const {
+    return false;
+  }
 };
 
 } // end namespace llvm
diff --git a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
index e574d94ca2f22..56fdd94187dd3 100644
--- a/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
+++ b/llvm/include/llvm/IRPrinter/IRPrintingPasses.h
@@ -35,13 +35,16 @@ class PrintModulePass : public RequiredPassInfoMixin<PrintModulePass> {
   std::string Banner;
   bool ShouldPreserveUseListOrder;
   bool EmitSummaryIndex;
+  bool ShouldRenumberMetadata;
 
 public:
   LLVM_ABI PrintModulePass();
+  /// If \p ShouldRenumberMetadata, renumber metadata for canonical assembly
+  /// output before printing.
   LLVM_ABI PrintModulePass(raw_ostream &OS, const std::string &Banner = "",
                            bool ShouldPreserveUseListOrder = false,
-                           bool EmitSummaryIndex = false);
-
+                           bool EmitSummaryIndex = false,
+                           bool ShouldRenumberMetadata = false);
   LLVM_ABI PreservedAnalyses run(Module &M, AnalysisManager<Module> &);
 };
 
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index a9caf95a32ef9..ef4927e2c4ee3 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -360,7 +360,7 @@ static void mapValueToSlot(const Value *V, ModuleSlotTracker &MST,
 /// Creates the mapping from slot numbers to function's unnamed IR values.
 static void initSlots2Values(const Function &F,
                              DenseMap<unsigned, const Value *> &Slots2Values) {
-  ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
+  ModuleSlotTracker MST(F.getParent());
   MST.incorporateFunction(F);
   for (const auto &Arg : F.args())
     mapValueToSlot(&Arg, MST, Slots2Values);
@@ -3813,7 +3813,7 @@ bool MIParser::parseMMRA(MDNode *&Node) {
 static void initSlots2BasicBlocks(
     const Function &F,
     DenseMap<unsigned, const BasicBlock *> &Slots2BasicBlocks) {
-  ModuleSlotTracker MST(F.getParent(), /*ShouldInitializeAllMetadata=*/false);
+  ModuleSlotTracker MST(F.getParent());
   MST.incorporateFunction(F);
   for (const auto &BB : F) {
     if (BB.hasName())
diff --git a/llvm/lib/CodeGen/MIRPrintingPass.cpp b/llvm/lib/CodeGen/MIRPrintingPass.cpp
index f5e455a520151..5f6537cdd8c13 100644
--- a/llvm/lib/CodeGen/MIRPrintingPass.cpp
+++ b/llvm/lib/CodeGen/MIRPrintingPass.cpp
@@ -12,16 +12,20 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/MIRPrinter.h"
+#include "llvm/CodeGen/MachineFunctionAnalysis.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineModuleSlotTracker.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/VirtRegMap.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/Module.h"
 #include "llvm/InitializePasses.h"
 
 using namespace llvm;
 
 PreservedAnalyses PrintMIRPreparePass::run(Module &M, ModuleAnalysisManager &) {
+  M.renumberMetadataForAssembly();
   printMIR(OS, M);
   return PreservedAnalyses::all();
 }
@@ -32,6 +36,14 @@ PreservedAnalyses PrintMIRPass::run(MachineFunction &MF,
                   .getManager();
 
   const VirtRegMap *VRM = MFAM.getCachedResult<VirtRegMapAnalysis>(MF);
+  MachineModuleSlotTracker MST(
+      [&](const Function &F) {
+        return &FAM.getResult<MachineFunctionAnalysis>(
+                       const_cast<Function &>(F))
+                    .getMF();
+      },
+      &MF);
+  MST.renumberMetadataForAssembly();
   printMIR(OS, FAM, MF, VRM);
   return PreservedAnalyses::all();
 }
@@ -67,12 +79,16 @@ struct MIRPrintingPass : public MachineFunctionPass {
     if (auto *W = getAnalysisIfAvailable<VirtRegMapWrapperLegacy>())
       VRM = &W->getVRM();
 
+    MachineModuleSlotTracker MST(
+        [&](const Function &F) { return MMI->getMachineFunction(F); }, &MF);
+    MST.renumberMetadataForAssembly();
     printMIR(StrOS, *MMI, MF, VRM);
     MachineFunctions.append(Str);
     return false;
   }
 
   bool doFinalization(Module &M) override {
+    M.renumberMetadataForAssembly();
     printMIR(OS, M);
     OS << MachineFunctions;
     return false;
diff --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 08a67935b52f5..b58a11efd103c 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -503,7 +503,7 @@ void MachineBasicBlock::printName(raw_ostream &os, unsigned printNameFlags,
       if (moduleSlotTracker) {
         slot = moduleSlotTracker->getLocalSlot(bb);
       } else if (bb->getParent()) {
-        ModuleSlotTracker tmpTracker(bb->getModule(), false);
+        ModuleSlotTracker tmpTracker(bb->getModule());
         tmpTracker.incorporateFunction(*bb->getParent());
         slot = tmpTracker.getLocalSlot(bb);
       }
diff --git a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
index e08b03eb4d70c..9e7ea156eab69 100644
--- a/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
+++ b/llvm/lib/CodeGen/MachineModuleSlotTracker.cpp
@@ -16,92 +16,98 @@
 
 using namespace llvm;
 
-void MachineModuleSlotTracker::processMachineFunctionMetadata(
-    AbstractSlotTrackerStorage *AST, const MachineFunction &MF) {
-  // Create metadata created within the backend.
+bool MachineModuleSlotTracker::shouldPrintDebugLocationInline(
+    const DILocation *DL) const {
+  return InlineDebugLocations.contains(DL);
+}
+
+void MachineModuleSlotTracker::collectMachineFunctionMetadata(
+    SmallVectorImpl<const MDNode *> &Metadata, const MachineFunction &MF,
+    SmallVectorImpl<const MDNode *> *DebugLocations) const {
   for (const MachineBasicBlock &MBB : MF)
     for (const MachineInstr &MI : MBB.instrs()) {
+      if (DebugLocations)
+        if (DebugLoc DL = MI.getDebugLoc())
+          DebugLocations->push_back(DL.getAsMDNode());
+
       if (MDNode *N = MI.getHeapAllocMarker())
-        AST->createMetadataSlot(N);
+        Metadata.push_back(N);
       if (MDNode *...
[truncated]

@yxsamliu
yxsamliu requested review from aengelke, bogner and rnk September 1, 2026 21:22
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

🐧 Linux x64 Test Results

  • 213359 tests passed
  • 6415 tests skipped

✅ The build succeeded and all tests passed.

@yxsamliu
yxsamliu force-pushed the amd/dev/yaxunl/PR-216838-persistent-metadata-ids-reland-main branch from a450eb0 to ffeb4a9 Compare September 2, 2026 01:29
@github-actions

github-actions Bot commented Sep 2, 2026

Copy link
Copy Markdown

🪟 Windows x64 Test Results

  • 147743 tests passed
  • 4870 tests skipped

✅ The build succeeded and all tests passed.

This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268
@yxsamliu
yxsamliu force-pushed the amd/dev/yaxunl/PR-216838-persistent-metadata-ids-reland-main branch from ffeb4a9 to 436f28c Compare September 2, 2026 12:31

@aengelke aengelke left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yxsamliu
yxsamliu merged commit dd7236d into llvm:main Sep 2, 2026
12 of 13 checks passed
@llvm-ci

llvm-ci commented Sep 3, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder llvm-clang-x86_64-expensive-checks-debian running on gribozavr4 while building clang,flang,llvm,mlir,polly at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/16/builds/5121

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: Bindings/OCaml/debuginfo.ml' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
rm -rf /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp && mkdir -p /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp && cp /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml && cp /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/Utils/Testsuite.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml
# executed command: rm -rf /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp
# executed command: mkdir -p /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp
# executed command: cp /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml
# executed command: cp /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/Utils/Testsuite.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml
# RUN: at line 2
/usr/bin/ocamlfind ocamlc -cclib -L/b/1/llvm-clang-x86_64-expensive-checks-debian/build/lib  -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/ -linkpkg /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml -o /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# executed command: /usr/bin/ocamlfind ocamlc -cclib -L/b/1/llvm-clang-x86_64-expensive-checks-debian/build/lib -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/ -linkpkg /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml -o /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# RUN: at line 3
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable | /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/FileCheck /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml
# executed command: /b/1/llvm-clang-x86_64-expensive-checks-debian/build/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# executed command: /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bin/FileCheck /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml
# .---command stderr------------
# | /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml:66:12: error: CHECK: expected string not found in input
# |  (* CHECK: [[FILE_PTR:<0x[0-9a-f]*>]] = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# |            ^
# | <stdin>:1:1: note: scanning from here
# | !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# | ^
# | <stdin>:1:1: note: pattern attempts to capture variables: "FILE_PTR"
# | !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# | ^
# | 
# | Input file: <stdin>
# | Check file: /b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/test/Bindings/OCaml/debuginfo.ml
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |             1: !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir") 
# | check:66'0    {                                                                   search range start (exclusive)
# | check:66'1                                                                        error: no match found in search range
# | check:66'2                                                                        pattern attempts to capture variables: "FILE_PTR"
# |             2: !2 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "TestGen", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false) 
# |             3: !3 = !DIModule(scope: null, name: "di_test_module") 
# |             4: !4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 
# |             5: !5 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptrint", baseType: !4, size: 32, align: 32, dwarfAddressSpace: 0) 
# |             6: !6 = !{null, !4, !5} 
# |             .
# |             .
# |             .
# |            26: !27 = !{!24, !25, !26} 
# |            27: !28 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: !20, file: !1, line: 1, baseType: !12, size: 64, elements: !27) 
...

@llvm-ci

llvm-ci commented Sep 3, 2026

Copy link
Copy Markdown

LLVM Buildbot has detected a new failure on builder clang-x86_64-debian-fast running on gribozavr4 while building clang,flang,llvm,mlir,polly at step 6 "test-build-unified-tree-check-all".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/56/builds/6880

Here is the relevant piece of the build log for the reference
Step 6 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM :: Bindings/OCaml/debuginfo.ml' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 1
rm -rf /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp && mkdir -p /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp && cp /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml && cp /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/Utils/Testsuite.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml
# executed command: rm -rf /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp
# executed command: mkdir -p /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp
# executed command: cp /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml
# executed command: cp /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/Utils/Testsuite.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml
# RUN: at line 2
/usr/bin/ocamlfind ocamlc -cclib -L/b/1/clang-x86_64-debian-fast/llvm.obj/lib  -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/ -linkpkg /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml -o /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# executed command: /usr/bin/ocamlfind ocamlc -cclib -L/b/1/clang-x86_64-debian-fast/llvm.obj/lib -g -w +A -package llvm.all_backends -package llvm.target -package llvm.analysis -package llvm.debuginfo -I /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/ -linkpkg /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/Testsuite.ml /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/debuginfo.ml -o /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# RUN: at line 3
/b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable | /b/1/clang-x86_64-debian-fast/llvm.obj/bin/FileCheck /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml
# executed command: /b/1/clang-x86_64-debian-fast/llvm.obj/test/Bindings/OCaml/Output/debuginfo.ml.tmp/executable
# executed command: /b/1/clang-x86_64-debian-fast/llvm.obj/bin/FileCheck /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml
# .---command stderr------------
# | /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml:66:12: error: CHECK: expected string not found in input
# |  (* CHECK: [[FILE_PTR:<0x[0-9a-f]*>]] = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# |            ^
# | <stdin>:1:1: note: scanning from here
# | !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# | ^
# | <stdin>:1:1: note: pattern attempts to capture variables: "FILE_PTR"
# | !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir")
# | ^
# | 
# | Input file: <stdin>
# | Check file: /b/1/clang-x86_64-debian-fast/llvm.src/llvm/test/Bindings/OCaml/debuginfo.ml
# | 
# | -dump-input=help explains the following input dump.
# | 
# | Input was:
# | <<<<<<
# |             1: !1 = !DIFile(filename: "di_test_file", directory: "di_test_dir") 
# | check:66'0    {                                                                   search range start (exclusive)
# | check:66'1                                                                        error: no match found in search range
# | check:66'2                                                                        pattern attempts to capture variables: "FILE_PTR"
# |             2: !2 = distinct !DICompileUnit(language: DW_LANG_C89, file: !1, producer: "TestGen", isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, splitDebugInlining: false) 
# |             3: !3 = !DIModule(scope: null, name: "di_test_module") 
# |             4: !4 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 
# |             5: !5 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "ptrint", baseType: !4, size: 32, align: 32, dwarfAddressSpace: 0) 
# |             6: !6 = !{null, !4, !5} 
# |             .
# |             .
# |             .
# |            26: !27 = !{!24, !25, !26} 
# |            27: !28 = !DICompositeType(tag: DW_TAG_enumeration_type, name: "EnumTest", scope: !20, file: !1, line: 1, baseType: !12, size: 64, elements: !27) 
...

fhahn added a commit to fhahn/llvm-project that referenced this pull request Sep 3, 2026
@zmodem

zmodem commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

This breaks a lot of tests that have expectations involving metadata, not necessarily on the IDs, but their order. Maybe it's worth mentioning this in a release note at least?

@yxsamliu

yxsamliu commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

Re: OCaml buildbot failure

The test still expected pointer-based metadata output. I updated it for persistent metadata IDs in #220957.

@yxsamliu

yxsamliu commented Sep 3, 2026

Copy link
Copy Markdown
Contributor Author

@zmodem Thanks for the suggestion. I added a release note in #220967.

Iasonaskrpr pushed a commit to Iasonaskrpr/llvm-project that referenced this pull request Sep 4, 2026
This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268
asudarsa-qti pushed a commit to asudarsa-qti/llvm-project that referenced this pull request Sep 4, 2026
This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268
addmisol pushed a commit to addmisol/llvm-project2 that referenced this pull request Sep 6, 2026
This relands 85e9030 with fixes for
the buildbot failures that prompted its revert.

Move the MachineModuleSlotTracker debug-location query out of line so
DILocation is complete when SmallPtrSet pointer traits are instantiated
by MSVC.

The legacy DXIL pretty-printer renumbers persistent metadata IDs, which
changes module print state. Make the pass report the modification and
register it as a transformation rather than an analysis.

Repeated pass and debug printing currently rebuilds metadata slot
numbers by scanning the module. On large modules, this repeated setup
can take more time than printing the requested function.

Store a persistent print ID in each metadata node and use that ID
whenever metadata is printed. Before final assembly output, renumber the
IDs into canonical compact order so normal textual IR output remains
unchanged.

This keeps metadata numbers stable across pass snapshots while avoiding
repeated module-wide metadata scans.

Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/2/builds/60795
Buildbot failure:
https://lab.llvm.org/buildbot/#/builders/187/builds/23268
yxsamliu added a commit that referenced this pull request Sep 8, 2026
Document how persistent metadata IDs affect intermediate and standalone
textual output. Final assembly output remains canonically renumbered.

Follow-up to #220390.
JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Sep 8, 2026
Call renumberMetadataForAssembly() in LLVMRustPrintModule()

Some metadata got reordered in llvm/llvm-project#220390
rust-bors Bot pushed a commit to rust-lang/rust that referenced this pull request Sep 8, 2026
Rollup merge of #162236 - zmodem:metadata_reordering, r=nikic

Call renumberMetadataForAssembly() in LLVMRustPrintModule()

Some metadata got reordered in llvm/llvm-project#220390
vadimkotov pushed a commit to vadimkotov/llvm-project that referenced this pull request Sep 8, 2026
Document how persistent metadata IDs affect intermediate and standalone
textual output. Final assembly output remains canonically renumbered.

Follow-up to llvm#220390.
github-actions Bot pushed a commit to rust-lang/rustc-dev-guide that referenced this pull request Sep 14, 2026
Call renumberMetadataForAssembly() in LLVMRustPrintModule()

Some metadata got reordered in llvm/llvm-project#220390
aobolensk pushed a commit to aobolensk/llvm-project that referenced this pull request Sep 15, 2026
Document how persistent metadata IDs affect intermediate and standalone
textual output. Final assembly output remains canonically renumbered.

Follow-up to llvm#220390.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants