Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
5 changes: 5 additions & 0 deletions mlir/include/mlir/IR/Block.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
succ_iterator succ_end() { return getSuccessors().end(); }
SuccessorRange getSuccessors() { return SuccessorRange(this); }

/// Return "true" if there is a path from this block to the given block
/// (according to the successors relationship). Both blocks must be in the
/// same region. Paths that contain a block from `except` do not count.
bool isReachable(Block *other, ArrayRef<Block *> except = {});

//===--------------------------------------------------------------------===//
// Walkers
//===--------------------------------------------------------------------===//
Expand Down
23 changes: 2 additions & 21 deletions mlir/lib/Dialect/Bufferization/Transforms/OneShotAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,25 +273,6 @@ static bool happensBefore(Operation *a, Operation *b,
return false;
}

static bool isReachable(Block *from, Block *to, ArrayRef<Block *> except) {
DenseSet<Block *> visited;
SmallVector<Block *> worklist;
for (Block *succ : from->getSuccessors())
worklist.push_back(succ);
while (!worklist.empty()) {
Block *next = worklist.pop_back_val();
if (llvm::is_contained(except, next))
continue;
if (next == to)
return true;
if (!visited.insert(next).second)
continue;
for (Block *succ : next->getSuccessors())
worklist.push_back(succ);
}
return false;
}

/// Return `true` if op dominance can be used to rule out a read-after-write
/// conflicts based on the ordering of ops. Returns `false` if op dominance
/// cannot be used to due region-based loops.
Expand Down Expand Up @@ -427,8 +408,8 @@ static bool canUseOpDominanceDueToBlocks(OpOperand *uRead, OpOperand *uWrite,
Block *writeBlock = uWrite->getOwner()->getBlock();
for (Value def : definitions) {
Block *defBlock = def.getParentBlock();
if (isReachable(readBlock, writeBlock, {defBlock}) &&
isReachable(writeBlock, readBlock, {defBlock}))
if (readBlock->isReachable(writeBlock, {defBlock}) &&
writeBlock->isReachable(readBlock, {defBlock}))
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,20 +73,7 @@ bool TransferOptimization::isReachable(Operation *start, Operation *dest) {
// Simple case where the start op dominate the destination.
if (dominators.dominates(start, dest))
return true;
Block *startBlock = start->getBlock();
Block *destBlock = dest->getBlock();
SmallVector<Block *, 32> worklist(startBlock->succ_begin(),
startBlock->succ_end());
SmallPtrSet<Block *, 32> visited;
while (!worklist.empty()) {
Block *bb = worklist.pop_back_val();
if (!visited.insert(bb).second)
continue;
if (dominators.dominates(bb, destBlock))
return true;
worklist.append(bb->succ_begin(), bb->succ_end());
}
return false;
return start->getBlock()->isReachable(dest->getBlock());
}

/// For transfer_write to overwrite fully another transfer_write must:
Expand Down
22 changes: 21 additions & 1 deletion mlir/lib/IR/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
//===----------------------------------------------------------------------===//

#include "mlir/IR/Block.h"

#include "mlir/IR/Builders.h"
#include "mlir/IR/Operation.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/SmallPtrSet.h"

using namespace mlir;

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -331,7 +334,7 @@ unsigned PredecessorIterator::getSuccessorIndex() const {
}

//===----------------------------------------------------------------------===//
// SuccessorRange
// Successors
//===----------------------------------------------------------------------===//

SuccessorRange::SuccessorRange() : SuccessorRange(nullptr, 0) {}
Expand All @@ -349,6 +352,23 @@ SuccessorRange::SuccessorRange(Operation *term) : SuccessorRange() {
base = term->getBlockOperands().data();
}

bool Block::isReachable(Block *other, ArrayRef<Block *> except) {
assert(getParent() == other->getParent() && "expected same region");
SmallVector<Block *> worklist(succ_begin(), succ_end());
SmallPtrSet<Block *, 16> visited;
while (!worklist.empty()) {
Block *next = worklist.pop_back_val();
if (llvm::is_contained(except, next))
continue;
if (next == other)
return true;
if (!visited.insert(next).second)
continue;
worklist.append(next->succ_begin(), next->succ_end());
}
return false;
}

//===----------------------------------------------------------------------===//
// BlockRange
//===----------------------------------------------------------------------===//
Expand Down
Loading