Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 29 additions & 4 deletions mlir/lib/Transforms/Utils/RegionUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/DebugLog.h"

#include <deque>
#include <iterator>

using namespace mlir;

#define DEBUG_TYPE "region-utils"

void mlir::replaceAllUsesInRegionWith(Value orig, Value replacement,
Region &region) {
for (auto &use : llvm::make_early_inc_range(orig.getUses())) {
Expand Down Expand Up @@ -182,19 +185,34 @@ SmallVector<Value> mlir::makeRegionIsolatedFromAbove(
// TODO: We could likely merge this with the DCE algorithm below.
LogicalResult mlir::eraseUnreachableBlocks(RewriterBase &rewriter,
MutableArrayRef<Region> regions) {
LDBG() << "Starting eraseUnreachableBlocks with " << regions.size()
<< " regions";

// Set of blocks found to be reachable within a given region.
llvm::df_iterator_default_set<Block *, 16> reachable;
// If any blocks were found to be dead.
bool erasedDeadBlocks = false;
int erasedDeadBlocks = 0;
Copy link
Member

Choose a reason for hiding this comment

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

If this weren't a util, a statistic would have been useful for additional reporting.

Copy link
Collaborator Author

@joker-eph joker-eph Aug 18, 2025

Choose a reason for hiding this comment

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

Instead of the API being

Returns success if any blocks were erased, failure otherwise.

We could return the number of block erased, WDYT? (I'll do it in a follow-up)

I also don't like using a "failure" when the API does not find something to do: it didn't fail, it succeeded with 0 replacements!


SmallVector<Region *, 1> worklist;
worklist.reserve(regions.size());
for (Region &region : regions)
worklist.push_back(&region);

LDBG(2) << "Initial worklist size: " << worklist.size();

while (!worklist.empty()) {
Region *region = worklist.pop_back_val();
if (region->empty())
if (region->empty()) {
LDBG(2) << "Skipping empty region";
continue;
}

LDBG(2) << "Processing region with " << region->getBlocks().size()
<< " blocks";
if (region->getParentOp())
LDBG(2) << " -> for operation: "
<< OpWithFlags(region->getParentOp(),
OpPrintingFlags().skipRegions());

// If this is a single block region, just collect the nested regions.
if (region->hasOneBlock()) {
Expand All @@ -209,13 +227,17 @@ LogicalResult mlir::eraseUnreachableBlocks(RewriterBase &rewriter,
for (Block *block : depth_first_ext(&region->front(), reachable))
(void)block /* Mark all reachable blocks */;

LDBG(2) << "Found " << reachable.size() << " reachable blocks out of "
<< region->getBlocks().size() << " total blocks";

// Collect all of the dead blocks and push the live regions onto the
// worklist.
for (Block &block : llvm::make_early_inc_range(*region)) {
if (!reachable.count(&block)) {
LDBG() << "Erasing unreachable block: " << &block;
block.dropAllDefinedValueUses();
rewriter.eraseBlock(&block);
erasedDeadBlocks = true;
++erasedDeadBlocks;
continue;
}

Expand All @@ -226,7 +248,10 @@ LogicalResult mlir::eraseUnreachableBlocks(RewriterBase &rewriter,
}
}

return success(erasedDeadBlocks);
LDBG() << "Finished eraseUnreachableBlocks, erased " << erasedDeadBlocks
<< " dead blocks";

return success(erasedDeadBlocks > 0);
}

//===----------------------------------------------------------------------===//
Expand Down