-
Notifications
You must be signed in to change notification settings - Fork 442
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
[#4656] Explicitly delay constant folding of only action enum IR::SwitchCase
label
expressions, instead of delaying constant folding of all IR::Mux
expressions
#4657
Conversation
@jphurl @oleg-ran-amd I cannot request your review, but feel free to review this too. |
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 am only reviewing the new test program and its expected outputs, not the C++ code changes inside the compiler. That part of this PR looks good to me.
The failing error tests need to be debugged.. |
frontends/common/constantFolding.cpp
Outdated
// Action enum switch case labels must be action names. | ||
// If we are in the context of a switch label, we want the typechecker | ||
// to look at the label expression first. | ||
if (const auto *switchStatement = findContext<IR::SwitchStatement>()) { |
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 wonder how expensive this search could be for deeply nested expressions...
In the worst case it will traverse to the root for each mux expression.
Maybe #3622 should be valid code instead?
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 thought that #3633 was added because:
- P4 spec says that action enum switch labels can only be action names, and Do not constant fold mux before it has been typechecked #3633 prevents them from being mux expressions that evaluate to action names at compile-time
- P4 spec says that mux cannot act on action decls at all
I have not looked at the spec to verify (1) or (2). I am just going by what was stated in #3622 (comment).
I am fine with reverting #3633 if you don't think we actually need the error message added by it.
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 have been thinking about changing the specification. I wonder whether there are any downsides in having compile-time-known ternary operator support for labels.
I just did some quick performance measurements and this change does not cause that significant of a degradation for me, which is good.
Would be great to have an approach that does not require searching for the context for every Mux, but I can not think of one right 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.
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 wonder how expensive this search could be for deeply nested expressions...
In the worst case it will traverse to the root for each mux expression.
I really do not think it is a problem. There are lots of much more severe overheads in other places, so this is just noise. We can certainly think of speeding-up findContext
in general :)
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.
Well, it can have some impact for analysis tools that use constant folding on complex expressions. In the case of the tool I am using, it looks like it causes a ~6% slowdown on larger programs. But I understand that this is a non-standard use of the pass.
My concern is that this can be a death-by-a-thousand-paper-cuts type of situation. The transform pass can definitely be improved to be faster etc but we are also introducing some inefficient lookups 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.
My concern is that this can be a death-by-a-thousand-paper-cuts type of situation.
And we are already here actually :)
The transform pass can definitely be improved to be faster etc but we are also some inefficient lookups here.
+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.
@fruffy Hopefully the recent changes will eliminate your concerns about the performance.
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 is a good solution, thanks!
IR::Mux
expressions only if we are inside of a label of an action enum SwitchStatement
IR::Mux
expressions only if we are inside of a label of a SwitchStatement
IR::Mux
expressions only if we are inside of a label of a SwitchStatement
IR::SwitchCase
label
expressions, instead of delaying constant folding of all IR::Mux
expressions
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!
What about case statements that contain non-mux constant expressions? Previously these would be folded. Perhaps only folding them after typechecking is fine? I don't see any testcases that excercise this currently. |
Agh right. We may have switch statements that are not switching on tables but on normal expressions. But this should be okay since the expressions are folded after type-checking has completed? A little fragile though... |
The purpose of #3633 was to make sure that only action names are used in labels of action enum switch statement cases. It did not actually do that. It only made sure that mux expressions were not used in labels of action enum switch statement cases. Now, any non-action-name expression in switch statement case labels will not be folded and can be inspected in the first type inference pass. The side-effect is that regular switch statement case labels are no longer folded until after the first type inference pass, which I think is ok. |
Unfortunately, I don't think that a switch statement's type is known until after the first type inference pass, so it cannot be checked in the first constant folding pass.. |
My concern is if there's some code that would flag the case label expression as not being a constant if it hasn't been folded yet. Maybe add a testcase like that to see what happens. We have a number of tests with |
Actually, let me see if I can make use of |
Yeah, checking whether a switch statement's expression is an action_run expression will be difficult in the first constant folding pass, as types are not yet known there. Neither Unfortunately, having compile-time constant expressions in regular switch case labels will now result in an error on this branch, which is not good. So the options are:
My preference is (1), or (3) if somebody has a more robust solution that they want to suggest. Also, I have added a test that shows the problem brought up by @ChrisDodd. |
d742c6b
to
b444092
Compare
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 looks like a reasonable compromise to me. I only have some tweak suggestions for the preorder(IR::SwitchCase *c)
.
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.
Just added some optional nits, approving from my side. Thanks for finding a good solution here!
const IR::Node *DoConstantFolding::preorder(IR::SwitchCase *c) { | ||
// Action enum switch case labels must be action names. | ||
// We only want to fold the label expression after it is inspected by the typechecker. | ||
const auto *parent = static_cast<const IR::SwitchStatement *>(getContext()->node); |
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.
How about using the preorder function for IR::SwitchStatement
then? Otherwise, I would just add a comment explaining why the static_cast was used.
IR::SwitchCase
label
expressions, instead of delaying constant folding of all IR::Mux
expressionsIR::SwitchCase
label
expressions, instead of delaying constant folding of all IR::Mux
expressions
@fruffy Is there a known issue with the CI? Looks like it is stuck |
No, nothing known. This seems like an issue on the Github side? It could also just be that we are currently consuming to many resources and are rate-limited. |
… label of an action enum SwitchStatement
…n't know if it is an action enum switch statement until after type inference has run.
…switch statement labels
… action_run expression
merging soon if no other concerns |
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.
Approving from my side.
This is one possible fix for #4656.
For example, one possible alternative might be to revert #3633 and add a check for action enum
SwitchStatement
labels, similar to the one in theTypeInference
pass, toValidateParsedProgram
.