Skip to content

Conversation

nikic
Copy link
Contributor

@nikic nikic commented Sep 15, 2025

This documents two things:

  • The recommended way to go about adding a new pass.
  • The criteria for enabling a pass.

RFC: https://discourse.llvm.org/t/rfc-guidelines-for-adding-enabling-new-passes/88290

a flag that is disabled by default.
2. Enable the pass by default. Separating this step allows easily disabling the
pass if issues are encountered, without having to revert the entire
implementation.
Copy link
Collaborator

@joker-eph joker-eph Sep 15, 2025

Choose a reason for hiding this comment

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

This seems implicit, but may be worth making it explicit a bit more: this strategy seems to rely on the first implementation to be "conservative": that is the "basic version" of the pass is about "doing less" in term of usefulness, but "not miscompiling anything" right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've added an extra sentence "The initial version should focus on handling simple cases correctly and efficiently" here. Is that clearer? Happy to take suggestions on how to improve the wording here.

least one maintainer.
* **Usefulness:** There should be evidence that the pass improves performance
(or whatever metric it optimizes for) on real-world workloads. Improvements
seen only on synthetic benchmarks may be insufficient.
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we should consider distinguishing -O2 and -O3? We already run a lot of passes that do nothing for most functions. For -O2 (the average RelWithDebInfo build) we might want to focus on transforms that have an impact for a broader range of programs and not just a few special workloads.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hm, I guess aspirationally the answer to this is "yes", but I think in practice it is "no". We don't really have a strong distinction between the -O2 and -O3 pipelines, beyond using different inlining/unrolling thresholds. The differences that do exist between the pipelines are not good ones (for example, there is no good reason why ArgumentPromotion should be an O3 pass, it is very much generally useful).

Copy link
Contributor

Choose a reason for hiding this comment

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

I know, but maybe we want to change this at some point? Loop interchange, for example, is likely beneficial for certain programs (probably numerics), but for the average integer-heavy C++ program, it probably has no impact (except for increasing compile times). Perhaps we can start by asking authors for an assessment of the range of programs that will benefit from the transformation if they believe that it should be enabled at -O2?

still complies with current quality standards. Fuzzing with disabled
profitability checks may help gain additional confidence in the
implementation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fuzzing with disabled profitability checks may help gain additional confidence in the implementation.

Yeah, I agree, and for the record, that's exactly what I did with loop-interchange:

Anyway, that is slightly irrelevant for this policy, but just wanted to get this out of the way from previous discussions.

Running fuzzers is slightly less straightforward than it sounds. A good documentation contribution would be to add a howto for this. I am not suggesting it should be here in this section, but I can look where that belongs and prepare a draft how to do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm aware that you did this. I thought it was a sufficiently good idea to include it as a general recommendation :)

Running fuzzers is slightly less straightforward than it sounds. A good documentation contribution would be to add a howto for this. I am not suggesting it should be here in this section, but I can look where that belongs and prepare a draft how to do this.

Sounds good to me.

@sjoerdmeijer
Copy link
Collaborator

Looks generally OK to me.

where the evaluation of what "large" means is up to reviewer discretion, and
may differ based on the value the pass provides. In any case, it is expected
that a concerted effort has been made to mitigate the compile-time impact,
both for the average case, and for pathological cases.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you want to suggest to use your LLVM compile-time tracker for this?

Copy link
Contributor

@madhur13490 madhur13490 Sep 16, 2025

Choose a reason for hiding this comment

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

Yes, a reference to the latest compile-time tracker results should be required. How much impact on compile-time is acceptable? (For loop interchange, we heard 0.19% is "too much"). While we are at it, let's also quantify how much is too much.
Edit: I see that it is left to the reviewer's discretion, but isn't that open-ended?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's not really possible to name a specific number here, because the compile-time impact is a tradeoff against the value the pass provides. A pass that provides a performance benefit on a wide range of code will have a larger compile-time budget than a pass that only benefits rare cases.

Copy link
Contributor

@fhahn fhahn left a comment

Choose a reason for hiding this comment

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

Thanks for putting this up! This matches my expectations, and I think is in line with current practice for enabling new passes in the last few years.

enabled, it becomes easier to identify the specific change that has caused a
regression in correctness, optimization quality or compile-time.

When enabling a pass, regardless of whether it is old or new, certain
Copy link
Contributor

Choose a reason for hiding this comment

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

Might be worth just dropping the old/new distinction, as the steps apply to any pass that needs enabling regardless of the distinction?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've dropped the distinction in this sentence, but I do think separating old/new is important for the correctness aspect. The bar for establishing confidence in the correctness of a pass implemented 15 years ago is different than from one that we reviewed just yesterday.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants