Skip to content

Commit 6a285cc

Browse files
[mlir][IR] Fix Block::without_terminator for blocks without terminator (#154498)
Blocks without a terminator are not handled correctly by `Block::without_terminator`: the last operation is excluded, even when it is not a terminator. With this commit, only terminators are excluded. If the last operation is unregistered, it is included for safety.
1 parent f487c0e commit 6a285cc

File tree

3 files changed

+21
-10
lines changed

3 files changed

+21
-10
lines changed

mlir/include/mlir/IR/Block.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,14 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
205205
}
206206

207207
/// Return an iterator range over the operation within this block excluding
208-
/// the terminator operation at the end.
208+
/// the terminator operation at the end. If the block has no terminator,
209+
/// return an iterator range over the entire block. If it is unknown if the
210+
/// block has a terminator (i.e., last block operation is unregistered), also
211+
/// return an iterator range over the entire block.
209212
iterator_range<iterator> without_terminator() {
210213
if (begin() == end())
211214
return {begin(), end()};
212-
auto endIt = --end();
213-
return {begin(), endIt};
215+
return without_terminator_impl();
214216
}
215217

216218
//===--------------------------------------------------------------------===//
@@ -221,7 +223,8 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
221223
/// the block might have a valid terminator operation.
222224
Operation *getTerminator();
223225

224-
/// Check whether this block might have a terminator.
226+
/// Return "true" if this block might have a terminator. Return "true" if
227+
/// the last operation is unregistered.
225228
bool mightHaveTerminator();
226229

227230
//===--------------------------------------------------------------------===//
@@ -402,6 +405,9 @@ class alignas(8) Block : public IRObjectWithUseList<BlockOperand>,
402405
void printAsOperand(raw_ostream &os, AsmState &state);
403406

404407
private:
408+
/// Same as `without_terminator`, but assumes that the block is not empty.
409+
iterator_range<iterator> without_terminator_impl();
410+
405411
/// Pair of the parent object that owns this block and a bit that signifies if
406412
/// the operations within this block have a valid ordering.
407413
llvm::PointerIntPair<Region *, /*IntBits=*/1, bool> parentValidOpOrderPair;

mlir/lib/Analysis/TopologicalSortUtils.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,7 @@ bool mlir::sortTopologically(
101101

102102
bool mlir::sortTopologically(
103103
Block *block, function_ref<bool(Value, Operation *)> isOperandReady) {
104-
if (block->empty())
105-
return true;
106-
if (block->back().hasTrait<OpTrait::IsTerminator>())
107-
return sortTopologically(block, block->without_terminator(),
108-
isOperandReady);
109-
return sortTopologically(block, *block, isOperandReady);
104+
return sortTopologically(block, block->without_terminator(), isOperandReady);
110105
}
111106

112107
bool mlir::computeTopologicalSorting(

mlir/lib/IR/Block.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,16 @@ bool Block::mightHaveTerminator() {
251251
return !empty() && back().mightHaveTrait<OpTrait::IsTerminator>();
252252
}
253253

254+
iterator_range<Block::iterator> Block::without_terminator_impl() {
255+
// Note: When the op is unregistered, we do not know for sure if the last
256+
// op is a terminator. In that case, we include it in `without_terminator`,
257+
// but that decision is somewhat arbitrary.
258+
if (!back().hasTrait<OpTrait::IsTerminator>())
259+
return {begin(), end()};
260+
auto endIt = --end();
261+
return {begin(), endIt};
262+
}
263+
254264
// Indexed successor access.
255265
unsigned Block::getNumSuccessors() {
256266
return empty() ? 0 : back().getNumSuccessors();

0 commit comments

Comments
 (0)