(I'm probably going to derail your thread, sorry about that.)
I think at this point, we should just bite the bullet and make the switch to NPM by default for Clang's optimization pipeline. Today.
Why? Because many of our downstream consumers have already switched. Google has. We (Azul) have. I think I've heard the same for a couple other major contributors. Why does this matter? Testing. At the current moment, the vast majority of testing the project gets is exercising NPM, not LPM.
NPM is functionally complete for Clang optimization. There might be a few missing cases around the sanitizers, but last I heard those were on the edge of being fixed.
I think we should make the switch, and deal with any fall out as
regressions. If we made the change immediately after a release
branch, we'd have several months to address any major issues
before the next release.
Philip
_______________________________________________ LLVM Developers mailing list llvm...@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
From: llvm-dev <llvm-dev...@lists.llvm.org>
On Behalf Of Arthur Eubanks via llvm-dev
Sent: Wednesday, July 22, 2020 2:39 PM
To: llvm-dev <llvm...@lists.llvm.org>
Subject: [llvm-dev] New pass manager for optimization pipeline status and questions
Hi all,
I wanted to give a quick update on the status of NPM for the IR optimization pipeline and ask some questions.
In the past I believe there were thoughts that NPM was basically ready because all of check-llvm and check-clang passed when -DENABLE_EXPERIMENTAL_NEW_PASS_MANAGER=ON was specified. But that CMake flag did not apply to opt and any tests running something like `opt -foo-pass -bar-pass` (which is the vast majority of check-llvm tests) were still using the legacy PM. The intended way to use NPM was to use the -passes flag, e.g. `opt -passes='foo,bar'`.
I've added a -enable-new-pm flag to opt to force running NPM passes even when `opt -foo-pass` is used. This is because I didn't want to go through every single test and figure out which ones should be using both -foo-pass and -passes=foo. Switching on -enable-new-pm currently leads to ~1800 check-llvm failures. I've documented the failed tests count per directory in https://bugs.llvm.org/show_bug.cgi?id=46651 (some have been fixed since that was posted).
This has led to real bugs in NPM being discovered and fixed (e.g. some optnone issues).
But a large portion of the remaining failures are because codegen-only passes haven't been ported to NPM yet. That's fine for the optimization pipeline NPM transition since it doesn't affect the optimization pipeline, but it does present an issue with the approach of the -enable-new-pm flag (which would by default become true alongside the NPM transition). Lots of tests are testing codegen-specific passes via opt (e.g. `opt -amdgpu-lower-intrinsics`) and they can't use NPM (yet).
I think the ideal way is just to port these to NPM. The problem is if the opt pipeline NPM switch is blocked on this, we’re forcing the targets to start porting which I’m not sure if target owners want to do.
On the other end, we’re (almost) actually ready to make these target IR passes use NPM for testing purpose with `opt` tool. Except there needs a way to expose these passes through llvm/lib/Target, llvm/lib/CodeGen rather than llvm/lib/Passes to `opt`. As part of the codegen using NPM work, this is almost done.
I was thinking either we have a way of identifying codegen-only passes and revert back to the legacy PM in opt whenever we see one, or we go back to considering the originally intended approach of adding an equivalent `-passes=` RUN to all tests that should be also running under NPM.
I would prefer the former since it sounds less pervasive.
I'm not sure of a nice and clean solution to identify codegen-only passes. We could go and update every instance of INITIALIZE_PASS to take another parameter indicating if it's codegen-only. Or we could just have a central list somewhere where we check if the pass is in some hardcoded list or has some prefix (e.g. "x86-").
The latter seems in line with the progress has been made on codegen using NPM work where each target would maintain their own pass registry like PassRegister.def. For x86, it is (tentatively) called X86PassRegistry.def. (https://reviews.llvm.org/D83613). If It is useful for the opt pipeline NPM switch, we could find a way to factor it out.
I can't speak for other targets but I'd love to get AMDGPU passes
converted to the NPM. Is there a howto somewhere?
Thanks,
Jay.
My guess would instead be that the vast majority of projects using
LLVM are using default pass manager. I know Chrome uses the default. I
know that's how the upstream releases are built and tested. Defaults
tend to be popular. All our docs about writing passes and such seem to
assume the default pm.
I guess what I'm saying is I think the transition has to be more
careful than biting the bullet and throwing the switch today.
From: llvm-dev <llvm-dev...@lists.llvm.org> On Behalf Of Arthur Eubanks via llvm-dev
Sent: Wednesday, July 22, 2020 2:39 PM
To: llvm-dev <llvm...@lists.llvm.org>
Subject: [llvm-dev] New pass manager for optimization pipeline status and questions
Hi all,
I wanted to give a quick update on the status of NPM for the IR optimization pipeline and ask some questions.
In the past I believe there were thoughts that NPM was basically ready because all of check-llvm and check-clang passed when -DENABLE_EXPERIMENTAL_NEW_PASS_MANAGER=ON was specified. But that CMake flag did not apply to opt and any tests running something like `opt -foo-pass -bar-pass` (which is the vast majority of check-llvm tests) were still using the legacy PM. The intended way to use NPM was to use the -passes flag, e.g. `opt -passes='foo,bar'`.
I've added a -enable-new-pm flag to opt to force running NPM passes even when `opt -foo-pass` is used. This is because I didn't want to go through every single test and figure out which ones should be using both -foo-pass and -passes=foo. Switching on -enable-new-pm currently leads to ~1800 check-llvm failures. I've documented the failed tests count per directory in https://bugs.llvm.org/show_bug.cgi?id=46651 (some have been fixed since that was posted).
This has led to real bugs in NPM being discovered and fixed (e.g. some optnone issues).
But a large portion of the remaining failures are because codegen-only passes haven't been ported to NPM yet. That's fine for the optimization pipeline NPM transition since it doesn't affect the optimization pipeline, but it does present an issue with the approach of the -enable-new-pm flag (which would by default become true alongside the NPM transition). Lots of tests are testing codegen-specific passes via opt (e.g. `opt -amdgpu-lower-intrinsics`) and they can't use NPM (yet).
I think the ideal way is just to port these to NPM. The problem is if the opt pipeline NPM switch is blocked on this, we’re forcing the targets to start porting which I’m not sure if target owners want to do.
On the other end, we’re (almost) actually ready to make these target IR passes use NPM for testing purpose with `opt` tool. Except there needs a way to expose these passes through llvm/lib/Target, llvm/lib/CodeGen rather than llvm/lib/Passes to `opt`. As part of the codegen using NPM work, this is almost done.
I was thinking either we have a way of identifying codegen-only passes and revert back to the legacy PM in opt whenever we see one, or we go back to considering the originally intended approach of adding an equivalent `-passes=` RUN to all tests that should be also running under NPM.
I would prefer the former since it sounds less pervasive.
I'm not sure of a nice and clean solution to identify codegen-only passes. We could go and update every instance of INITIALIZE_PASS to take another parameter indicating if it's codegen-only. Or we could just have a central list somewhere where we check if the pass is in some hardcoded list or has some prefix (e.g. "x86-").
The latter seems in line with the progress has been made on codegen using NPM work where each target would maintain their own pass registry like PassRegister.def. For x86, it is (tentatively) called X86PassRegistry.def. (https://reviews.llvm.org/D83613). If It is useful for the opt pipeline NPM switch, we could find a way to factor it out.
The approach of adding equivalent `-passes=` RUN lines to all relevant tests seems daunting, but not exactly sure how daunting. Maybe it's possible to script something and see what fails? We'd still need some way to identify codegen-only passes to make sure we don't miss anything, and we'd need to distinguish between analyses and normal passes. Also, it would slow down test execution since we'd run a lot more tests twice, but maybe that's not such a big deal? Maybe it's good to have most tests running against the legacy PM even when NPM is on by default?
Thoughts?
This is split off from http://lists.llvm.org/pipermail/llvm-dev/2020-July/143395.html.
I can't speak for other targets but I'd love to get AMDGPU passes converted to the NPM. Is there a howto somewhere?
From: Arthur Eubanks <aeub...@google.com>
Sent: Thursday, July 23, 2020 10:58 AM
To: Chen, Yuanfang <Yuanfa...@sony.com>
Cc: LLVM Developers' List <llvm...@lists.llvm.org>
Subject: Re: [llvm-dev] New pass manager for optimization pipeline status and questions
On Wed, Jul 22, 2020 at 4:05 PM Chen, Yuanfang <Yuanfa...@sony.com> wrote:
From: llvm-dev <llvm-dev...@lists.llvm.org> On Behalf Of Arthur Eubanks via llvm-dev
Sent: Wednesday, July 22, 2020 2:39 PM
To: llvm-dev <llvm...@lists.llvm.org>
Subject: [llvm-dev] New pass manager for optimization pipeline status and questions
Hi all,
I wanted to give a quick update on the status of NPM for the IR optimization pipeline and ask some questions.
In the past I believe there were thoughts that NPM was basically ready because all of check-llvm and check-clang passed when -DENABLE_EXPERIMENTAL_NEW_PASS_MANAGER=ON was specified. But that CMake flag did not apply to opt and any tests running something like `opt -foo-pass -bar-pass` (which is the vast majority of check-llvm tests) were still using the legacy PM. The intended way to use NPM was to use the -passes flag, e.g. `opt -passes='foo,bar'`.
I've added a -enable-new-pm flag to opt to force running NPM passes even when `opt -foo-pass` is used. This is because I didn't want to go through every single test and figure out which ones should be using both -foo-pass and -passes=foo. Switching on -enable-new-pm currently leads to ~1800 check-llvm failures. I've documented the failed tests count per directory in https://bugs.llvm.org/show_bug.cgi?id=46651 (some have been fixed since that was posted).
This has led to real bugs in NPM being discovered and fixed (e.g. some optnone issues).
But a large portion of the remaining failures are because codegen-only passes haven't been ported to NPM yet. That's fine for the optimization pipeline NPM transition since it doesn't affect the optimization pipeline, but it does present an issue with the approach of the -enable-new-pm flag (which would by default become true alongside the NPM transition). Lots of tests are testing codegen-specific passes via opt (e.g. `opt -amdgpu-lower-intrinsics`) and they can't use NPM (yet).
I think the ideal way is just to port these to NPM. The problem is if the opt pipeline NPM switch is blocked on this, we’re forcing the targets to start porting which I’m not sure if target owners want to do.
On the other end, we’re (almost) actually ready to make these target IR passes use NPM for testing purpose with `opt` tool. Except there needs a way to expose these passes through llvm/lib/Target, llvm/lib/CodeGen rather than llvm/lib/Passes to `opt`. As part of the codegen using NPM work, this is almost done.
Grepping for INITIALIZE_PASS in llvm/lib/Target, there are 220 files with that. That means there are ~200 target specific passes. There's no way we'll be able to port all of those in a reasonable amount of time.
Plus it's not a blocker if we can detect passes are target specific and simply revert to the legacy PM in opt. Then as codegen passes are ported to NPM we can start running those on NPM instead reverting back to the legacy PM. The exact mechanism for this TBD, although probably something similar to below.
220 should include machine passes. If you grep “public FunctionPass/ModulePass etc.”, we should be looking at ~60 and not every each of them is registered (tested by `opt`). A lot of them are from AMDGPU. Other than AMDGPU, each target has 2 or 3 on average. If AMDGPU is willing to actively be involved in this and the other targets could migrate theirs, this could not only helps opt pipeline switch but also the codegen pipeline switch. Again, I meant to say these are all “ideal” situation.
I was thinking either we have a way of identifying codegen-only passes and revert back to the legacy PM in opt whenever we see one, or we go back to considering the originally intended approach of adding an equivalent `-passes=` RUN to all tests that should be also running under NPM.
I would prefer the former since it sounds less pervasive.
I'm not sure of a nice and clean solution to identify codegen-only passes. We could go and update every instance of INITIALIZE_PASS to take another parameter indicating if it's codegen-only. Or we could just have a central list somewhere where we check if the pass is in some hardcoded list or has some prefix (e.g. "x86-").
The latter seems in line with the progress has been made on codegen using NPM work where each target would maintain their own pass registry like PassRegister.def. For x86, it is (tentatively) called X86PassRegistry.def. (https://reviews.llvm.org/D83613). If It is useful for the opt pipeline NPM switch, we could find a way to factor it out.
If we can add an equivalent of something like PassBuilder::isAAPassName() to https://reviews.llvm.org/D83613 (X86CodeGenPassBuilder::isX86CodeGenPassName()?) that would definitely work.
That should be straightforward. I’ll see if I could split it out from the patch.
Hi Alina,
I think this is an excellent direction, this is the direction we should take here. Just a somewhat irrelevant disagreement on this though:
> Philip's point is spot on that we are deficient now in the testing of the LegacyPassManager,
I disagree because the LPM is still the default and I appreciated Hans' reply: "Defaults tend to be popular". But this is the direction I like:
> This means prioritizing those blockers over other LLVM work. The current umbrella bug is PR46649.Just checking: do you accept both performance and code-size regressions as blockers here?
> My point is that we want and should work with users to make the transition smooth, but we do very much need user (meaning companies using LLVM) involvement here in order to not delay the switch further.
That's clear, and agreed.I would like to remark here that currently, when a commit regresses one benchmark that is important for someone, that is enough justification most of the time for a revert of that commit. That's why I surprised that it looked like we were not setting code-quality goals and requirements before switching. And what I would like to ask here is to provide reasonable enough time for people to look into switching to the NPM, to evaluate this, and then file bugs under PR46649. Just collecting data, evaluating problems, filings bugs can already time-consuming, and then I guess they need fixing too. This also needs to fit in people's plans right now.
But it sounds reasonable to me that this is time-boxed. Given that switching is quite some work I think, switching before the clang-12 release would be unreasonable, and if clang-13 is in half a year from now, that already sounds perhaps somewhat reasonable, but might be tight.
Hi,
> Yes, I think big performance and code-size regressions need to be investigated. It will be hard to quantify what "big" is though, but we should definitely track such regressions.> Due to the time-boxed approach we may need to discuss moving forward with the switch with some regressions deemed acceptable, but those considered blockers should be prioritized of course.
Agreed, SGTM.
> I think it's reasonable to add a firm switch before clang-13 and before the end of this year, with intermediary milestones (e.g. filing blockers for user regressions in the next 1-2 months).> I'm inclined to favor a tighter deadline, the motivation here being to ensure that working on potential blockers is prioritized with plenty of time to spare, so the switch remains time-boxed.
I am not entirely sure yet about the tighter deadline, but I am optimistic things might start falling into place soon. Let me explain.
I think you've noticed the code-size issue that I raised. Switching before that being fixed would be a real non-starter for us, but if there's consensus the community want to switch then we'll deal with that of course.
Because (some) of these regression are so big, I am hoping we are missing something obvious and that with a few things fixed we solve most of these cases, which is why I am optimistic, and also because of next point:
After code-size, I'm now looking at performance, and things look a lot better there for us. I do see some up and down behaviour: some wins in some benchmarks overall, but also some regressions. I will need to do some more homework here, as I need to check if small downstream divergence play a role here, and need to eliminate that. In some benchmarks where we win overall, there are a few cases that we really don't want to regress, so I need to look into this. I think these are problems that we need to fix, but I will start raising issues for them just for visibility. Overall, there are less to none non-starters in this area I think.
But because these are time-consuming exercises, and it's the summer months, I am getting slightly nervous about the tight(er) deadline. :-)
Cheers,Sjoerd.
Just wanted to comment that I'm thrilled to see us at this point
finally. This is long overdue. Arthur, thank you for all the
work making this happen!
Philip