-
Notifications
You must be signed in to change notification settings - Fork 445
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
Follow-up issue on exit statements #2358
Comments
The first transform moves the copyback to eth_hdr.src_addr after the return where it will never happen (due to the exit), which I think is incorrect (if this is incorrect). To make it correct, we need to first get rid of the |
We already have a pass which removes |
Actually, that pass implements exit entirely by control-flow, by having a global flag in each control that indicates that the program has exited. |
I guess we only need to eliminate exits that are in function/actions with out or inout arguments. Not sure if that is worth worrying about. |
We can also make this a back-end policy which indicates whether the back-end natively supports exit. If it does, we can indeed be more efficient in actions without out arguments. Functions should be inlined, so they should not cause problems. |
According to the language spec, only controls or actions may contain |
I think we also allow targets to not support actions with out or inout arguments as well -- at least for putting into tables. It's not clear if such actions make sense -- allowing the control plane to specify different fields for actions in a table to modify is hard to implement, and impossible to analyze. |
Actually this is a deeper bug than I implied. The program produced by the sideEffectOrdering pass is already incorrect, since it assumes that the callee will return to the caller, which is not true if exit is called. That program is already incorrect, and no matter what we do in the RemoveExits pass will not fix the program. |
This is what you would get after RemoveExits:
|
The compiler has skipped the copy-out if the exit has occurred. |
this is a bit like a java |
We need RemoveExits before SideEffectOrdering. Requiring that side effects happen in a specific order adds a lot of extra work to the compiler... |
That will be very difficult, because you can have very complex expressions involving multiple calls that could each invoke exit... My RemoveExits pass assumes that each statement has at most one call that could invoke exit. Consider something like |
that's the whole point of SideEffectOrdering: it makes all subsequent passes simpler. That pass is very annoying to write. I wish we had no out parameters, they mess up everything. |
How is it possible to have a complex expression that invoke exit? The only expression that I can think of that can invoke exit is And it isn't completely clear to me if the language spec precisely defines what happens if |
Created this issue on the P4 language spec, in case the answers are subtler than I can think of so far: p4lang/p4-spec#856 |
I can imagine two solutions for this problem:
|
Sorry, I came late to the party. We do need to fix exit and return in action or the IR seen by the backend is incorrect. Regarding a solution, I agree with @mbudiu-vmw. I don't like either of the solutions. However, I prefer 1 even if it's ugly because the solution does not complicate code. See #2374 and
|
This issue, issue #2374, and issue #2382, all need to operate on an action body for exit. So, I developed some code to help the effort. From this code, anyone who understands the SideEffectOrdering pass can take over. See https://gitlab.com/hemant_mnkcg/p4c-defuse/-/commit/4d5338ea96209e628cc190d5f9d8257214123bd2 I will continue to study the SideEffectOrdering pass to understand it better. |
I had suggested an analysis solution 3 days ago. Today I developed an example for the solution in p4c to fix #2374. Please see this commit. @mbudiu-vmw Please check if the frontend and midend output look acceptable to you - thanks. For reference, the P4 program is here. The output files are at this repo.
Next, I plan to extend the example to remove an exit statement to fix #2382 |
Even if section 11.5 says "The exit statement immediately terminates the execution of all the blocks currently executing", but thereafter, says "the current action (if invoked within an action)", I got confused. My confusion stems from the fact that an action is always invoked from the apply block, so why bother qualifying text to say "exit action" or "exit control"? For both cases, the control is exited. |
"the current action (if invoked within an action)" is intended to mean "the current action (if the exit statement is invoked within an action)". exit statements can be performed within actions, or within control apply blocks, so the first phrase "the current action" does not apply for exit statements performed within a control apply block, because in that case there is no current action. |
This text later in the section makes me think "the control is not exited" because some operations are still performed. I think, adding a P4 code example with out or inout parameters would be useful. One of Fruffy's issues for exit could be used to steal the example code. "Any copy-out behavior due to direction out or inout parameters of the enclosing action or control, and all of its callers, are still performed after the execution of the exit statement." |
The enclosing control is exited, always. The copy-out behavior (up the entire "call stack") is the only thing done after the exit statement is executed -- nothing else. |
If an action has if-else statement with an exit statement in the body, it gets tricky to fix the issue. I don't think p4c checks for semantics inside an if or else statement. I see the compile-design slides mention semantics in relation to the SideEffectOrdering pass. I think we do have to support if-else with exit for an action with inout or out parameters, don' t we? |
Posting the same text against this issue. Sorry, I had posted this note against another exit issue. @mbudiu-vmw Having poked around more, I see p4c already supports an exit statement inside if-else. For example, I found p4c/testdata/p4_16_samples/exit2.p4. This test case does not include any action with hasOut parameter or even a parameter. But the control the action is inside has an out parameter. So now, one should also check if the control has a hasOut parameter and remove exit statement(s) from control actions. The current behavior for handling exit in exti2.p4 looks correct to me. Should we bother changing the behavior for such a test if exits are removed in frontend code? |
Another silly This program control ingress(inout Headers h) {
action reset_action(in Headers in_hdr, out Headers out_hdr) {
exit;
}
apply {
reset_action(h, h);
} } control ingress(inout Headers h) {
@name("reset_action") action reset_action_0(in Headers in_hdr, out Headers out_hdr) {
exit;
}
Headers tmp;
Headers tmp_0;
apply {
{
tmp = h;
reset_action_0(tmp, tmp_0);
h = tmp_0;
}
}
} Which neglects the "reset" done by the |
Seems like this problem also got fixed by #2640. Closing this issue. |
As @jafingerhut pointed out in #2225 , there might be some fallout from the exit changes. One of them is an edge-case in how to handle
SideEffectOrdering
.SideEffectOrdering
transforms the following program:into
which still looks okay, but ultimately this change causes this transformation in the MidEnd pass
RemoveActionParameters
:Here,
h.eth_hdr.src_addr
will never be assigned the value1
, from what I can tell.side_effect_ordering_exit.p4.txt
side_effect_ordering_exit.stf.txt
The text was updated successfully, but these errors were encountered: