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

Add @likely/@unlikely annotations for blocks #4979

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ChrisDodd
Copy link
Contributor

These will generally be used by backends and simply passed through the frontend/midend, so not much is needed here.

Perhaps some frontend passes (in particular, DoSimplifyControlFlow in frontends/p4/simplify.cpp) could be extended to understand these -- currently, any annotations on a block will inhibit combining the blocks, whereas @likely/@unlikely on a block should not inhibit combining it with a block with no annotation (the annotation should be on the resulting combined block).

See discussion in p4lang/p4-spec#1308

@fruffy fruffy added the p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/). label Oct 24, 2024
@kfcripps kfcripps requested a review from asl October 24, 2024 13:28
@ChrisDodd ChrisDodd marked this pull request as draft October 24, 2024 21:48
@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 3 times, most recently from d86089f to d482036 Compare October 28, 2024 03:35
@ChrisDodd ChrisDodd marked this pull request as ready for review October 28, 2024 03:36
@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 2 times, most recently from 46257c9 to 1847985 Compare October 31, 2024 20:28
@ChrisDodd ChrisDodd requested review from vlstill and fruffy October 31, 2024 21:38
Copy link
Contributor

@vlstill vlstill left a comment

Choose a reason for hiding this comment

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

Perhaps some frontend passes (in particular, DoSimplifyControlFlow in frontends/p4/simplify.cpp) could be extended to understand these -- currently, any annotations on a block will inhibit combining the blocks, whereas @likely/@unlikely on a block should not inhibit combining it with a block with no annotation (the annotation should be on the resulting combined block).

Sounds reasonable. Is there a risk that the annotation will currently inhibit some optimization? That would be very unfortunate.

However, if we start merging blocks where the annotations don't match exactly, could we end up with both @likely and @unlikely on a single blocks? What should be done then? Imagine code like this:

if (some_runtime_condition) @likely {
    if (some_condition_compiler_proves_true) @unlikely {
        code;
    }
}

obviously, this example is a bit pathological as the code claims the branch is unlikely, but the compiler proves it can be taken always.

@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 6 times, most recently from b116b77 to ecb291c Compare December 9, 2024 20:48
@ChrisDodd ChrisDodd requested a review from vlstill December 11, 2024 22:03
@ChrisDodd
Copy link
Contributor Author

So it seems that something like

if (condition_that_is_always_true) @likely {  ...some code... }

is quite plausible, and if the compiler can prove it is always true and remove the if, it should probably also remove the @likely. For the more pathological case of having an @unlikely here, it should probably also remove it, as it just seems wrong. Maybe a warning about that?

@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 2 times, most recently from 05e10e9 to da01db2 Compare December 16, 2024 00:23
@ChrisDodd
Copy link
Contributor Author

So I've added warnings for always taken/@unlikely and never taken/@likely branches and a testcase. Overall, I think this is ready to go -- do we need more discussion in the LDWG next week?

@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 3 times, most recently from f1652aa to 35b4a33 Compare January 7, 2025 07:02
@ChrisDodd ChrisDodd enabled auto-merge January 14, 2025 23:32
@jafingerhut
Copy link
Contributor

@asl @fruffy @vlstill (and anyone else interested, of course) -- We discussed this PR, and the corresponding issue considering adding these new annotations to the language spec, at the 2025-Jan-13 language design work group meeting. Chris is hoping that these changes can be approved and merged before he starts work on a PR for the language spec describing these annotations.

@ChrisDodd
Copy link
Contributor Author

@asl @fruffy @vlstill @jafingerhut -- is it possible to get a review/approval for this?

@asl
Copy link
Contributor

asl commented Jan 17, 2025

@asl @fruffy @vlstill @jafingerhut -- is it possible to get a review/approval for this?

Thanks! I will review soon

Copy link
Contributor

@vlstill vlstill left a comment

Choose a reason for hiding this comment

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

What should be the intended meaning of these cases:

apply {
    @likely {
        // code (1)
    }
    @unlikely {
        // (2)
    }
    if (foo) {
        // ...
    } else @likely {
        // (3)
    }
}

