Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mlir][IR] Insert operations before SingleBlock's terminator #65959

Merged
merged 1 commit into from
Sep 15, 2023

Conversation

victor-eds
Copy link
Contributor

@victor-eds victor-eds commented Sep 11, 2023

Change SingleBlock::{insert,push_back} to avoid inserting the argument operation after the block's terminator. This allows removing SingleBlockImplicitTerminator's functions with the same name.

Define Block::hasTerminator checking whether the block has a terminator operation.

Signed-off-by: Victor Perez victor.perez@codeplay.com

@victor-eds victor-eds self-assigned this Sep 11, 2023
@victor-eds victor-eds requested a review from a team as a code owner September 11, 2023 13:05
@llvmbot llvmbot added mlir:core MLIR Core Infrastructure mlir labels Sep 11, 2023
@llvmbot
Copy link
Collaborator

llvmbot commented Sep 11, 2023

@llvm/pr-subscribers-mlir

Changes

Avoid member functions duplication caused by SingleBlockImplicitTerminator now implying SingleBlock (since 0ac21e6).

Full diff: https://github.com/llvm/llvm-project/pull/65959.diff

1 Files Affected:

  • (modified) mlir/include/mlir/IR/OpDefinition.h (-31)
diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h
index 84ba46f4d6f3ec1..fade95f200476f2 100644
--- a/mlir/include/mlir/IR/OpDefinition.h
+++ b/mlir/include/mlir/IR/OpDefinition.h
@@ -996,37 +996,6 @@ struct SingleBlockImplicitTerminator {
       ::mlir::impl::ensureRegionTerminator(region, builder, loc,
                                            buildTerminator);
     }
-
-    //===------------------------------------------------------------------===//
-    // Single Region Utilities
-    //===------------------------------------------------------------------===//
-
-    template 
-    using enable_if_single_region =
-        std::enable_if_t(), T>;
-
-    /// Insert the operation into the back of the body, before the terminator.
-    template 
-    enable_if_single_region push_back(Operation *op) {
-      Block *body = static_cast *>(this)->getBody();
-      insert(Block::iterator(body->getTerminator()), op);
-    }
-
-    /// Insert the operation at the given insertion point. Note: The operation
-    /// is never inserted after the terminator, even if the insertion point is
-    /// end().
-    template 
-    enable_if_single_region insert(Operation *insertPt, Operation *op) {
-      insert(Block::iterator(insertPt), op);
-    }
-    template 
-    enable_if_single_region insert(Block::iterator insertPt,
-                                        Operation *op) {
-      Block *body = static_cast *>(this)->getBody();
-      if (insertPt == body->end())
-        insertPt = Block::iterator(body->getTerminator());
-      body->getOperations().insert(insertPt, op);
-    }
   };
 };
 

@victor-eds
Copy link
Contributor Author

This causes build failures if the member functions are used.

@victor-eds victor-eds changed the title [mlir] Remove duplicated SingleBlockImplicitTerminator member funions [mlir] Remove duplicated SingleBlockImplicitTerminator member functions Sep 11, 2023
@victor-eds victor-eds marked this pull request as draft September 11, 2023 14:05
Change `SingleBlock::{insert,push_back}` to avoid inserting the
argument operation after the block's terminator. This allows removing
`SingleBlockImplicitTerminator`'s functions with the same name.

Define `Block::hasTerminator` checking whether the block has a
terminator operation.

Signed-off-by: Victor Perez <victor.perez@codeplay.com>
@victor-eds victor-eds changed the title [mlir] Remove duplicated SingleBlockImplicitTerminator member functions [mlir][IR] Insert operations before SingleBlock's terminator Sep 13, 2023
@victor-eds victor-eds marked this pull request as ready for review September 13, 2023 11:30
@victor-eds
Copy link
Contributor Author

@matthias-springer updated according to Discourse conversation

@victor-eds victor-eds merged commit 87d77d3 into llvm:main Sep 15, 2023
2 checks passed
@victor-eds victor-eds deleted the single-block-members-dup branch September 15, 2023 14:17
/// Check whether this block has a terminator.
bool Block::hasTerminator() {
return !empty() && back().mightHaveTrait<OpTrait::IsTerminator>();
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

The API is misnamed: this should be "mightHaveTerminator", as the trait check indicates.

Block *body = getBody();
// Insert op before the block's terminator if it has one
if (insertPt == body->end() && body->hasTerminator())
insertPt = Block::iterator(body->getTerminator());
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is not a safe: if there is an unregistered operation at the end of the current block it'll insert before.

I don't see a safe way of doing this actually.

Copy link
Member

@matthias-springer matthias-springer Sep 17, 2023

Choose a reason for hiding this comment

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

Previously, (before 0ac21e6, which made push_back ambiguous) this was actually (somewhat?) safe. SingleBlockImplicitTerminator<OpTy> must be instantiated with an op type, which means that the terminator op must be known (registered?).

I'm wondering if it's better to just always insert at the end of the block. It would simplify the API: no special handling for terminators, it behaves like a vector::push_back.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just a nit: the terminator must be known when the verifier is passing, this may not be the case in the middle of a transformation or while building the operation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changing the definition of hasTerminator so that it checks the last operation is definitely a terminator and keeping current semantics should work, right? (of course reverting the change to the assertion in this PR)

Copy link
Collaborator

Choose a reason for hiding this comment

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

It's not clear to me that it'll fix it: if you can't be sure if the last op is a terminator or not, I don't quite see how you can decide to insert before or after it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My point is: if it is definitely a terminator, do not break the code and insert before it; keep vector::push_back semantics otherwise

Copy link
Collaborator

Choose a reason for hiding this comment

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

This depends if the operation is registered in the MLIRContext, so we're creating a different behavior here, and avoiding this is the reason the "mighHaveTrait" exists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So do you guys think we should just be consistent with vector::push_back semantics and just blame the API user if the code is broken? I'm fine with that, just wanted to keep former semantics.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The push_back approach has the advantage of being consistent in terms of behavior (there is no "gotcha" involved). If there is an API misuse here it'll blow up immediately and consistently.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes total sense. I'll push a follow-up PR.

ZijunZhaoCCK pushed a commit to ZijunZhaoCCK/llvm-project that referenced this pull request Sep 19, 2023
…65959)

Change `SingleBlock::{insert,push_back}` to avoid inserting the argument
operation after the block's terminator. This allows removing
`SingleBlockImplicitTerminator`'s functions with the same name.

Define `Block::hasTerminator` checking whether the block has a
terminator operation.

Signed-off-by: Victor Perez <victor.perez@codeplay.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mlir:core MLIR Core Infrastructure mlir
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants