This is an archive of the discontinued LLVM Phabricator instance.

[mlir] ensureRegionTerminator: take OpBuilder
ClosedPublic

Authored by ftynse on May 18 2020, 9:12 AM.

Details

Summary

The SingleBlockImplicitTerminator op trait provides a function
ensureRegionTerminator that injects an appropriate terminator into the block
if necessary, which is used during operation constructing and parsing.
Currently, this function directly modifies the IR using low-level APIs on
Operation and Block. If this function is called from a conversion pattern,
these manipulations are not reflected in the ConversionPatternRewriter and thus
cannot be undone or, worse, lead to tricky memory errors and malformed IR.
Change ensureRegionTerminator to take an instance of OpBuilder instead of
Builder, and use it to construct the block and the terminator when required.
Maintain overloads taking an instance of Builder and creating a simple
OpBuilder to use in parsers, which don't have an OpBuilder and cannot
interact with the dialect conversion mechanism. This change was one of the
reasons to make <OpTy>::build accept an OpBuilder.

Depends On D80137

Diff Detail

Event Timeline

ftynse created this revision.May 18 2020, 9:12 AM
Herald added a project: Restricted Project. · View Herald Transcript

After seeing the stack of CL I am wondering whether RewritePatterns should only operate on Wrapper classes around Region, Block and Operation that would inherit privately.

Thoughts?

nicolasvasilache added inline comments.
mlir/include/mlir/IR/OpDefinition.h
1123

would it be better to make it explicit by having a small wrapper class and force users to cast?
Making the non-safe use case hard here and everywhere else would have likely saved many hours of engineering,

After seeing the stack of CL I am wondering whether RewritePatterns should only operate on Wrapper classes around Region, Block and Operation that would inherit privately.

Thoughts?

I thought about this, but it looks infeasible without reimplementing all of the core classes. E.g., if we pass in an OperationWrapper, but we still want specific ops, we then add a possibility to dyn_cast<SomeOp>, from which an Operaiton * can be trivially extracted. Same for the remaining classes. What we seem to be needing is some const-semantics for IR classes, but we decided against that for good reasons. These reasons would still apply to wrappers that essentially achieves const methods.

ftynse marked an inline comment as done.May 20 2020, 6:27 AM
ftynse added inline comments.
mlir/include/mlir/IR/OpDefinition.h
1123

There are two kinds of users for this: ::build and ::parse. The former has OpBuilder readily available and the latter does not (and neither it should). Unless somebody explicitly upcasts the OpBuilder inside ::build for some reason, this should be fine.

This revision was not accepted when it landed; it landed in state Needs Review.May 20 2020, 7:37 AM
This revision was automatically updated to reflect the committed changes.
rriddle added inline comments.May 27 2020, 1:43 PM
mlir/lib/IR/Operation.cpp
1119

Where is this version called from? Can we remove it?

ftynse marked an inline comment as done.Jun 2 2020, 3:02 AM
ftynse added inline comments.
mlir/lib/IR/Operation.cpp
1119

From SingleBlockImplicitTerminator::ensureTerminator(Region &, Builder &, Location) overload, which in turn is called by various parsers. Since parsers don't have an OpBuilder, we need to construct it somewhere. If we want to remove this, we need to either give parsers an OpBuilder, or require them to construct one before calling ensureTerminator.

Herald added a project: Restricted Project. · View Herald TranscriptJun 2 2020, 3:02 AM