This is an archive of the discontinued LLVM Phabricator instance.

[PM] Significantly refactor the pass pipeline parsing to be easier to reason about and less error prone.
ClosedPublic

Authored by chandlerc on Jul 23 2016, 1:41 AM.

Details

Summary

The core idea is to fully parse the text without trying to identify
passes or structure. This is done with a single state machine. There
were various bugs in the logic around this previously that were repeated
and scattered across the code. Having a single routine makes it much
easier to fix and get correct. For example, this routine doesn't suffer
from PR28577.

Then the actual pass construction is handled using *much* easier to read
code and simple loops, with particular pass manager construction sunk to
live with other pass construction. This is especially nice as the pass
managers *are* in fact passes.

Finally, the "implicit" pass manager synthesis is done much more simply
by forming "pre-parsed" structures rather than having to duplicate tons
of logic.

One of the bugs fixed by this was evident in the tests where we accepted
a pipeline that wasn't really well formed. Another bug is PR28577 for
which I have added a test case.

The code is less efficient than the previous code but I'm really hoping
that's not a priority. ;]

Depends on D22723

Diff Detail

Repository
rL LLVM

Event Timeline

chandlerc updated this revision to Diff 65219.Jul 23 2016, 1:41 AM
chandlerc retitled this revision from to [PM] Significantly refactor the pass pipeline parsing to be easier to reason about and less error prone..
chandlerc updated this object.
chandlerc added a subscriber: llvm-commits.
silvas added a subscriber: silvas.Jul 24 2016, 3:26 PM
silvas added inline comments.
lib/Passes/PassBuilder.cpp
561 ↗(On Diff #65219)

Do you need error-checking here to verify that InnerPipeline is empty? Just from staring at the code it seems like gvn(foo,bar) will just be silently accepted with the (foo,bar) ignored.

I think down the road it actually would be useful to allow passes to take "arguments". E.g. inline(150) or instcombine(expensivecombines=true). That way we can run two inliners in the same pipeline but with different thresholds.
The instcombine case is actually interesting because currently there is no way to specify an instcombine pass that does not do the "expensive" combines. This means that this textual pipeline description cannot actually describe the O2 pipeline correctly (this is an issue with the old PM too, of course, so it isn't a high priority to fix).

chandlerc added inline comments.Aug 2 2016, 6:25 PM
lib/Passes/PassBuilder.cpp
561 ↗(On Diff #65219)

I think we should check that the inner pipeline is empty as you suggest.

I agree that we'll want passes to take arguments. We actually already have that with requires and such.

The design I've been going with is that ()s denote *pipelines*, and <>s denote *arguments*. So, imagining a pass that repeats a pipeline a certain number of times (which I have a review out for but will update based on the new parsing momentarily) we will have "repeat<N>(gvn,whatever)". Does that make sense?

chandlerc updated this revision to Diff 66603.Aug 2 2016, 6:26 PM

Add error checking for providing an inner pipeline to a normal pass by handling
the inner pipeline parsing separately. Seems less brittle going forward too.

silvas accepted this revision.Aug 2 2016, 7:14 PM
silvas added a reviewer: silvas.

LGTM.

lib/Passes/PassBuilder.cpp
574 ↗(On Diff #66603)

Thanks for the clarification. That makes sense to me. Can you make sure that ends up in a comment somewhere (if it isn't already)?

602 ↗(On Diff #66603)

LoopPassManager &FPM looks a bit funky. Might as well make it LPM if changing the line.

This revision is now accepted and ready to land.Aug 2 2016, 7:14 PM

Thanks for reviewing! Will land shortly.

lib/Passes/PassBuilder.cpp
574 ↗(On Diff #66603)

Yea, I'll land a follow-up commit that documents some of this design stuff. Let me know if it doesn't go far enough.

602 ↗(On Diff #66603)

This is precisely one of the things I want to fix and mentioned in IRC. Changing it in this patch adds a bunch of other lines of diff sadly. I'll do it in a follow-up.

This revision was automatically updated to reflect the committed changes.