[mlir] Don't elide the last op if there is no terminator

Reviewed By: mehdi_amini

Differential Revision: https://reviews.llvm.org/D103264
This commit is contained in:
Lei Zhang 2021-05-28 07:21:41 -04:00
parent ca5f07f8c4
commit 4694097dab
4 changed files with 48 additions and 4 deletions

View File

@ -420,8 +420,12 @@ private:
// Consider the operations within this block, ignoring the terminator if
// requested.
bool hasTerminator =
!block->empty() && block->back().hasTrait<OpTrait::IsTerminator>();
auto range = llvm::make_range(
block->begin(), std::prev(block->end(), printBlockTerminator ? 0 : 1));
block->begin(),
std::prev(block->end(),
(!hasTerminator || printBlockTerminator) ? 0 : 1));
for (Operation &op : range)
print(&op);
}
@ -2604,8 +2608,12 @@ void OperationPrinter::print(Block *block, bool printBlockArgs,
}
currentIndent += indentWidth;
bool hasTerminator =
!block->empty() && block->back().hasTrait<OpTrait::IsTerminator>();
auto range = llvm::make_range(
block->begin(), std::prev(block->end(), printBlockTerminator ? 0 : 1));
block->begin(),
std::prev(block->end(),
(!hasTerminator || printBlockTerminator) ? 0 : 1));
for (auto &op : range) {
print(&op);
os << newLine;

View File

@ -101,3 +101,9 @@ func @named_region_has_wrong_number_of_blocks() {
func @foo2() { return }
}
) : () -> ()
// CHECK: test.single_no_terminator_custom_asm_op
// CHECK-NEXT: important_dont_drop
test.single_no_terminator_custom_asm_op {
"important_dont_drop"() : () -> ()
}

View File

@ -1006,6 +1006,27 @@ void RegionIfOp::getSuccessorRegions(
regions.push_back(RegionSuccessor(&elseRegion(), getElseArgs()));
}
//===----------------------------------------------------------------------===//
// SingleNoTerminatorCustomAsmOp
//===----------------------------------------------------------------------===//
static ParseResult parseSingleNoTerminatorCustomAsmOp(OpAsmParser &parser,
OperationState &state) {
Region *body = state.addRegion();
if (parser.parseRegion(*body, /*arguments=*/{}, /*argTypes=*/{}))
return failure();
return success();
}
static void print(SingleNoTerminatorCustomAsmOp op, OpAsmPrinter &printer) {
printer << op.getOperationName();
printer.printRegion(
op.getRegion(), /*printEntryBlockArgs=*/false,
// This op has a single block without terminators. But explicitly mark
// as not printing block terminators for testing.
/*printBlockTerminators=*/false);
}
#include "TestOpEnums.cpp.inc"
#include "TestOpInterfaces.cpp.inc"
#include "TestOpStructs.cpp.inc"

View File

@ -338,13 +338,22 @@ def SizedRegionOp : TEST_Op<"sized_region_op", []> {
// NoTerminator Operation
//===----------------------------------------------------------------------===//
def SingleNoTerminatorOp : TEST_Op<"single_no_terminator_op", GraphRegionNoTerminator.traits> {
def SingleNoTerminatorOp : TEST_Op<"single_no_terminator_op",
GraphRegionNoTerminator.traits> {
let regions = (region SizedRegion<1>:$my_region);
let assemblyFormat = "attr-dict `:` $my_region";
}
def VariadicNoTerminatorOp : TEST_Op<"variadic_no_terminator_op", GraphRegionNoTerminator.traits> {
def SingleNoTerminatorCustomAsmOp : TEST_Op<"single_no_terminator_custom_asm_op",
[SingleBlock, NoTerminator]> {
let regions = (region SizedRegion<1>);
let parser = [{ return ::parseSingleNoTerminatorCustomAsmOp(parser, result); }];
let printer = [{ return ::print(*this, p); }];
}
def VariadicNoTerminatorOp : TEST_Op<"variadic_no_terminator_op",
GraphRegionNoTerminator.traits> {
let regions = (region VariadicRegion<SizedRegion<1>>:$my_regions);
let assemblyFormat = "attr-dict `:` $my_regions";