summaryrefslogtreecommitdiffstats
path: root/llvm/unittests/IR/PassManagerTest.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [PM] Add names and debug logging for analysis passes to the new passChandler Carruth2015-01-051-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | manager. This starts to allow us to test analyses more easily, but it's really only the beginning. Some of the code here is still untestable without manual changes to create analysis passes, but I wanted to factor it into a small of chunks as possible. Next up in order to be able to test things are, in no particular order: - No-op analyses passes so we don't have to use real ones to exercise the pass maneger itself. - Automatic way of generating dummy passes that require an analysis be run, including a variant that calls a 'print' method on a pass to make it even easier to print out the results of an analysis. - Dummy passes that invalidate all analyses for their IR unit so we can test invalidation and re-runs. - Automatic way to print each analysis pass as it is re-run. - Automatic but optional verification of analysis passes everywhere possible. I'm not claiming I'll get to all of these immediately, but that's what is in the pipeline at some stage. I'm fleshing out exactly what I need and what to prioritize by working on converting analyses and then trying to test the conversion. =] llvm-svn: 225162
* [PM] Switch the new pass manager to use a reference-based API for IRChandler Carruth2015-01-051-15/+15
| | | | | | | | | | | | | | | | | | | | | units. This was debated back and forth a bunch, but using references is now clearly cleaner. Of all the code written using pointers thus far, in only one place did it really make more sense to have a pointer. In most cases, this just removes immediate dereferencing from the code. I think it is much better to get errors on null IR units earlier, potentially at compile time, than to delay it. Most notably, the legacy pass manager uses references for its routines and so as more and more code works with both, the use of pointers was likely to become really annoying. I noticed this when I ported the domtree analysis over and wrote the entire thing with references only to have it fail to compile. =/ It seemed better to switch now than to delay. We can, of course, revisit this is we learn that references are really problematic in the API. llvm-svn: 225145
* Modernize the .ll parsing interface.Rafael Espindola2014-08-191-1/+1
| | | | | | | | | | * Use StringRef instead of std::string& * Return a std::unique_ptr<Module> instead of taking an optional module to write to (was not really used). * Use current comment style. * Use current naming convention. llvm-svn: 215989
* [C++11] Use 'nullptr'.Craig Topper2014-06-081-1/+1
| | | | llvm-svn: 210442
* [PM] As was pointed out in review, I need to define a custom swap inChandler Carruth2014-03-131-3/+44
| | | | | | | | | | | | | order to use the single assignment. That's probably worth doing for a lot of these types anyways as they may have non-trivial moves and so getting copy elision in more places seems worthwhile. I've tried to add some tests that actually catch this mistake, and one of the types is now well tested but the others' tests still fail to catch this. I'll keep working on tests, but this gets the core pattern right. llvm-svn: 203780
* [PM] While I'm here, fix a few other clang-format issues. Pulls someChandler Carruth2014-03-101-4/+2
| | | | | | lines under 80-columns, etc. llvm-svn: 203434
* [PM] Switch new pass manager from polymorphic_ptr to unique_ptr now thatChandler Carruth2014-03-091-23/+33
| | | | | | | it is available. Also make the move semantics sufficiently correct to tolerate move-only passes, as the PassManagers *are* move-only passes. llvm-svn: 203391
* Replace OwningPtr<T> with std::unique_ptr<T>.Ahmed Charles2014-03-061-1/+1
| | | | | | | | | | This compiles with no changes to clang/lld/lldb with MSVC and includes overloads to various functions which are used by those projects and llvm which have OwningPtr's as parameters. This should allow out of tree projects some time to move. There are also no changes to libs/Target, which should help out of tree targets have time to move, if necessary. llvm-svn: 203083
* [PM] Don't require analysis results to be const in the new pass manager.Chandler Carruth2014-02-051-3/+3
| | | | | | | | | | I think this was just over-eagerness on my part. The analysis results need to often be non-const because they need to (in some cases at least) be updated by the transformation pass in order to remain correct. It also makes lazy analyses (a common case) needlessly annoying to write in order to make their entire state mutable. llvm-svn: 200881
* [PM] Add names to passes under the new pass manager, and a debug outputChandler Carruth2014-01-111-0/+10
| | | | | | | | | | mode that can be used to debug the execution of everything. No support for analyses here, that will come later. This already helps show parts of the opt commandline integration that isn't working. Tests of that will start using it as the bugs are fixed. llvm-svn: 199004
* Move the LLVM IR asm writer header files into the IR directory, as theyChandler Carruth2014-01-071-1/+1
| | | | | | | | | | | | | | | | | are part of the core IR library in order to support dumping and other basic functionality. Rename the 'Assembly' include directory to 'AsmParser' to match the library name and the only functionality left their -- printing has been in the core IR library for quite some time. Update all of the #includes to match. All of this started because I wanted to have the layering in good shape before I started adding support for printing LLVM IR using the new pass infrastructure, and commandline support for the new pass infrastructure. llvm-svn: 198688
* [PM] Complete the cross-layer interfaces with a Module-to-FunctionChandler Carruth2013-11-231-12/+65
| | | | | | | | | | | | | proxy. This lets a function pass query a module analysis manager. However, the interface is const to indicate that only cached results can be safely queried. With this, I think the new pass manager is largely functionally complete for modules and analyses. Still lots to test, and need to generalize to SCCs and Loops, and need to build an adaptor layer to support the use of existing Pass objects in the new managers. llvm-svn: 195538
* [PM] Rename TestAnalysisPass to TestFunctionAnalysis to clear the wayChandler Carruth2013-11-231-7/+7
| | | | | | for a TestModuleAnalysis. llvm-svn: 195537
* [PM] Add support to the analysis managers to query explicitly for cachedChandler Carruth2013-11-231-5/+34
| | | | | | | | | | | results. This is the last piece of infrastructure needed to effectively support querying *up* the analysis layers. The next step will be to introduce a proxy which provides access to those layers with appropriate use of const to direct queries to the safe interface. llvm-svn: 195525
* [PM] Switch the downward invalidation to be incremental where only theChandler Carruth2013-11-221-4/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | one function's analyses are invalidated at a time. Also switch the preservation of the proxy to *fully* preserve the lower (function) analyses. Combined, this gets both upward and downward analysis invalidation to a point I'm happy with: - A function pass invalidates its function analyses, and its parent's module analyses. - A module pass invalidates all of its functions' analyses including the set of which functions are in the module. - A function pass can preserve a module analysis pass. - If all function passes preserve a module analysis pass, that preservation persists. If any doesn't the module analysis is invalidated. - A module pass can opt into managing *all* function analysis invalidation itself or *none*. - The conservative default is none, and the proxy takes the maximally conservative approach that works even if the set of functions has changed. - If a module pass opts into managing function analysis invalidation it has to propagate the invalidation itself, the proxy just does nothing. The only thing really missing is a way to query for a cached analysis or nothing at all. With this, function passes can more safely request a cached module analysis pass without fear of it accidentally running part way through. llvm-svn: 195519
* [PM] Teach the analysis managers to pass themselves as arguments to theChandler Carruth2013-11-221-1/+1
| | | | | | | | | | | | | | run methods of the analysis passes. Also generalizes and re-uses the SFINAE for transformation passes so that users can write an analysis pass and only accept an analysis manager if that is useful to their pass. This completes the plumbing to make an analysis manager available through every pass's run method if desired so that passes no longer need to be constructed around them. llvm-svn: 195451
* [PM] Remove the IRUnitT typedef requirement for analysis passes.Chandler Carruth2013-11-221-2/+0
| | | | | | | | | | | | Since the analysis managers were split into explicit function and module analysis managers, it is now completely trivial to specify this when building up the concept and model types explicitly, and it is impossible to end up with a type error at run time. We instantiate a template when registering a pass that will enforce the requirement at a type-system level, and we produce a dynamic error on all the other query paths to the analysis manager if the pass in question isn't registered. llvm-svn: 195447
* [PM] Fix the analysis templates' usage of IRUnitT.Chandler Carruth2013-11-221-1/+1
| | | | | | | | | | | This is supposed to be the whole type of the IR unit, and so we shouldn't pass a pointer to it but rather the value itself. In turn, we need to provide a 'Module *' as that type argument (for example). This will become more relevant with SCCs or other units which may not be passed as a pointer type, but also brings consistency with the transformation pass templates. llvm-svn: 195445
* [PM] Switch analysis managers to be threaded through the run methodsChandler Carruth2013-11-221-22/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | rather than the constructors of passes. This simplifies the APIs of passes significantly and removes an error prone pattern where the *same* manager had to be given to every different layer. With the new API the analysis managers themselves will have to be cross connected with proxy analyses that allow a pass at one layer to query for the analysis manager of another layer. The proxy will both expose a handle to the other layer's manager and it will provide the invalidation hooks to ensure things remain consistent across layers. Finally, the outer-most analysis manager has to be passed to the run method of the outer-most pass manager. The rest of the propagation is automatic. I've used SFINAE again to allow passes to completely disregard the analysis manager if they don't need or want to care. This helps keep simple things simple for users of the new pass manager. Also, the system specifically supports passing a null pointer into the outer-most run method if your pass pipeline neither needs nor wants to deal with analyses. I find this of dubious utility as while some *passes* don't care about analysis, I'm not sure there are any real-world users of the pass manager itself that need to avoid even creating an analysis manager. But it is easy to support, so there we go. Finally I renamed the module proxy for the function analysis manager to the more verbose but less confusing name of FunctionAnalysisManagerModuleProxy. I hate this name, but I have no idea what else to name these things. I'm expecting in the fullness of time to potentially have the complete cross product of types at the proxy layer: {Module,SCC,Function,Loop,Region}AnalysisManager{Module,SCC,Function,Loop,Region}Proxy (except for XAnalysisManagerXProxy which doesn't make any sense) This should make it somewhat easier to do the next phases which is to build the upward proxy and get its invalidation correct, as well as to make the invalidation within the Module -> Function mapping pass be more fine grained so as to invalidate fewer fuction analyses. After all of the proxy analyses are done and the invalidation working, I'll finally be able to start working on the next two fun fronts: how to adapt an existing pass to work in both the legacy pass world and the new one, and building the SCC, Loop, and Region counterparts. Fun times! llvm-svn: 195400
* [PM] Widen the interface for invalidate on an analysis result now thatChandler Carruth2013-11-211-1/+35
| | | | | | | | | | | | | | | | | | | it is completely optional, and sink the logic for handling the preserved analysis set into it. This allows us to implement the delegation logic desired in the proxy module analysis for the function analysis manager where if the proxy itself is preserved we assume the set of functions hasn't changed and we do a fine grained invalidation by walking the functions in the module and running the invalidate for them all at the manager level and letting it try to invalidate any passes. This in turn makes it blindingly obvious why we should hoist the invalidate trait and have two collections of results. That allows handling invalidation for almost all analyses without indirect calls and it allows short circuiting when the preserved set is all. llvm-svn: 195338
* [PM] Add support for using SFINAE to reflect on an analysis's resultChandler Carruth2013-11-211-1/+0
| | | | | | | | | | | | | | | | | | type and detect whether or not it provides an 'invalidate' member the analysis manager should use. This lets the overwhelming common case of *not* caring about custom behavior when an analysis is invalidated be the the obvious default behavior with no code written by the author of an analysis. Only when they write code specifically to handle invalidation does it get used. Both cases are actually covered by tests here. The test analysis uses the default behavior, and the proxy module analysis actually has custom behavior on invalidation that is firing correctly. (In fact, this is the analysis which was the primary motivation for having custom invalidation behavior in the first place.) llvm-svn: 195332
* [PM] Add a module analysis pass proxy for the function analysis manager.Chandler Carruth2013-11-211-12/+37
| | | | | | | | | | | | | | | | This proxy will fill the role of proxying invalidation events down IR unit layers so that when a module changes we correctly invalidate function analyses. Currently this is a very coarse solution -- any change blows away the entire thing -- but the next step is to make invalidation handling more nuanced so that we can propagate specific amounts of invalidation from one layer to the next. The test is extended to place a module pass between two function pass managers each of which have preserved function analyses which get correctly invalidated by the module pass that might have changed what functions are even in the module. llvm-svn: 195304
* [PM] Add the preservation system to the new pass manager.Chandler Carruth2013-11-201-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds a new set-like type which represents a set of preserved analysis passes. The set is managed via the opaque PassT::ID() void*s. The expected convenience templates for interacting with specific passes are provided. It also supports a symbolic "all" state which is represented by an invalid pointer in the set. This state is nicely saturating as it comes up often. Finally, it supports intersection which is used when finding the set of preserved passes after N different transforms. The pass API is then changed to return the preserved set rather than a bool. This is much more self-documenting than the previous system. Returning "none" is a conservatively correct solution just like returning "true" from todays passes and not marking any passes as preserved. Passes can also be dynamically preserved or not throughout the run of the pass, and whatever gets returned is the binding state. Finally, preserving "all" the passes is allowed for no-op transforms that simply can't harm such things. Finally, the analysis managers are changed to instead of blindly invalidating all of the analyses, invalidate those which were not preserved. This should rig up all of the basic preservation functionality. This also correctly combines the preservation moving up from one IR-layer to the another and the preservation aggregation across N pass runs. Still to go is incrementally correct invalidation and preservation across IR layers incrementally during N pass runs. That will wait until we have a device for even exposing analyses across IR layers. While the core of this change is obvious, I'm not happy with the current testing, so will improve it to cover at least some of the invalidation that I can test easily in a subsequent commit. llvm-svn: 195241
* [PM] Make the function pass manager more regular.Chandler Carruth2013-11-201-1/+1
| | | | | | | | | | | | | | | | The FunctionPassManager is now itself a function pass. When run over a function, it runs all N of its passes over that function. This is the 1:N mapping in the pass dimension only. This allows it to be used in either a ModulePassManager or potentially some other manager that works on IR units which are supersets of Functions. This commit also adds the obvious adaptor to map from a module pass to a function pass, running the function pass across every function in the module. The test has been updated to use this new pattern. llvm-svn: 195192
* [PM] Split the analysis manager into a function-specific interface andChandler Carruth2013-11-201-9/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | a module-specific interface. This is the first of many steps necessary to generalize the infrastructure such that we can support both a Module-to-Function and Module-to-SCC-to-Function pass manager nestings. After a *lot* of attempts that never worked and didn't even make it to a committable state, it became clear that I had gotten the layering design of analyses flat out wrong. Four days later, I think I have most of the plan for how to correct this, and I'm starting to reshape the code into it. This is just a baby step I'm afraid, but starts separating the fundamentally distinct concepts of function analysis passes and module analysis passes so that in subsequent steps we can effectively layer them, and have a consistent design for the eventual SCC layer. As part of this, I've started some interface changes to make passes more regular. The module pass accepts the module in the run method, and some of the constructor parameters are gone. I'm still working out exactly where constructor parameters vs. method parameters will be used, so I expect this to fluctuate a bit. This actually makes the invalidation less "correct" at this phase, because now function passes don't invalidate module analysis passes, but that was actually somewhat of a misfeature. It will return in a better factored form which can scale to other units of IR. The documentation has gotten less verbose and helpful. llvm-svn: 195189
* [PM] Completely remove support for explicit 'require' methods on theChandler Carruth2013-11-171-1/+0
| | | | | | | AnalysisManager. All this method did was assert something and we have a perfectly good way to trigger that assert from the query path. llvm-svn: 194947
* Introduce an AnalysisManager which is like a pass manager but with a lotChandler Carruth2013-11-131-4/+48
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | more smarts in it. This is where most of the interesting logic that used to live in the implicit-scheduling-hackery of the old pass manager will live. Like the previous commits, note that this is a very early prototype! I expect substantial changes before this is ready to use. The core of the design is the following: - We have an AnalysisManager which can be used across a series of passes over a module. - The code setting up a pass pipeline registers the analyses available with the manager. - Individual transform passes can check than an analysis manager provides the analyses they require in order to fail-fast. - There is *no* implicit registration or scheduling. - Analysis passes are different from other passes: they produce an analysis result that is cached and made available via the analysis manager. - Cached results are invalidated automatically by the pass managers. - When a transform pass requests an analysis result, either the analysis is run to produce the result or a cached result is provided. There are a few aspects of this design that I *know* will change in subsequent commits: - Currently there is no "preservation" system, that needs to be added. - All of the analysis management should move up to the analysis library. - The analysis management needs to support at least SCC passes. Maybe loop passes. Living in the analysis library will facilitate this. - Need support for analyses which are *both* module and function passes. - Need support for pro-actively running module analyses to have cached results within a function pass manager. - Need a clear design for "immutable" passes. - Need support for requesting cached results when available and not re-running the pass even if that would be necessary. - Need more thorough testing of all of this infrastructure. There are other aspects that I view as open questions I'm hoping to resolve as I iterate a bit on the infrastructure, and especially as I start writing actual passes against this. - Should we have separate management layers for function, module, and SCC analyses? I think "yes", but I'm not yet ready to switch the code. Adding SCC support will likely resolve this definitively. - How should the 'require' functionality work? Should *that* be the only way to request results to ensure that passes always require things? - How should preservation work? - Probably some other things I'm forgetting. =] Look forward to more patches in shorter order now that this is in place. llvm-svn: 194538
* [PM] Start sketching out the new module and function pass manager.Chandler Carruth2013-11-091-0/+88
| | | | | | | | | | | | | | | | | | This is still just a skeleton. I'm trying to pull together the experimentation I've done into committable chunks, and this is the first coherent one. Others will follow in hopefully short order that move this more toward a useful initial implementation. I still expect the design to continue evolving in small ways as I work through the different requirements and features needed here though. Keep in mind, all of this is off by default. Currently, this mostly exercises the use of a polymorphic smart pointer and templates to hide the polymorphism for the pass manager from the pass implementation. The next step will be more significant, adding the first framework of analysis support. llvm-svn: 194325
* Move the old pass manager infrastructure into a legacy namespace andChandler Carruth2013-11-091-552/+0
| | | | | | | | | | | | | | | | | | | give the files a legacy prefix in the right directory. Use forwarding headers in the old locations to paper over the name change for most clients during the transitional period. No functionality changed here! This is just clearing some space to reduce renaming churn later on with a new system. Even when the new stuff starts to go in, it is going to be hidden behind a flag and off-by-default as it is still WIP and under development. This patch is specifically designed so that very little out-of-tree code has to change. I'm going to work as hard as I can to keep that the case. Only direct forward declarations of the PassManager class are impacted by this change. llvm-svn: 194324
* Merge CallGraph and BasicCallGraph.Rafael Espindola2013-10-311-1/+1
| | | | llvm-svn: 193734
* Rename the VMCore unittest tree to IR. Somehow was missed when doing theChandler Carruth2013-01-071-0/+552
library rename. llvm-svn: 171747
OpenPOWER on IntegriCloud