-
Notifications
You must be signed in to change notification settings - Fork 70
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
Core: Add NoTerminator trait #1049
Conversation
Codecov ReportPatch coverage:
Additional details and impacted files@@ Coverage Diff @@
## main #1049 +/- ##
==========================================
+ Coverage 88.66% 88.68% +0.02%
==========================================
Files 160 160
Lines 22300 22332 +32
Branches 3345 3356 +11
==========================================
+ Hits 19773 19806 +33
+ Misses 1989 1988 -1
Partials 538 538
☔ View full report in Codecov by Sentry. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to check in the MLIR codebase, but what we should have is somewhere a check that all blocks have terminator. I need to look where this check is done though!
xdsl/traits.py
Outdated
|
||
def verify(self, op: Operation) -> None: | ||
for r in op.regions: | ||
if len(r.blocks) > 1: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is actually a bit more complex than that. Here is the "documentation" I could find in MLIR:
In our case, we don't actually need to verify anything in the trait. What we need is somewhere a check that blocks have terminator if the conditions are respected. I'm just not sure where to put it yet, I'll take a look now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah, I found that as well yesterday, good to see, but when I tried to check for the NoTerminator
trait in ir.py
(simulating this), I got a circular dependency in my imports, so that kinda put me off from going that route.
Moreover, I couldn't find any validation for terminators in xDSL. (see comment below)
If I understand correctly, while this trait would be useful for xDSL in general, we'd still want terminators in pretty much all RISC-V blocks, right? @math-fehr |
At least the ones that represent code as opposed to data sections |
That is my understanding by looking at the MLIR verifier. Otherwise, maybe we could have a TerminatorOp that doesn't emit assembly. |
I think that's standard, something like a yield op that just carries on to its successor |
I guess the steps would be:
|
Yeah, I was going to open a PR later for this, but I guess it makes sense to add it first. Regarding, the MLIR implementation of this and |
Seems like riscv.ret would benefit from the Terminator trait, and then we could add a yield operation for other control flow like things |
yeah exactly and combine that with |
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A big PR, but I don't think we can reduce it much further!
@@ -6,12 +6,14 @@ | |||
%y = "op_with_res"() {otherattr = #unknown_attr<b2 ...2 [] <<>>>} : () -> (i32) | |||
%z = "op_with_operands"(%y, %y) : (i32, i32) -> !unknown_type<{[<()>]}> | |||
"op"() {ab = !unknown_singleton_type} : () -> () | |||
"test.termop"() : () -> () |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks suspicious to me.
If an operation is not registered, we cannot require a terminator, as we don't know if the operation has a NoTerminator
trait or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, let's do that in another PR, I need to add HasMaybeTrait
that does exactly that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, that goes back to a question I had regarding unregistered ops in xDSL.
I can have a look at that, basically, it will be modelled after hasTrait
but take into account if an op is not registered, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened an issue to track this #1167
) | ||
if parent_block.last_op == self: | ||
if len(parent_region.blocks) == 1: | ||
if ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a case missing where we have NoTerminator
but have been given a terminator?
Or is this handle somewhere else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you mean the check in Block.verify()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this checks it as well.
If we have
builtin.module {
test.term_op
}
this should fail because the last operation of a NoTerminator
operation is a terminator.
But I don't see any check for that here or in Block.verify()
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, forget my Block.verify
comment, I misunderstood there.
The way I read it was that if the NoTerminator
trait is applied, no need to do any further checking.
If it doesn't exist, then the IsTerminator
is required on the last operation.
Basically, the last few lines here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a test case regarding this @math-fehr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks for the PR :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
This PR adds the
NoTerminator
trait.A current issue is that the IRDL annotations (e.g.,
SingleBlockRegion
, etc) operate separately from this trait.I'm not sure if the link between the two should be checked before an operation's
verify
method, i.e. during construction, or type-checked in this trait'sverify
method.Any feedback on this is welcome.