[Mlir-commits] [mlir] 8e86107 - [mlir][IR][NFC] Add `Block::computeBlockNumber` convenience helper (#173475)

llvmlistbot at llvm.org llvmlistbot at llvm.org
Tue Dec 30 05:43:55 PST 2025


Author: Matthias Springer
Date: 2025-12-30T13:43:51Z
New Revision: 8e86107b1f767ae87dc7a5022af027c2ae38142f

URL: https://github.com/llvm/llvm-project/commit/8e86107b1f767ae87dc7a5022af027c2ae38142f
DIFF: https://github.com/llvm/llvm-project/commit/8e86107b1f767ae87dc7a5022af027c2ae38142f.diff

LOG: [mlir][IR][NFC] Add `Block::computeBlockNumber` convenience helper (#173475)

Add a helper function to compute the number of a block. Recommended only
for debugging purposes and to print error messages.

Added: 
    

Modified: 
    mlir/include/mlir/IR/Block.h
    mlir/lib/Dialect/Transform/DebugExtension/DebugExtensionOps.cpp
    mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp
    mlir/lib/IR/Block.cpp
    mlir/lib/IR/Unit.cpp
    mlir/lib/IR/Verifier.cpp
    mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
    mlir/lib/Transforms/RemoveDeadValues.cpp
    mlir/test/lib/Analysis/TestAliasAnalysis.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/IR/Block.h b/mlir/include/mlir/IR/Block.h
index 85ce66f69df48..92351402ed53b 100644
--- a/mlir/include/mlir/IR/Block.h
+++ b/mlir/include/mlir/IR/Block.h
@@ -77,6 +77,16 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
   /// Unlink this Block from its parent region and delete it.
   void erase();
 
+  /// Compute the position of this block within its parent region using an O(N)
+  /// linear scan.
+  ///
+  /// Note: There is no semantic meaning to a block number. Blocks are used for
+  /// unstructured control flow and relying on block numbers for functional
+  /// purposes may indicate a design flaw. (You can give semantic meaning to
+  /// region numbers instead.) Block numbers are useful for debugging purposes
+  /// and for error messages.
+  unsigned computeBlockNumber();
+
   //===--------------------------------------------------------------------===//
   // Block argument management
   //===--------------------------------------------------------------------===//

diff  --git a/mlir/lib/Dialect/Transform/DebugExtension/DebugExtensionOps.cpp b/mlir/lib/Dialect/Transform/DebugExtension/DebugExtensionOps.cpp
index a963b3f063a8a..9f9695b7d348b 100644
--- a/mlir/lib/Dialect/Transform/DebugExtension/DebugExtensionOps.cpp
+++ b/mlir/lib/Dialect/Transform/DebugExtension/DebugExtensionOps.cpp
@@ -34,9 +34,8 @@ transform::EmitRemarkAtOp::apply(transform::TransformRewriter &rewriter,
     os << "value handle points to ";
     if (auto arg = llvm::dyn_cast<BlockArgument>(value)) {
       os << "a block argument #" << arg.getArgNumber() << " in block #"
-         << std::distance(arg.getOwner()->getParent()->begin(),
-                          arg.getOwner()->getIterator())
-         << " in region #" << arg.getOwner()->getParent()->getRegionNumber();
+         << arg.getOwner()->computeBlockNumber() << " in region #"
+         << arg.getOwner()->getParent()->getRegionNumber();
     } else {
       os << "an op result #" << llvm::cast<OpResult>(value).getResultNumber();
     }

diff  --git a/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp b/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp
index 4f09782859e07..c1fc1d53742ea 100644
--- a/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp
+++ b/mlir/lib/Dialect/Transform/Interfaces/TransformInterfaces.cpp
@@ -554,8 +554,7 @@ void transform::TransformState::recordValueHandleInvalidationByOpHandleOne(
       auto arg = llvm::cast<BlockArgument>(payloadValue);
       definingOp = arg.getParentBlock()->getParentOp();
       argumentNo = arg.getArgNumber();
-      blockNo = std::distance(arg.getOwner()->getParent()->begin(),
-                              arg.getOwner()->getIterator());
+      blockNo = arg.getOwner()->computeBlockNumber();
       regionNo = arg.getOwner()->getParent()->getRegionNumber();
     }
     assert(definingOp && "expected the value to be defined by an op as result "

diff  --git a/mlir/lib/IR/Block.cpp b/mlir/lib/IR/Block.cpp
index 27b47e2d2653d..1a06c576fd01c 100644
--- a/mlir/lib/IR/Block.cpp
+++ b/mlir/lib/IR/Block.cpp
@@ -141,6 +141,11 @@ void Block::recomputeOpOrder() {
     op.orderIndex = (orderIndex += Operation::kOrderStride);
 }
 
+unsigned Block::computeBlockNumber() {
+  assert(getParent() && "cannot compute block number of detached block");
+  return std::distance(getParent()->begin(), getIterator());
+}
+
 //===----------------------------------------------------------------------===//
 // Argument list management.
 //===----------------------------------------------------------------------===//

diff  --git a/mlir/lib/IR/Unit.cpp b/mlir/lib/IR/Unit.cpp
index 58c1d27db87f0..158fa13bf9e5f 100644
--- a/mlir/lib/IR/Unit.cpp
+++ b/mlir/lib/IR/Unit.cpp
@@ -37,9 +37,7 @@ static void printRegion(llvm::raw_ostream &os, Region *region,
 static void printBlock(llvm::raw_ostream &os, Block *block,
                        OpPrintingFlags &flags) {
   Region *region = block->getParent();
-  Block *entry = &region->front();
-  int blockId = std::distance(entry->getIterator(), block->getIterator());
-  os << "Block #" << blockId << " for ";
+  os << "Block #" << block->computeBlockNumber() << " for ";
   bool shouldSkipRegions = flags.shouldSkipRegions();
   printRegion(os, region, flags.skipRegions());
   if (!shouldSkipRegions)

diff  --git a/mlir/lib/IR/Verifier.cpp b/mlir/lib/IR/Verifier.cpp
index 3ced663a87be1..e19537a901d18 100644
--- a/mlir/lib/IR/Verifier.cpp
+++ b/mlir/lib/IR/Verifier.cpp
@@ -364,7 +364,7 @@ static void diagnoseInvalidOperandDominance(Operation &op, unsigned operandNo) {
   }
   if (block1 == block2)
     llvm::report_fatal_error("Internal error in dominance verification");
-  int index = std::distance(region2->begin(), block2->getIterator());
+  unsigned index = block2->computeBlockNumber();
   note << "operand defined as a block argument (block #" << index;
   if (region1 == region2)
     note << " in the same region)";

diff  --git a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
index 248f885505819..05ab4fb4f07cd 100644
--- a/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
+++ b/mlir/lib/Tools/mlir-lsp-server/MLIRServer.cpp
@@ -172,11 +172,6 @@ static std::optional<StringRef> getTextFromRange(SMRange range) {
   return StringRef(startPtr, range.End.getPointer() - startPtr);
 }
 
-/// Given a block, return its position in its parent region.
-static unsigned getBlockNumber(Block *block) {
-  return std::distance(block->getParent()->begin(), block->getIterator());
-}
-
 /// Given a block and source location, print the source name of the block to the
 /// given output stream.
 static void printDefBlockName(raw_ostream &os, Block *block, SMRange loc = {}) {
@@ -188,7 +183,7 @@ static void printDefBlockName(raw_ostream &os, Block *block, SMRange loc = {}) {
   }
 
   // Otherwise, we don't have a name so print the block number.
-  os << "<Block #" << getBlockNumber(block) << ">";
+  os << "<Block #" << block->computeBlockNumber() << ">";
 }
 static void printDefBlockName(raw_ostream &os,
                               const AsmParserState::BlockDefinition &def) {
@@ -622,7 +617,7 @@ MLIRDocument::buildHoverForBlock(SMRange hoverRange,
 
   // Display the parent operation, block number, predecessors, and successors.
   os << "Operation: \"" << block.block->getParentOp()->getName() << "\"\n\n"
-     << "Block #" << getBlockNumber(block.block) << "\n\n";
+     << "Block #" << block.block->computeBlockNumber() << "\n\n";
   if (!block.block->hasNoPredecessors()) {
     os << "Predecessors: ";
     llvm::interleaveComma(block.block->getPredecessors(), os,

diff  --git a/mlir/lib/Transforms/RemoveDeadValues.cpp b/mlir/lib/Transforms/RemoveDeadValues.cpp
index c7b9b49c9c159..45266bc7b34ea 100644
--- a/mlir/lib/Transforms/RemoveDeadValues.cpp
+++ b/mlir/lib/Transforms/RemoveDeadValues.cpp
@@ -791,7 +791,7 @@ static void cleanUpDeadVals(RDVFinalCleanupList &list) {
     LDBG_OS([&](raw_ostream &os) {
       os << "Erasing non-live arguments [";
       llvm::interleaveComma(b.nonLiveArgs.set_bits(), os);
-      os << "] from block: " << b.b << " in region "
+      os << "] from block #" << b.b->computeBlockNumber() << " in region #"
          << b.b->getParent()->getRegionNumber() << " of operation "
          << OpWithFlags(b.b->getParent()->getParentOp(),
                         OpPrintingFlags().skipRegions().printGenericOpForm());

diff  --git a/mlir/test/lib/Analysis/TestAliasAnalysis.cpp b/mlir/test/lib/Analysis/TestAliasAnalysis.cpp
index 65e3490953d6e..0125e403272a8 100644
--- a/mlir/test/lib/Analysis/TestAliasAnalysis.cpp
+++ b/mlir/test/lib/Analysis/TestAliasAnalysis.cpp
@@ -26,8 +26,7 @@ static void printAliasOperand(Operation *op) {
 static void printAliasOperand(Value value) {
   if (BlockArgument arg = dyn_cast<BlockArgument>(value)) {
     Region *region = arg.getParentRegion();
-    unsigned parentBlockNumber =
-        std::distance(region->begin(), arg.getOwner()->getIterator());
+    unsigned parentBlockNumber = arg.getOwner()->computeBlockNumber();
     llvm::errs() << region->getParentOp()
                         ->getAttrOfType<StringAttr>("test.ptr")
                         .getValue()


        


More information about the Mlir-commits mailing list