2015-03-07 17:02:36 +08:00
|
|
|
//===- Parsing, selection, and construction of pass pipelines -------------===//
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// \file
|
|
|
|
///
|
2015-03-07 17:02:36 +08:00
|
|
|
/// This file provides the implementation of the PassBuilder based on our
|
|
|
|
/// static pass registry as well as related functionality. It also provides
|
|
|
|
/// helpers to aid in analyzing, debugging, and testing passes and pass
|
|
|
|
/// pipelines.
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
///
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
#include "llvm/Passes/PassBuilder.h"
|
2016-02-29 06:16:03 +08:00
|
|
|
#include "llvm/ADT/StringSwitch.h"
|
2016-02-14 07:32:00 +08:00
|
|
|
#include "llvm/Analysis/AliasAnalysis.h"
|
2016-02-20 11:46:03 +08:00
|
|
|
#include "llvm/Analysis/AliasAnalysisEvaluator.h"
|
2015-01-23 05:53:09 +08:00
|
|
|
#include "llvm/Analysis/AssumptionCache.h"
|
2016-02-14 07:46:24 +08:00
|
|
|
#include "llvm/Analysis/BasicAliasAnalysis.h"
|
2016-05-06 05:13:27 +08:00
|
|
|
#include "llvm/Analysis/BlockFrequencyInfo.h"
|
|
|
|
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
|
2016-05-05 10:59:57 +08:00
|
|
|
#include "llvm/Analysis/BranchProbabilityInfo.h"
|
2016-02-20 11:52:02 +08:00
|
|
|
#include "llvm/Analysis/CFLAliasAnalysis.h"
|
2014-04-21 19:12:00 +08:00
|
|
|
#include "llvm/Analysis/CGSCCPassManager.h"
|
2016-03-10 19:24:11 +08:00
|
|
|
#include "llvm/Analysis/CallGraph.h"
|
2016-04-19 07:55:01 +08:00
|
|
|
#include "llvm/Analysis/DemandedBits.h"
|
2016-05-13 06:19:39 +08:00
|
|
|
#include "llvm/Analysis/DependenceAnalysis.h"
|
2016-02-26 01:54:15 +08:00
|
|
|
#include "llvm/Analysis/DominanceFrontier.h"
|
2016-03-11 17:15:11 +08:00
|
|
|
#include "llvm/Analysis/GlobalsModRef.h"
|
2014-02-06 12:37:03 +08:00
|
|
|
#include "llvm/Analysis/LazyCallGraph.h"
|
2016-06-14 06:01:25 +08:00
|
|
|
#include "llvm/Analysis/LazyValueInfo.h"
|
2015-01-20 18:58:50 +08:00
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2016-03-10 08:55:30 +08:00
|
|
|
#include "llvm/Analysis/MemoryDependenceAnalysis.h"
|
2016-02-26 01:54:07 +08:00
|
|
|
#include "llvm/Analysis/PostDominators.h"
|
2016-06-04 06:54:26 +08:00
|
|
|
#include "llvm/Analysis/ProfileSummaryInfo.h"
|
2016-02-26 01:54:25 +08:00
|
|
|
#include "llvm/Analysis/RegionInfo.h"
|
[PM] Port ScalarEvolution to the new pass manager.
This change makes ScalarEvolution a stand-alone object and just produces
one from a pass as needed. Making this work well requires making the
object movable, using references instead of overwritten pointers in
a number of places, and other refactorings.
I've also wired it up to the new pass manager and added a RUN line to
a test to exercise it under the new pass manager. This includes basic
printing support much like with other analyses.
But there is a big and somewhat scary change here. Prior to this patch
ScalarEvolution was never *actually* invalidated!!! Re-running the pass
just re-wired up the various other analyses and didn't remove any of the
existing entries in the SCEV caches or clear out anything at all. This
might seem OK as everything in SCEV that can uses ValueHandles to track
updates to the values that serve as SCEV keys. However, this still means
that as we ran SCEV over each function in the module, we kept
accumulating more and more SCEVs into the cache. At the end, we would
have a SCEV cache with every value that we ever needed a SCEV for in the
entire module!!! Yowzers. The releaseMemory routine would dump all of
this, but that isn't realy called during normal runs of the pipeline as
far as I can see.
To make matters worse, there *is* actually a key that we don't update
with value handles -- there is a map keyed off of Loop*s. Because
LoopInfo *does* release its memory from run to run, it is entirely
possible to run SCEV over one function, then over another function, and
then lookup a Loop* from the second function but find an entry inserted
for the first function! Ouch.
To make matters still worse, there are plenty of updates that *don't*
trip a value handle. It seems incredibly unlikely that today GVN or
another pass that invalidates SCEV can update values in *just* such
a way that a subsequent run of SCEV will incorrectly find lookups in
a cache, but it is theoretically possible and would be a nightmare to
debug.
With this refactoring, I've fixed all this by actually destroying and
recreating the ScalarEvolution object from run to run. Technically, this
could increase the amount of malloc traffic we see, but then again it is
also technically correct. ;] I don't actually think we're suffering from
tons of malloc traffic from SCEV because if we were, the fact that we
never clear the memory would seem more likely to have come up as an
actual problem before now. So, I've made the simple fix here. If in fact
there are serious issues with too much allocation and deallocation,
I can work on a clever fix that preserves the allocations (while
clearing the data) between each run, but I'd prefer to do that kind of
optimization with a test case / benchmark that shows why we need such
cleverness (and that can test that we actually make it faster). It's
possible that this will make some things faster by making the SCEV
caches have higher locality (due to being significantly smaller) so
until there is a clear benchmark, I think the simple change is best.
Differential Revision: http://reviews.llvm.org/D12063
llvm-svn: 245193
2015-08-17 10:08:17 +08:00
|
|
|
#include "llvm/Analysis/ScalarEvolution.h"
|
2016-02-20 12:01:45 +08:00
|
|
|
#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
|
2016-02-20 12:03:06 +08:00
|
|
|
#include "llvm/Analysis/ScopedNoAliasAA.h"
|
2015-01-15 19:39:46 +08:00
|
|
|
#include "llvm/Analysis/TargetLibraryInfo.h"
|
2015-02-01 18:11:22 +08:00
|
|
|
#include "llvm/Analysis/TargetTransformInfo.h"
|
2016-02-20 12:04:52 +08:00
|
|
|
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
|
2015-01-14 18:19:28 +08:00
|
|
|
#include "llvm/IR/Dominators.h"
|
2014-01-12 20:15:39 +08:00
|
|
|
#include "llvm/IR/IRPrintingPasses.h"
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
#include "llvm/IR/PassManager.h"
|
2014-01-20 19:34:08 +08:00
|
|
|
#include "llvm/IR/Verifier.h"
|
2014-01-12 20:15:39 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
2016-02-29 06:16:03 +08:00
|
|
|
#include "llvm/Support/Regex.h"
|
2015-02-01 18:11:22 +08:00
|
|
|
#include "llvm/Target/TargetMachine.h"
|
2016-06-05 13:12:23 +08:00
|
|
|
#include "llvm/Transforms/GCOVProfiler.h"
|
2016-05-05 08:51:09 +08:00
|
|
|
#include "llvm/Transforms/IPO/ConstantMerge.h"
|
2016-06-12 17:16:39 +08:00
|
|
|
#include "llvm/Transforms/IPO/DeadArgumentElimination.h"
|
2016-05-05 10:37:32 +08:00
|
|
|
#include "llvm/Transforms/IPO/ElimAvailExtern.h"
|
2015-12-27 16:13:45 +08:00
|
|
|
#include "llvm/Transforms/IPO/ForceFunctionAttrs.h"
|
2016-02-18 19:03:11 +08:00
|
|
|
#include "llvm/Transforms/IPO/FunctionAttrs.h"
|
2016-05-04 03:39:15 +08:00
|
|
|
#include "llvm/Transforms/IPO/GlobalDCE.h"
|
2016-04-26 08:28:01 +08:00
|
|
|
#include "llvm/Transforms/IPO/GlobalOpt.h"
|
2015-12-27 16:41:34 +08:00
|
|
|
#include "llvm/Transforms/IPO/InferFunctionAttrs.h"
|
2016-04-27 04:15:52 +08:00
|
|
|
#include "llvm/Transforms/IPO/Internalize.h"
|
2016-05-06 05:05:36 +08:00
|
|
|
#include "llvm/Transforms/IPO/SCCP.h"
|
2015-10-31 07:28:12 +08:00
|
|
|
#include "llvm/Transforms/IPO/StripDeadPrototypes.h"
|
2016-06-15 05:44:19 +08:00
|
|
|
#include "llvm/Transforms/IPO/WholeProgramDevirt.h"
|
2015-12-27 16:13:45 +08:00
|
|
|
#include "llvm/Transforms/InstCombine/InstCombine.h"
|
2016-04-19 01:47:38 +08:00
|
|
|
#include "llvm/Transforms/InstrProfiling.h"
|
2016-05-06 13:49:19 +08:00
|
|
|
#include "llvm/Transforms/PGOInstrumentation.h"
|
2016-05-28 07:20:16 +08:00
|
|
|
#include "llvm/Transforms/SampleProfile.h"
|
2015-10-31 07:13:18 +08:00
|
|
|
#include "llvm/Transforms/Scalar/ADCE.h"
|
2016-06-15 14:18:01 +08:00
|
|
|
#include "llvm/Transforms/Scalar/AlignmentFromAssumptions.h"
|
2016-05-25 09:57:04 +08:00
|
|
|
#include "llvm/Transforms/Scalar/BDCE.h"
|
2016-04-23 03:40:41 +08:00
|
|
|
#include "llvm/Transforms/Scalar/DCE.h"
|
2016-05-18 05:38:13 +08:00
|
|
|
#include "llvm/Transforms/Scalar/DeadStoreElimination.h"
|
2015-02-01 18:51:23 +08:00
|
|
|
#include "llvm/Transforms/Scalar/EarlyCSE.h"
|
2016-06-04 06:54:26 +08:00
|
|
|
#include "llvm/Transforms/Scalar/GVN.h"
|
2016-06-14 08:49:23 +08:00
|
|
|
#include "llvm/Transforms/Scalar/GuardWidening.h"
|
2016-06-06 02:01:19 +08:00
|
|
|
#include "llvm/Transforms/Scalar/IndVarSimplify.h"
|
2016-06-14 08:51:09 +08:00
|
|
|
#include "llvm/Transforms/Scalar/JumpThreading.h"
|
2016-05-04 06:02:31 +08:00
|
|
|
#include "llvm/Transforms/Scalar/LoopRotation.h"
|
2016-05-04 05:47:32 +08:00
|
|
|
#include "llvm/Transforms/Scalar/LoopSimplifyCFG.h"
|
2016-05-14 06:52:35 +08:00
|
|
|
#include "llvm/Transforms/Scalar/LowerAtomic.h"
|
2015-01-24 19:13:02 +08:00
|
|
|
#include "llvm/Transforms/Scalar/LowerExpectIntrinsic.h"
|
2016-06-14 10:44:55 +08:00
|
|
|
#include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
|
2016-06-18 03:10:09 +08:00
|
|
|
#include "llvm/Transforms/Scalar/MergedLoadStoreMotion.h"
|
2016-05-26 07:38:53 +08:00
|
|
|
#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"
|
2016-04-27 07:39:29 +08:00
|
|
|
#include "llvm/Transforms/Scalar/Reassociate.h"
|
2016-05-18 23:18:25 +08:00
|
|
|
#include "llvm/Transforms/Scalar/SCCP.h"
|
2016-06-17 15:15:29 +08:00
|
|
|
#include "llvm/Transforms/Scalar/SLPVectorizer.h"
|
2015-09-12 17:09:14 +08:00
|
|
|
#include "llvm/Transforms/Scalar/SROA.h"
|
2015-12-27 16:13:45 +08:00
|
|
|
#include "llvm/Transforms/Scalar/SimplifyCFG.h"
|
2016-04-23 03:54:10 +08:00
|
|
|
#include "llvm/Transforms/Scalar/Sink.h"
|
2016-06-16 05:51:30 +08:00
|
|
|
#include "llvm/Transforms/Utils/AddDiscriminators.h"
|
2016-06-10 03:44:46 +08:00
|
|
|
#include "llvm/Transforms/Utils/LCSSA.h"
|
2016-06-14 11:22:22 +08:00
|
|
|
#include "llvm/Transforms/Utils/Mem2Reg.h"
|
2016-06-02 05:30:40 +08:00
|
|
|
#include "llvm/Transforms/Utils/MemorySSA.h"
|
2016-06-14 11:22:22 +08:00
|
|
|
|
2016-02-26 20:17:54 +08:00
|
|
|
#include <type_traits>
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2016-02-29 06:16:03 +08:00
|
|
|
static Regex DefaultAliasRegex("^(default|lto-pre-link|lto)<(O[0123sz])>$");
|
|
|
|
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
namespace {
|
|
|
|
|
2014-01-12 17:34:22 +08:00
|
|
|
/// \brief No-op module pass which does nothing.
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
struct NoOpModulePass {
|
2016-06-17 08:11:01 +08:00
|
|
|
PreservedAnalyses run(Module &M, AnalysisManager<Module> &) {
|
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
2014-01-11 19:52:05 +08:00
|
|
|
static StringRef name() { return "NoOpModulePass"; }
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
};
|
|
|
|
|
2015-01-06 10:50:06 +08:00
|
|
|
/// \brief No-op module analysis.
|
2016-03-11 18:33:22 +08:00
|
|
|
class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
|
|
|
|
friend AnalysisInfoMixin<NoOpModuleAnalysis>;
|
2016-03-11 18:22:49 +08:00
|
|
|
static char PassID;
|
|
|
|
|
|
|
|
public:
|
2015-01-06 10:50:06 +08:00
|
|
|
struct Result {};
|
2016-06-17 08:11:01 +08:00
|
|
|
Result run(Module &, AnalysisManager<Module> &) { return Result(); }
|
2015-01-06 10:50:06 +08:00
|
|
|
static StringRef name() { return "NoOpModuleAnalysis"; }
|
|
|
|
};
|
|
|
|
|
2014-04-21 19:12:00 +08:00
|
|
|
/// \brief No-op CGSCC pass which does nothing.
|
|
|
|
struct NoOpCGSCCPass {
|
2016-06-17 08:11:01 +08:00
|
|
|
PreservedAnalyses run(LazyCallGraph::SCC &C,
|
|
|
|
AnalysisManager<LazyCallGraph::SCC> &) {
|
2014-04-21 19:12:00 +08:00
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
|
|
|
static StringRef name() { return "NoOpCGSCCPass"; }
|
|
|
|
};
|
|
|
|
|
2015-01-06 10:50:06 +08:00
|
|
|
/// \brief No-op CGSCC analysis.
|
2016-03-11 18:33:22 +08:00
|
|
|
class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
|
|
|
|
friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
|
2016-03-11 18:22:49 +08:00
|
|
|
static char PassID;
|
|
|
|
|
|
|
|
public:
|
2015-01-06 10:50:06 +08:00
|
|
|
struct Result {};
|
2016-06-17 08:11:01 +08:00
|
|
|
Result run(LazyCallGraph::SCC &, AnalysisManager<LazyCallGraph::SCC> &) {
|
|
|
|
return Result();
|
|
|
|
}
|
2015-01-06 10:50:06 +08:00
|
|
|
static StringRef name() { return "NoOpCGSCCAnalysis"; }
|
|
|
|
};
|
|
|
|
|
2014-01-12 17:34:22 +08:00
|
|
|
/// \brief No-op function pass which does nothing.
|
|
|
|
struct NoOpFunctionPass {
|
2016-06-17 08:11:01 +08:00
|
|
|
PreservedAnalyses run(Function &F, AnalysisManager<Function> &) {
|
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
2014-01-12 17:34:22 +08:00
|
|
|
static StringRef name() { return "NoOpFunctionPass"; }
|
|
|
|
};
|
|
|
|
|
2015-01-06 10:50:06 +08:00
|
|
|
/// \brief No-op function analysis.
|
2016-03-11 18:33:22 +08:00
|
|
|
class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
|
|
|
|
friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
|
2016-03-11 18:22:49 +08:00
|
|
|
static char PassID;
|
|
|
|
|
|
|
|
public:
|
2015-01-06 10:50:06 +08:00
|
|
|
struct Result {};
|
2016-06-17 08:11:01 +08:00
|
|
|
Result run(Function &, AnalysisManager<Function> &) { return Result(); }
|
2015-01-06 10:50:06 +08:00
|
|
|
static StringRef name() { return "NoOpFunctionAnalysis"; }
|
|
|
|
};
|
|
|
|
|
2016-02-25 15:23:08 +08:00
|
|
|
/// \brief No-op loop pass which does nothing.
|
|
|
|
struct NoOpLoopPass {
|
2016-06-17 08:11:01 +08:00
|
|
|
PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &) {
|
|
|
|
return PreservedAnalyses::all();
|
|
|
|
}
|
2016-02-25 15:23:08 +08:00
|
|
|
static StringRef name() { return "NoOpLoopPass"; }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief No-op loop analysis.
|
2016-03-11 18:33:22 +08:00
|
|
|
class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
|
|
|
|
friend AnalysisInfoMixin<NoOpLoopAnalysis>;
|
2016-03-11 18:22:49 +08:00
|
|
|
static char PassID;
|
|
|
|
|
|
|
|
public:
|
2016-02-25 15:23:08 +08:00
|
|
|
struct Result {};
|
2016-06-17 08:11:01 +08:00
|
|
|
Result run(Loop &, AnalysisManager<Loop> &) { return Result(); }
|
2016-02-25 15:23:08 +08:00
|
|
|
static StringRef name() { return "NoOpLoopAnalysis"; }
|
|
|
|
};
|
|
|
|
|
2016-03-11 18:22:49 +08:00
|
|
|
char NoOpModuleAnalysis::PassID;
|
|
|
|
char NoOpCGSCCAnalysis::PassID;
|
|
|
|
char NoOpFunctionAnalysis::PassID;
|
|
|
|
char NoOpLoopAnalysis::PassID;
|
|
|
|
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
} // End anonymous namespace.
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
void PassBuilder::registerModuleAnalyses(ModuleAnalysisManager &MAM) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
2016-02-18 17:45:17 +08:00
|
|
|
MAM.registerPass([&] { return CREATE_PASS; });
|
2015-01-06 10:21:37 +08:00
|
|
|
#include "PassRegistry.def"
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
void PassBuilder::registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
2016-02-18 17:45:17 +08:00
|
|
|
CGAM.registerPass([&] { return CREATE_PASS; });
|
2015-01-06 10:21:37 +08:00
|
|
|
#include "PassRegistry.def"
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
void PassBuilder::registerFunctionAnalyses(FunctionAnalysisManager &FAM) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
2016-02-18 17:45:17 +08:00
|
|
|
FAM.registerPass([&] { return CREATE_PASS; });
|
2015-01-06 10:21:37 +08:00
|
|
|
#include "PassRegistry.def"
|
|
|
|
}
|
|
|
|
|
2016-02-25 15:23:08 +08:00
|
|
|
void PassBuilder::registerLoopAnalyses(LoopAnalysisManager &LAM) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
2016-02-25 15:23:08 +08:00
|
|
|
LAM.registerPass([&] { return CREATE_PASS; });
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
}
|
|
|
|
|
2016-02-29 06:16:03 +08:00
|
|
|
void PassBuilder::addPerModuleDefaultPipeline(ModulePassManager &MPM,
|
|
|
|
OptimizationLevel Level,
|
|
|
|
bool DebugLogging) {
|
|
|
|
// FIXME: Finish fleshing this out to match the legacy pipelines.
|
|
|
|
FunctionPassManager EarlyFPM(DebugLogging);
|
|
|
|
EarlyFPM.addPass(SimplifyCFGPass());
|
|
|
|
EarlyFPM.addPass(SROA());
|
|
|
|
EarlyFPM.addPass(EarlyCSEPass());
|
|
|
|
EarlyFPM.addPass(LowerExpectIntrinsicPass());
|
|
|
|
|
|
|
|
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(EarlyFPM)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void PassBuilder::addLTOPreLinkDefaultPipeline(ModulePassManager &MPM,
|
|
|
|
OptimizationLevel Level,
|
|
|
|
bool DebugLogging) {
|
|
|
|
// FIXME: We should use a customized pre-link pipeline!
|
|
|
|
addPerModuleDefaultPipeline(MPM, Level, DebugLogging);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PassBuilder::addLTODefaultPipeline(ModulePassManager &MPM,
|
|
|
|
OptimizationLevel Level,
|
|
|
|
bool DebugLogging) {
|
|
|
|
// FIXME: Finish fleshing this out to match the legacy LTO pipelines.
|
|
|
|
FunctionPassManager LateFPM(DebugLogging);
|
|
|
|
LateFPM.addPass(InstCombinePass());
|
|
|
|
LateFPM.addPass(SimplifyCFGPass());
|
|
|
|
|
|
|
|
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(LateFPM)));
|
|
|
|
}
|
|
|
|
|
2015-01-06 17:10:47 +08:00
|
|
|
#ifndef NDEBUG
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
static bool isModulePassName(StringRef Name) {
|
2016-02-29 06:16:03 +08:00
|
|
|
// Manually handle aliases for pre-configured pipeline fragments.
|
|
|
|
if (Name.startswith("default") || Name.startswith("lto"))
|
|
|
|
return DefaultAliasRegex.match(Name);
|
|
|
|
|
2016-06-17 15:15:29 +08:00
|
|
|
#define MODULE_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) \
|
|
|
|
return true;
|
2015-01-06 10:10:51 +08:00
|
|
|
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
2015-01-06 12:49:44 +08:00
|
|
|
if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true;
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
return false;
|
|
|
|
}
|
2015-01-06 17:10:47 +08:00
|
|
|
#endif
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
|
2014-04-21 19:12:00 +08:00
|
|
|
static bool isCGSCCPassName(StringRef Name) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define CGSCC_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) \
|
|
|
|
return true;
|
2015-01-06 10:10:51 +08:00
|
|
|
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
2015-01-06 12:49:44 +08:00
|
|
|
if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true;
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
2014-04-21 19:12:00 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-01-12 17:34:22 +08:00
|
|
|
static bool isFunctionPassName(StringRef Name) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define FUNCTION_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) \
|
|
|
|
return true;
|
2015-01-06 10:10:51 +08:00
|
|
|
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
2015-01-06 12:49:44 +08:00
|
|
|
if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true;
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
2014-01-12 17:34:22 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-25 15:23:08 +08:00
|
|
|
static bool isLoopPassName(StringRef Name) {
|
2016-06-17 15:15:29 +08:00
|
|
|
#define LOOP_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) \
|
|
|
|
return true;
|
2016-02-25 15:23:08 +08:00
|
|
|
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
|
|
|
|
return true;
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-29 06:16:03 +08:00
|
|
|
bool PassBuilder::parseModulePassName(ModulePassManager &MPM, StringRef Name,
|
|
|
|
bool DebugLogging) {
|
|
|
|
// Manually handle aliases for pre-configured pipeline fragments.
|
|
|
|
if (Name.startswith("default") || Name.startswith("lto")) {
|
|
|
|
SmallVector<StringRef, 3> Matches;
|
|
|
|
if (!DefaultAliasRegex.match(Name, &Matches))
|
|
|
|
return false;
|
|
|
|
assert(Matches.size() == 3 && "Must capture two matched strings!");
|
|
|
|
|
|
|
|
auto L = StringSwitch<OptimizationLevel>(Matches[2])
|
|
|
|
.Case("O0", O0)
|
|
|
|
.Case("O1", O1)
|
|
|
|
.Case("O2", O2)
|
|
|
|
.Case("O3", O3)
|
|
|
|
.Case("Os", Os)
|
|
|
|
.Case("Oz", Oz);
|
|
|
|
|
|
|
|
if (Matches[1] == "default") {
|
|
|
|
addPerModuleDefaultPipeline(MPM, L, DebugLogging);
|
|
|
|
} else if (Matches[1] == "lto-pre-link") {
|
|
|
|
addLTOPreLinkDefaultPipeline(MPM, L, DebugLogging);
|
|
|
|
} else {
|
|
|
|
assert(Matches[1] == "lto" && "Not one of the matched options!");
|
|
|
|
addLTODefaultPipeline(MPM, L, DebugLogging);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-21 16:08:50 +08:00
|
|
|
#define MODULE_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
|
|
|
MPM.addPass(CREATE_PASS); \
|
|
|
|
return true; \
|
2014-02-06 12:37:03 +08:00
|
|
|
}
|
2015-01-06 10:10:51 +08:00
|
|
|
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == "require<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
MPM.addPass(RequireAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true; \
|
2015-01-06 12:49:44 +08:00
|
|
|
} \
|
|
|
|
if (Name == "invalidate<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
MPM.addPass(InvalidateAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 12:49:44 +08:00
|
|
|
return true; \
|
2015-01-06 10:10:51 +08:00
|
|
|
}
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
|
2014-04-21 19:12:00 +08:00
|
|
|
#define CGSCC_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
|
|
|
CGPM.addPass(CREATE_PASS); \
|
|
|
|
return true; \
|
|
|
|
}
|
2015-01-06 10:10:51 +08:00
|
|
|
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == "require<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
CGPM.addPass(RequireAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true; \
|
2015-01-06 12:49:44 +08:00
|
|
|
} \
|
|
|
|
if (Name == "invalidate<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
CGPM.addPass(InvalidateAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 12:49:44 +08:00
|
|
|
return true; \
|
2015-01-06 10:10:51 +08:00
|
|
|
}
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
2014-04-21 19:12:00 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parseFunctionPassName(FunctionPassManager &FPM,
|
|
|
|
StringRef Name) {
|
2014-04-21 16:08:50 +08:00
|
|
|
#define FUNCTION_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
|
|
|
FPM.addPass(CREATE_PASS); \
|
|
|
|
return true; \
|
2014-01-12 20:15:39 +08:00
|
|
|
}
|
2015-01-06 10:10:51 +08:00
|
|
|
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == "require<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
FPM.addPass(RequireAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 10:10:51 +08:00
|
|
|
return true; \
|
2015-01-06 12:49:44 +08:00
|
|
|
} \
|
|
|
|
if (Name == "invalidate<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
FPM.addPass(InvalidateAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2015-01-06 12:49:44 +08:00
|
|
|
return true; \
|
2015-01-06 10:10:51 +08:00
|
|
|
}
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
2014-01-12 17:34:22 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-06-17 15:15:29 +08:00
|
|
|
bool PassBuilder::parseLoopPassName(LoopPassManager &FPM, StringRef Name) {
|
2016-02-25 15:23:08 +08:00
|
|
|
#define LOOP_PASS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
|
|
|
FPM.addPass(CREATE_PASS); \
|
|
|
|
return true; \
|
|
|
|
}
|
|
|
|
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == "require<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
FPM.addPass(RequireAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2016-02-25 15:23:08 +08:00
|
|
|
return true; \
|
|
|
|
} \
|
|
|
|
if (Name == "invalidate<" NAME ">") { \
|
2016-02-26 20:30:18 +08:00
|
|
|
FPM.addPass(InvalidateAnalysisPass< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>()); \
|
2016-02-25 15:23:08 +08:00
|
|
|
return true; \
|
|
|
|
}
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-18 17:45:17 +08:00
|
|
|
bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
|
2016-03-11 17:15:11 +08:00
|
|
|
#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
|
|
|
AA.registerModuleAnalysis< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>(); \
|
|
|
|
return true; \
|
|
|
|
}
|
2016-02-18 17:45:17 +08:00
|
|
|
#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
|
|
|
|
if (Name == NAME) { \
|
2016-02-26 20:17:54 +08:00
|
|
|
AA.registerFunctionAnalysis< \
|
|
|
|
std::remove_reference<decltype(CREATE_PASS)>::type>(); \
|
2016-02-18 17:45:17 +08:00
|
|
|
return true; \
|
|
|
|
}
|
|
|
|
#include "PassRegistry.def"
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-02-25 15:23:08 +08:00
|
|
|
bool PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
|
|
|
|
StringRef &PipelineText,
|
|
|
|
bool VerifyEachPass,
|
|
|
|
bool DebugLogging) {
|
|
|
|
for (;;) {
|
|
|
|
// Parse nested pass managers by recursing.
|
|
|
|
if (PipelineText.startswith("loop(")) {
|
|
|
|
LoopPassManager NestedLPM(DebugLogging);
|
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("loop("));
|
|
|
|
if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
|
|
|
PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
assert(PipelineText[0] == ')');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
|
|
|
LPM.addPass(std::move(NestedLPM));
|
|
|
|
} else {
|
|
|
|
// Otherwise try to parse a pass name.
|
|
|
|
size_t End = PipelineText.find_first_of(",)");
|
|
|
|
if (!parseLoopPassName(LPM, PipelineText.substr(0, End)))
|
|
|
|
return false;
|
|
|
|
// TODO: Ideally, we would run a LoopVerifierPass() here in the
|
|
|
|
// VerifyEachPass case, but we don't have such a verifier yet.
|
|
|
|
|
|
|
|
PipelineText = PipelineText.substr(End);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PipelineText.empty() || PipelineText[0] == ')')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(PipelineText[0] == ',');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parseFunctionPassPipeline(FunctionPassManager &FPM,
|
|
|
|
StringRef &PipelineText,
|
|
|
|
bool VerifyEachPass,
|
|
|
|
bool DebugLogging) {
|
2014-01-12 17:34:22 +08:00
|
|
|
for (;;) {
|
|
|
|
// Parse nested pass managers by recursing.
|
|
|
|
if (PipelineText.startswith("function(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
FunctionPassManager NestedFPM(DebugLogging);
|
2014-01-12 17:34:22 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("function("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-01-12 18:02:02 +08:00
|
|
|
PipelineText.empty())
|
2014-01-12 17:34:22 +08:00
|
|
|
return false;
|
2014-01-12 18:02:02 +08:00
|
|
|
assert(PipelineText[0] == ')');
|
2014-01-12 17:34:22 +08:00
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
2014-03-09 19:49:53 +08:00
|
|
|
FPM.addPass(std::move(NestedFPM));
|
2016-02-25 15:23:08 +08:00
|
|
|
} else if (PipelineText.startswith("loop(")) {
|
|
|
|
LoopPassManager NestedLPM(DebugLogging);
|
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("loop("));
|
|
|
|
if (!parseLoopPassPipeline(NestedLPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
|
|
|
PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
assert(PipelineText[0] == ')');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
|
|
|
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(NestedLPM)));
|
2014-01-12 17:34:22 +08:00
|
|
|
} else {
|
|
|
|
// Otherwise try to parse a pass name.
|
|
|
|
size_t End = PipelineText.find_first_of(",)");
|
|
|
|
if (!parseFunctionPassName(FPM, PipelineText.substr(0, End)))
|
|
|
|
return false;
|
2014-01-20 19:34:08 +08:00
|
|
|
if (VerifyEachPass)
|
|
|
|
FPM.addPass(VerifierPass());
|
2014-01-12 17:34:22 +08:00
|
|
|
|
|
|
|
PipelineText = PipelineText.substr(End);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PipelineText.empty() || PipelineText[0] == ')')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(PipelineText[0] == ',');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
|
|
|
|
StringRef &PipelineText,
|
|
|
|
bool VerifyEachPass,
|
|
|
|
bool DebugLogging) {
|
2014-04-21 19:12:00 +08:00
|
|
|
for (;;) {
|
|
|
|
// Parse nested pass managers by recursing.
|
|
|
|
if (PipelineText.startswith("cgscc(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
CGSCCPassManager NestedCGPM(DebugLogging);
|
2014-04-21 19:12:00 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline into the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("cgscc("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-04-21 19:12:00 +08:00
|
|
|
PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
assert(PipelineText[0] == ')');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
|
|
|
CGPM.addPass(std::move(NestedCGPM));
|
|
|
|
} else if (PipelineText.startswith("function(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
FunctionPassManager NestedFPM(DebugLogging);
|
2014-04-21 19:12:00 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("function("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-04-21 19:12:00 +08:00
|
|
|
PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
assert(PipelineText[0] == ')');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
|
|
|
CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
|
|
|
|
} else {
|
|
|
|
// Otherwise try to parse a pass name.
|
|
|
|
size_t End = PipelineText.find_first_of(",)");
|
|
|
|
if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
|
|
|
|
return false;
|
|
|
|
// FIXME: No verifier support for CGSCC passes!
|
|
|
|
|
|
|
|
PipelineText = PipelineText.substr(End);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PipelineText.empty() || PipelineText[0] == ')')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(PipelineText[0] == ',');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-16 18:13:37 +08:00
|
|
|
void PassBuilder::crossRegisterProxies(LoopAnalysisManager &LAM,
|
|
|
|
FunctionAnalysisManager &FAM,
|
|
|
|
CGSCCAnalysisManager &CGAM,
|
|
|
|
ModuleAnalysisManager &MAM) {
|
|
|
|
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
|
|
|
|
MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
|
|
|
|
CGAM.registerPass([&] { return FunctionAnalysisManagerCGSCCProxy(FAM); });
|
|
|
|
CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
|
|
|
|
FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
|
|
|
|
FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
|
|
|
|
FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
|
|
|
|
LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
|
|
|
|
}
|
|
|
|
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
|
|
|
|
StringRef &PipelineText,
|
|
|
|
bool VerifyEachPass,
|
|
|
|
bool DebugLogging) {
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
for (;;) {
|
|
|
|
// Parse nested pass managers by recursing.
|
|
|
|
if (PipelineText.startswith("module(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
ModulePassManager NestedMPM(DebugLogging);
|
2014-01-11 20:06:47 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline into the nested manager.
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
PipelineText = PipelineText.substr(strlen("module("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseModulePassPipeline(NestedMPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-01-12 18:02:02 +08:00
|
|
|
PipelineText.empty())
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
return false;
|
2014-01-12 18:02:02 +08:00
|
|
|
assert(PipelineText[0] == ')');
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
PipelineText = PipelineText.substr(1);
|
2014-01-11 20:06:47 +08:00
|
|
|
|
|
|
|
// Now add the nested manager as a module pass.
|
2014-03-09 19:49:53 +08:00
|
|
|
MPM.addPass(std::move(NestedMPM));
|
2014-04-21 19:12:00 +08:00
|
|
|
} else if (PipelineText.startswith("cgscc(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
CGSCCPassManager NestedCGPM(DebugLogging);
|
2014-04-21 19:12:00 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("cgscc("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-04-21 19:12:00 +08:00
|
|
|
PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
assert(PipelineText[0] == ')');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
|
|
|
MPM.addPass(
|
|
|
|
createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
|
2014-01-12 17:34:22 +08:00
|
|
|
} else if (PipelineText.startswith("function(")) {
|
2015-01-14 06:42:38 +08:00
|
|
|
FunctionPassManager NestedFPM(DebugLogging);
|
2014-01-12 17:34:22 +08:00
|
|
|
|
|
|
|
// Parse the inner pipeline inte the nested manager.
|
|
|
|
PipelineText = PipelineText.substr(strlen("function("));
|
2015-01-14 06:42:38 +08:00
|
|
|
if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-01-12 18:02:02 +08:00
|
|
|
PipelineText.empty())
|
2014-01-12 17:34:22 +08:00
|
|
|
return false;
|
2014-01-12 18:02:02 +08:00
|
|
|
assert(PipelineText[0] == ')');
|
2014-01-12 17:34:22 +08:00
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
|
|
|
|
// Add the nested pass manager with the appropriate adaptor.
|
2014-03-09 19:49:53 +08:00
|
|
|
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(NestedFPM)));
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
} else {
|
|
|
|
// Otherwise try to parse a pass name.
|
|
|
|
size_t End = PipelineText.find_first_of(",)");
|
2016-02-29 06:16:03 +08:00
|
|
|
if (!parseModulePassName(MPM, PipelineText.substr(0, End), DebugLogging))
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
return false;
|
2014-01-20 19:34:08 +08:00
|
|
|
if (VerifyEachPass)
|
|
|
|
MPM.addPass(VerifierPass());
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
|
|
|
|
PipelineText = PipelineText.substr(End);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PipelineText.empty() || PipelineText[0] == ')')
|
|
|
|
return true;
|
|
|
|
|
|
|
|
assert(PipelineText[0] == ',');
|
|
|
|
PipelineText = PipelineText.substr(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Primary pass pipeline description parsing routine.
|
|
|
|
// FIXME: Should this routine accept a TargetMachine or require the caller to
|
|
|
|
// pre-populate the analysis managers with target-specific stuff?
|
2015-03-07 17:02:36 +08:00
|
|
|
bool PassBuilder::parsePassPipeline(ModulePassManager &MPM,
|
|
|
|
StringRef PipelineText, bool VerifyEachPass,
|
|
|
|
bool DebugLogging) {
|
2015-01-06 16:37:58 +08:00
|
|
|
// By default, try to parse the pipeline as-if it were within an implicit
|
|
|
|
// 'module(...)' pass pipeline. If this will parse at all, it needs to
|
|
|
|
// consume the entire string.
|
2015-01-14 06:42:38 +08:00
|
|
|
if (parseModulePassPipeline(MPM, PipelineText, VerifyEachPass, DebugLogging))
|
2015-01-06 16:37:58 +08:00
|
|
|
return PipelineText.empty();
|
|
|
|
|
|
|
|
// This isn't parsable as a module pipeline, look for the end of a pass name
|
|
|
|
// and directly drop down to that layer.
|
2014-01-12 18:02:02 +08:00
|
|
|
StringRef FirstName =
|
|
|
|
PipelineText.substr(0, PipelineText.find_first_of(",)"));
|
2015-01-06 16:37:58 +08:00
|
|
|
assert(!isModulePassName(FirstName) &&
|
|
|
|
"Already handled all module pipeline options.");
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
|
2015-01-06 16:37:58 +08:00
|
|
|
// If this looks like a CGSCC pass, parse the whole thing as a CGSCC
|
|
|
|
// pipeline.
|
2016-02-25 15:23:08 +08:00
|
|
|
if (PipelineText.startswith("cgscc(") || isCGSCCPassName(FirstName)) {
|
2015-01-14 06:42:38 +08:00
|
|
|
CGSCCPassManager CGPM(DebugLogging);
|
|
|
|
if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-04-21 19:12:00 +08:00
|
|
|
!PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-06 16:37:58 +08:00
|
|
|
// Similarly, if this looks like a Function pass, parse the whole thing as
|
|
|
|
// a Function pipelien.
|
2016-02-25 15:23:08 +08:00
|
|
|
if (PipelineText.startswith("function(") || isFunctionPassName(FirstName)) {
|
2015-01-14 06:42:38 +08:00
|
|
|
FunctionPassManager FPM(DebugLogging);
|
|
|
|
if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
2014-01-20 19:34:08 +08:00
|
|
|
!PipelineText.empty())
|
2014-01-12 17:34:22 +08:00
|
|
|
return false;
|
2014-03-09 19:49:53 +08:00
|
|
|
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
2014-01-12 17:34:22 +08:00
|
|
|
return true;
|
|
|
|
}
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
|
2016-02-25 15:23:08 +08:00
|
|
|
// If this looks like a Loop pass, parse the whole thing as a Loop pipeline.
|
|
|
|
if (PipelineText.startswith("loop(") || isLoopPassName(FirstName)) {
|
|
|
|
LoopPassManager LPM(DebugLogging);
|
|
|
|
if (!parseLoopPassPipeline(LPM, PipelineText, VerifyEachPass,
|
|
|
|
DebugLogging) ||
|
|
|
|
!PipelineText.empty())
|
|
|
|
return false;
|
|
|
|
FunctionPassManager FPM(DebugLogging);
|
|
|
|
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
|
|
|
|
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
[PM] Add (very skeletal) support to opt for running the new pass
manager. I cannot emphasize enough that this is a WIP. =] I expect it
to change a great deal as things stabilize, but I think its really
important to get *some* functionality here so that the infrastructure
can be tested more traditionally from the commandline.
The current design is looking something like this:
./bin/opt -passes='module(pass_a,pass_b,function(pass_c,pass_d))'
So rather than custom-parsed flags, there is a single flag with a string
argument that is parsed into the pass pipeline structure. This makes it
really easy to have nice structural properties that are very explicit.
There is one obvious and important shortcut. You can start off the
pipeline with a pass, and the minimal context of pass managers will be
built around the entire specified pipeline. This makes the common case
for tests super easy:
./bin/opt -passes=instcombine,sroa,gvn
But this won't introduce any of the complexity of the fully inferred old
system -- we only ever do this for the *entire* argument, and we only
look at the first pass. If the other passes don't fit in the pass
manager selected it is a hard error.
The other interesting aspect here is that I'm not relying on any
registration facilities. Such facilities may be unavoidable for
supporting plugins, but I have alternative ideas for plugins that I'd
like to try first. My plan is essentially to build everything without
registration until we hit an absolute requirement.
Instead of registration of pass names, there will be a library dedicated
to parsing pass names and the pass pipeline strings described above.
Currently, this is directly embedded into opt for simplicity as it is
very early, but I plan to eventually pull this into a library that opt,
bugpoint, and even Clang can depend on. It should end up as a good home
for things like the existing PassManagerBuilder as well.
There are a bunch of FIXMEs in the code for the parts of this that are
just stubbed out to make the patch more incremental. A quick list of
what's coming up directly after this:
- Support for function passes and building the structured nesting.
- Support for printing the pass structure, and FileCheck tests of all of
this code.
- The .def-file based pass name parsing.
- IR priting passes and the corresponding tests.
Some obvious things that I'm not going to do right now, but am
definitely planning on as the pass manager work gets a bit further:
- Pull the parsing into library, including the builders.
- Thread the rest of the target stuff into the new pass manager.
- Wire support for the new pass manager up to llc.
- Plugin support.
Some things that I'd like to have, but are significantly lower on my
priority list. I'll get to these eventually, but they may also be places
where others want to contribute:
- Adding nice error reporting for broken pass pipeline descriptions.
- Typo-correction for pass names.
llvm-svn: 198998
2014-01-11 16:16:35 +08:00
|
|
|
return false;
|
|
|
|
}
|
2016-02-18 17:45:17 +08:00
|
|
|
|
|
|
|
bool PassBuilder::parseAAPipeline(AAManager &AA, StringRef PipelineText) {
|
|
|
|
while (!PipelineText.empty()) {
|
|
|
|
StringRef Name;
|
|
|
|
std::tie(Name, PipelineText) = PipelineText.split(',');
|
|
|
|
if (!parseAAPassName(AA, Name))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|