summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/LazyCallGraph.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* [LCG] We don't actually need a set in each SCC to track the nodes. WeChandler Carruth2014-04-241-7/+1
| | | | | | | can use the node -> SCC mapping in the top-level graph to test this on the rare occasions we need it. llvm-svn: 207090
* [LCG] Normalize the post-order SCC iterator to just iterate over the SCCChandler Carruth2014-04-231-2/+2
| | | | | | values rather than having pointers in weird places. llvm-svn: 207053
* [LCG] Switch the primary node iterator to be a *much* more normal C++Chandler Carruth2014-04-231-39/+33
| | | | | | iterator, returning a Node by reference on dereference. llvm-svn: 207048
* [LCG] Make the insertion and query paths into the LCG which cannot failChandler Carruth2014-04-231-4/+4
| | | | | | | | return references to better model this property. No functionality changed. llvm-svn: 207047
* [LCG] Switch the SCC lookup to be in terms of call graph nodes ratherChandler Carruth2014-04-231-8/+8
| | | | | | | | | | than functions. So far, this access pattern is *much* more common. It seems likely that any user of this interface is going to have nodes at the point that they are querying the SCCs. No functionality changed. llvm-svn: 207045
* [LCG] Switch the primary SCC building code to use the negative low-linkChandler Carruth2014-04-231-2/+4
| | | | | | | | | | | | | | | values rather than an expensive dense map query to test whether children have already been popped into an SCC. This matches the incremental SCC building code. I've also included the assert that I put there but updated both of their text. No functionality changed here. I still don't have any great ideas for sharing the code between the two implementations, but I may try a brute-force approach to factoring it at some point. llvm-svn: 207042
* [LCG] Add the first round of mutation support to the lazy call graph.Chandler Carruth2014-04-231-0/+233
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | This implements the core functionality necessary to remove an edge from the call graph and correctly update both the basic graph and the SCC structure. As part of that it has to run a tiny (in number of nodes) Tarjan-style DFS walk of an SCC being mutated to compute newly formed SCCs, etc. This is *very rough* and a WIP. I have a bunch of FIXMEs for code cleanup that will reduce the boilerplate in this change substantially. I also have a bunch of simplifications to various parts of both algorithms that I want to make, but first I'd like to have a more holistic picture. Ideally, I'd also like more testing. I'll probably add quite a few more unit tests as I go here to cover the various different aspects and corner cases of removing edges from the graph. Still, this is, so far, successfully updating the SCC graph in-place without disrupting the identity established for the existing SCCs even when we do challenging things like delete the critical edge that made an SCC cycle at all and have to reform things as a tree of smaller SCCs. Getting this to work is really critical for the new pass manager as it is going to associate significant state with the SCC instance and needs it to be stable. That is also the motivation behind the return of the newly formed SCCs. Eventually, I'll wire this all the way up to the public API so that the pass manager can use it to correctly re-enqueue newly formed SCCs into a fresh postorder traversal. llvm-svn: 206968
* [LCG] Implement Tarjan's algorithm correctly this time. We have to walkChandler Carruth2014-04-231-34/+42
| | | | | | | | | | | | up the stack finishing the exploration of each entries children before we're finished in addition to accounting for their low-links. Added a unittest that really hammers home the need for this with interlocking cycles that would each appear distinct otherwise and crash or compute the wrong result. As part of this, nuke a stale fixme and bring the rest of the implementation still more closely in line with the original algorithm. llvm-svn: 206966
* [LCG] Add a unittest for the LazyCallGraph. I had a weak moment andChandler Carruth2014-04-231-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | resisted this for too long. Just with the basic testing here I was able to exercise the analysis in more detail and sift out both type signature bugs in the API and a bug in the DFS numbering. All of these are fixed here as well. The unittests will be much more important for the mutation support where it is necessary to craft minimal mutations and then inspect the state of the graph. There is just no way to do that with a standard FileCheck test. However, unittesting these kinds of analyses is really quite easy, especially as they're designed with the new pass manager where there is essentially no infrastructure required to rig up the core logic and exercise it at an API level. As a minor aside about the DFS numbering bug, the DFS numbering used in LCG is a bit unusual. Rather than numbering from 0, we number from 1, and use 0 as the sentinel "unvisited" state. Other implementations often use '-1' for this, but I find it easier to deal with 0 and it shouldn't make any real difference provided someone doesn't write silly bugs like forgetting to actually initialize the DFS numbering. Oops. ;] llvm-svn: 206954
* [LCG] Hoist the logic for forming a new SCC from the top of the DFSStackChandler Carruth2014-04-231-41/+47
| | | | | | | into a helper function. I plan to re-use it for doing incremental DFS-based updates to the SCCs when we mutate the call graph. llvm-svn: 206948
* [LCG] Switch the Callee sets to be DenseMaps pointing to the index intoChandler Carruth2014-04-231-7/+8
| | | | | | | | | the Callee list. This is going to be quite important to prevent removal from going quadratic. No functionality changed at this point, this is one of the refactoring patches I've broken out of my initial work toward mutation updates of the call graph. llvm-svn: 206938
* [Modules] Fix potential ODR violations by sinking the DEBUG_TYPEChandler Carruth2014-04-221-1/+2
| | | | | | | | | | definition below all the header #include lines, lib/Analysis/... edition. This one has a bit extra as there were *other* #define's before #include lines in addition to DEBUG_TYPE. I've sunk all of them as a block. llvm-svn: 206843
* [LCG] Add some basic debug output to the LCG pass.Chandler Carruth2014-04-211-2/+17
| | | | llvm-svn: 206730
* [LCG] Fix the bugs that Ben pointed out in code review (and the MSan botChandler Carruth2014-04-181-3/+7
| | | | | | | caught). Sad that we don't have warnings for these things, but bleh, no idea how to fix that. llvm-svn: 206646
* [LCG] Remove all of the complexity stemming from supporting copying.Chandler Carruth2014-04-181-42/+21
| | | | | | | | | | | | | | Reality is that we're never going to copy one of these. Supporting this was becoming a nightmare because nothing even causes it to compile most of the time. Lots of subtle errors built up that wouldn't have been caught by any "normal" testing. Also, make the move assignment actually work rather than the bogus swap implementation that would just infloop if used. As part of that, factor out the graph pointer updates into a helper to share between move construction and move assignment. llvm-svn: 206583
* [LCG] Add support for building persistent and connected SCCs to theChandler Carruth2014-04-181-4/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | LazyCallGraph. This is the start of the whole point of this different abstraction, but it is just the initial bits. Here is a run-down of what's going on here. I'm planning to incorporate some (or all) of this into comments going forward, hopefully with better editing and wording. =] The crux of the problem with the traditional way of building SCCs is that they are ephemeral. The new pass manager however really needs the ability to associate analysis passes and results of analysis passes with SCCs in order to expose these analysis passes to the SCC passes. Making this work is kind-of the whole point of the new pass manager. =] So, when we're building SCCs for the call graph, we actually want to build persistent nodes that stick around and can be reasoned about later. We'd also like the ability to walk the SCC graph in more complex ways than just the traditional postorder traversal of the current CGSCC walk. That means that in addition to being persistent, the SCCs need to be connected into a useful graph structure. However, we still want the SCCs to be formed lazily where possible. These constraints are quite hard to satisfy with the SCC iterator. Also, using that would bypass our ability to actually add data to the nodes of the call graph to facilite implementing the Tarjan walk. So I've re-implemented things in a more direct and embedded way. This immediately makes it easy to get the persistence and connectivity correct, and it also allows leveraging the existing nodes to simplify the algorithm. I've worked somewhat to make this implementation more closely follow the traditional paper's nomenclature and strategy, although it is still a bit obtuse because it isn't recursive, using an explicit stack and a tail call instead, and it is interruptable, resuming each time we need another SCC. The other tricky bit here, and what actually took almost all the time and trials and errors I spent building this, is exactly *what* graph structure to build for the SCCs. The naive thing to build is the call graph in its newly acyclic form. I wrote about 4 versions of this which did precisely this. Inevitably, when I experimented with them across various use cases, they became incredibly awkward. It was all implementable, but it felt like a complete wrong fit. Square peg, round hole. There were two overriding aspects that pushed me in a different direction: 1) We want to discover the SCC graph in a postorder fashion. That means the root node will be the *last* node we find. Using the call-SCC DAG as the graph structure of the SCCs results in an orphaned graph until we discover a root. 2) We will eventually want to walk the SCC graph in parallel, exploring distinct sub-graphs independently, and synchronizing at merge points. This again is not helped by the call-SCC DAG structure. The structure which, quite surprisingly, ended up being completely natural to use is the *inverse* of the call-SCC DAG. We add the leaf SCCs to the graph as "roots", and have edges to the caller SCCs. Once I switched to building this structure, everything just fell into place elegantly. Aside from general cleanups (there are FIXMEs and too few comments overall) that are still needed, the other missing piece of this is support for iterating across levels of the SCC graph. These will become useful for implementing #2, but they aren't an immediate priority. Once SCCs are in good shape, I'll be working on adding mutation support for incremental updates and adding the pass manager that this analysis enables. llvm-svn: 206581
* [LCG] Just move the allocator (now that we can) when moving a callChandler Carruth2014-04-171-28/+14
| | | | | | | | | graph. This simplifies the custom move constructor operation to one of walking the graph and updating the 'up' pointers to point to the new location of the graph. Switch the nodes from a reference to a pointer for the 'up' edge to facilitate this. llvm-svn: 206450
* [LCG] Remove the Module reference member which we weren't using forChandler Carruth2014-04-171-3/+3
| | | | | | anything and doesn't make sense if assigning. llvm-svn: 206449
* [LCG] Ran clang-format over this too and it pointed out some fixes.Chandler Carruth2014-03-101-4/+6
| | | | llvm-svn: 203435
* [LCG] Simplify a bunch of the LCG code with range for loops and auto.Chandler Carruth2014-03-091-37/+29
| | | | | | | Still more work to be done here to leverage C++11, but this clears out the glaring issues. llvm-svn: 203395
* [Layering] Move InstVisitor.h into the IR library as it is prettyChandler Carruth2014-03-061-1/+1
| | | | | | obviously coupled to the IR. llvm-svn: 203064
* [Modules] Move CallSite into the IR library where it belogs. It isChandler Carruth2014-03-041-1/+1
| | | | | | | abstracting between a CallInst and an InvokeInst, both of which are IR concepts. llvm-svn: 202816
* [cleanup] Re-sort all the includes with utils/sort_includes.py.Chandler Carruth2014-03-041-1/+1
| | | | llvm-svn: 202811
* [C++11] Add two range adaptor views to User: operands andChandler Carruth2014-03-031-9/+5
| | | | | | | | | | | | | | | | | | operand_values. The first provides a range view over operand Use objects, and the second provides a range view over the Value*s being used by those operands. The naming is "STL-style" rather than "LLVM-style" because we have historically named iterator methods STL-style, and range methods seem to have far more in common with their iterator counterparts than with "normal" APIs. Feel free to bikeshed on this one if you want, I'm happy to change these around if people feel strongly. I've switched code in SROA and LCG to exercise these mostly to ensure they work correctly -- we don't really have an easy way to unittest this and they're trivial. llvm-svn: 202687
* [C++11] Remove the use of LLVM_HAS_RVALUE_REFERENCES from the rest ofChandler Carruth2014-03-011-6/+0
| | | | | | the core LLVM libraries. llvm-svn: 202582
* [PM] Fix horrible typos that somehow didn't cause a failure in a C++11Chandler Carruth2014-02-061-7/+9
| | | | | | | | | | | | build but spectacularly changed behavior of the C++98 build. =] This shows my one problem with not having unittests -- basic API expectations aren't well exercised by the integration tests because they *happen* to not come up, even though they might later. I'll probably add a basic unittest to complement the integration testing later, but I wanted to revive the bots. llvm-svn: 200905
* [PM] Add a new "lazy" call graph analysis pass for the new pass manager.Chandler Carruth2014-02-061-0/+195
The primary motivation for this pass is to separate the call graph analysis used by the new pass manager's CGSCC pass management from the existing call graph analysis pass. That analysis pass is (somewhat unfortunately) over-constrained by the existing CallGraphSCCPassManager requirements. Those requirements make it *really* hard to cleanly layer the needed functionality for the new pass manager on top of the existing analysis. However, there are also a bunch of things that the pass manager would specifically benefit from doing differently from the existing call graph analysis, and this new implementation tries to address several of them: - Be lazy about scanning function definitions. The existing pass eagerly scans the entire module to build the initial graph. This new pass is significantly more lazy, and I plan to push this even further to maximize locality during CGSCC walks. - Don't use a single synthetic node to partition functions with an indirect call from functions whose address is taken. This node creates a huge choke-point which would preclude good parallelization across the fanout of the SCC graph when we got to the point of looking at such changes to LLVM. - Use a memory dense and lightweight representation of the call graph rather than value handles and tracking call instructions. This will require explicit update calls instead of some updates working transparently, but should end up being significantly more efficient. The explicit update calls ended up being needed in many cases for the existing call graph so we don't really lose anything. - Doesn't explicitly model SCCs and thus doesn't provide an "identity" for an SCC which is stable across updates. This is essential for the new pass manager to work correctly. - Only form the graph necessary for traversing all of the functions in an SCC friendly order. This is a much simpler graph structure and should be more memory dense. It does limit the ways in which it is appropriate to use this analysis. I wish I had a better name than "call graph". I've commented extensively this aspect. This is still very much a WIP, in fact it is really just the initial bits. But it is about the fourth version of the initial bits that I've implemented with each of the others running into really frustrating problms. This looks like it will actually work and I'd like to split the actual complexity across commits for the sake of my reviewers. =] The rest of the implementation along with lots of wiring will follow somewhat more rapidly now that there is a good path forward. Naturally, this doesn't impact any of the existing optimizer. This code is specific to the new pass manager. A bunch of thanks are deserved for the various folks that have helped with the design of this, especially Nick Lewycky who actually sat with me to go through the fundamentals of the final version here. llvm-svn: 200903
OpenPOWER on IntegriCloud