They are permitted by the grammar, should there be warning for (2), maybe even for (1) as it is is suspicious? Is (3) intended to be equivalent to having the opposite annotation on the "then" branch. Maybe there should be just a general warning pass that warns on any unconditional @likely/@unlikely and maybe even simplifies case (3). Plus there probably should be warning for something like if (foo) @likely @unlikely which is also entirely permissible in the grammar.


I was thinking if there is a better way than attaching this just to block statements. But probably not, it does not seem right to have a special attachment point for annotations in if/switch just for this case. This does not work for non-block-statement if though, because statements generally aren't annotated. Again, this is probably OK.

We might want to extend selectCase to something like this though:

selectCase
    : keysetExpression ":" optAnnotations name ";"
    ;

Summary: This looks reasonable to me. I think the if (true) @unlikely warning should be added in this PR, the rest can be probably done later (including the select expression for its similarity with switch).

@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 2 times, most recently from 33d2886 to 1cb5b44 Compare February 3, 2025 04:38
@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 2 times, most recently from feec6c0 to 01d18b2 Compare February 18, 2025 04:25
@ChrisDodd
Copy link
Contributor Author

Summary: This looks reasonable to me. I think the if (true) @unlikely warning should be added in this PR, the rest can be probably done later (including the select expression for its similarity with switch).

I added that (as well as if (false) @likely) warning. However, there's currently no message for @likely/@unlikely on a block that is not part of an if or case. A backend can take such annotations into account if it wants to put a meaning on them.

Copy link
Contributor

@asl asl left a comment

Choose a reason for hiding this comment

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

See comments

return ifstmt->ifTrue;
if (auto blk = ifstmt->ifFalse ? ifstmt->ifFalse->to<IR::BlockStatement>() : nullptr) {
if (auto annot = blk->getAnnotation(IR::Annotation::likelyAnnotation))
warning(ErrorType::WARN_IGNORE, "ignoring %1% on never taken statement", annot);
Copy link
Contributor

Choose a reason for hiding this comment

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

Won't it be too verbose? I can easily see that unlikely case could appear after some e.g. generic routine would be inlined and then condition will be constfolded on e.g. on error path? Something like this:

function generic() {
  if (not error)  @likely {
   dosomething();
  } else {
    dootherthing();
  }
}

function handle_error() {
  generic();
}

As a comparison, C/C++ compilers do not produce diagnostics while constfolding __builtin_expect and friends.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Trying to find a happy medium between too verbose and not verbose enough. @vlstill requested this warning, and it is just a warning. Perhaps leave it and see if anyone complains?

@ChrisDodd ChrisDodd force-pushed the cdodd-likely branch 2 times, most recently from 03b99dd to 3cebcdc Compare February 26, 2025 03:48
@ChrisDodd ChrisDodd requested a review from asl March 1, 2025 08:12
@ChrisDodd
Copy link
Contributor Author

I think this PR is ready to go, except for discussion on what should and should not be a warning. @asl, @vlstill what do you think?

- fix a few places annotations on blocks are accidentally lost
- allow merging blocks with same annotation

Signed-off-by: Chris Dodd <[email protected]>
Signed-off-by: Chris Dodd <[email protected]>
- warn if @unlikely is always taken.

Signed-off-by: Chris Dodd <[email protected]>
Signed-off-by: Chris Dodd <[email protected]>
@ChrisDodd
Copy link
Contributor Author

@fruffy @jafingerhut -- can I get approval for this PR?

@jafingerhut
Copy link
Contributor

@ChrisDodd Given my familiarity with only a tiny subset of the C++ implementation code for p4c, unfortunately I don't think I'm qualified to review that, and that is pretty critical here.

@asl
Copy link
Contributor

asl commented Mar 5, 2025

I think this PR is ready to go, except for discussion on what should and should not be a warning. @asl, @vlstill what do you think?

Yeah. @vlstill what do you think for the warning? I doubt that it should be there and e.g. existing practice with C/C++ compilers with __builtin_expect shows that we might easily inline through unexpected branch (e.g. inside error path handling) and therefore things will be too verbose.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p4-spec Topics related to the P4 specification (https://github.com/p4lang/p4-spec/).
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants