llvm-project/llvm/lib/Transforms
Chandler Carruth aaad9f84be [PM/LCG] Teach the LazyCallGraph how to replace a function without
disturbing the graph or having to update edges.

This is motivated by porting argument promotion to the new pass manager.
Because of how LLVM IR Function objects work, in order to change their
signature a new object needs to be created. This is efficient and
straight forward in the IR but previously was very hard to implement in
LCG. We could easily replace the function a node in the graph
represents. The challenging part is how to handle updating the edges in
the graph.

LCG previously used an edge to a raw function to represent a node that
had not yet been scanned for calls and references. This was the core
of its laziness. However, that model causes this kind of update to be
very hard:
1) The keys to lookup an edge need to be `Function*`s that would all
   need to be updated when we update the node.
2) There will be some unknown number of edges that haven't transitioned
   from `Function*` edges to `Node*` edges.

All of this complexity isn't necessary. Instead, we can always build
a node around any function, always pointing edges at it and always using
it as the key to lookup an edge. To maintain the laziness, we need to
sink the *edges* of a node into a secondary object and explicitly model
transitioning a node from empty to populated by scanning the function.
This design seems much cleaner in a number of ways, but importantly
there is now exactly *one* place where the `Function*` has to be
updated!

Some other cleanups that fall out of this include having something to
model the *entry* edges more accurately. Rather than hand rolling parts
of the node in the graph itself, we have an explicit `EdgeSequence`
object that gives us exactly the functionality needed. We also have
a consistent place to define the edge iterators and can use them for
both the entry edges and the internal edges of the graph.

The API used to model the separation between a node and its edges is
intentionally very thin as most clients are expected to deal with nodes
that have populated edges. We model this exactly as an optional does
with an additional method to populate the edges when that is
a reasonable thing for a client to do. This is based on API design
suggestions from Richard Smith and David Blaikie, credit goes to them
for helping pick how to model this without it being either too explicit
or too implicit.

The patch is somewhat noisy due to shifting around iterator types and
new syntax for walking the edges of a node, but most of the
functionality change is in the `Edge`, `EdgeSequence`, and `Node` types.

Differential Revision: https://reviews.llvm.org/D29577

llvm-svn: 294653
2017-02-09 23:24:13 +00:00
..
Coroutines [Coroutines] Add header guard to header that's missing one. 2017-01-30 16:32:20 +00:00
Hello Add auto-exporting of symbols from tools so that plugins work on Windows 2016-05-26 11:16:43 +00:00
IPO [PM/LCG] Teach the LazyCallGraph how to replace a function without 2017-02-09 23:24:13 +00:00
InstCombine [InstCombine] allow (X * C2) << C1 --> X * (C2 << C1) for vectors 2017-02-09 23:13:04 +00:00
Instrumentation [sancov] using comdat only when it is enabled 2017-02-08 23:12:46 +00:00
ObjCARC [CMake] NFC. Updating CMake dependency specifications 2016-11-17 04:36:50 +00:00
Scalar [LoadCombine] Fix combining of loads which span an aliasing store. 2017-02-09 21:46:49 +00:00
Utils [JumpThreading] Thread through guards 2017-02-09 19:40:22 +00:00
Vectorize [Loop Vectorizer] Cost-based decision for vectorization form of memory instruction. 2017-02-08 19:25:23 +00:00
CMakeLists.txt [coroutines] Part 3 of N: Adding Boilerplate for Coroutine Passes 2016-07-28 21:04:31 +00:00
LLVMBuild.txt [coroutines] Part 3 of N: Adding Boilerplate for Coroutine Passes 2016-07-28 21:04:31 +00:00