forked from OSchip/llvm-project
[LCG] Minor cleanup to the LCG walk over a function, NFC.
This just hoists the check for declarations up a layer which allows various sets used in the walk to be smaller. Also moves the relevant comments to match, and catches a few other cleanups in this code. llvm-svn: 289163
This commit is contained in:
parent
7a1e5bbe4e
commit
86f0bdf832
|
@ -953,6 +953,13 @@ public:
|
|||
/// useful to code doing updates or otherwise wanting to walk the IR in the
|
||||
/// same patterns as when we build the call graph.
|
||||
|
||||
/// Recursively visits the defined functions whose address is reachable from
|
||||
/// every constant in the \p Worklist.
|
||||
///
|
||||
/// Doesn't recurse through any constants already in the \p Visited set, and
|
||||
/// updates that set with every constant visited.
|
||||
///
|
||||
/// For each defined function, calls \p Callback with that function.
|
||||
template <typename CallbackT>
|
||||
static void visitReferences(SmallVectorImpl<Constant *> &Worklist,
|
||||
SmallPtrSetImpl<Constant *> &Visited,
|
||||
|
@ -961,7 +968,8 @@ public:
|
|||
Constant *C = Worklist.pop_back_val();
|
||||
|
||||
if (Function *F = dyn_cast<Function>(C)) {
|
||||
Callback(*F);
|
||||
if (!F->isDeclaration())
|
||||
Callback(*F);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -969,10 +977,10 @@ public:
|
|||
if (Visited.insert(cast<Constant>(Op)).second)
|
||||
Worklist.push_back(cast<Constant>(Op));
|
||||
}
|
||||
|
||||
///@}
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
private:
|
||||
typedef SmallVectorImpl<Node *>::reverse_iterator node_stack_iterator;
|
||||
typedef iterator_range<node_stack_iterator> node_stack_range;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/ScopeExit.h"
|
||||
#include "llvm/IR/CallSite.h"
|
||||
#include "llvm/IR/InstVisitor.h"
|
||||
#include "llvm/IR/Instructions.h"
|
||||
|
@ -25,21 +26,11 @@ using namespace llvm;
|
|||
static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges,
|
||||
DenseMap<Function *, int> &EdgeIndexMap, Function &F,
|
||||
LazyCallGraph::Edge::Kind EK) {
|
||||
// Note that we consider *any* function with a definition to be a viable
|
||||
// edge. Even if the function's definition is subject to replacement by
|
||||
// some other module (say, a weak definition) there may still be
|
||||
// optimizations which essentially speculate based on the definition and
|
||||
// a way to check that the specific definition is in fact the one being
|
||||
// used. For example, this could be done by moving the weak definition to
|
||||
// a strong (internal) definition and making the weak definition be an
|
||||
// alias. Then a test of the address of the weak function against the new
|
||||
// strong definition's address would be an effective way to determine the
|
||||
// safety of optimizing a direct call edge.
|
||||
if (!F.isDeclaration() &&
|
||||
EdgeIndexMap.insert({&F, Edges.size()}).second) {
|
||||
DEBUG(dbgs() << " Added callable function: " << F.getName() << "\n");
|
||||
Edges.emplace_back(LazyCallGraph::Edge(F, EK));
|
||||
}
|
||||
if (!EdgeIndexMap.insert({&F, Edges.size()}).second)
|
||||
return;
|
||||
|
||||
DEBUG(dbgs() << " Added callable function: " << F.getName() << "\n");
|
||||
Edges.emplace_back(LazyCallGraph::Edge(F, EK));
|
||||
}
|
||||
|
||||
LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F)
|
||||
|
@ -56,14 +47,26 @@ LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F)
|
|||
// are trivially added, but to accumulate the latter we walk the instructions
|
||||
// and add every operand which is a constant to the worklist to process
|
||||
// afterward.
|
||||
//
|
||||
// Note that we consider *any* function with a definition to be a viable
|
||||
// edge. Even if the function's definition is subject to replacement by
|
||||
// some other module (say, a weak definition) there may still be
|
||||
// optimizations which essentially speculate based on the definition and
|
||||
// a way to check that the specific definition is in fact the one being
|
||||
// used. For example, this could be done by moving the weak definition to
|
||||
// a strong (internal) definition and making the weak definition be an
|
||||
// alias. Then a test of the address of the weak function against the new
|
||||
// strong definition's address would be an effective way to determine the
|
||||
// safety of optimizing a direct call edge.
|
||||
for (BasicBlock &BB : F)
|
||||
for (Instruction &I : BB) {
|
||||
if (auto CS = CallSite(&I))
|
||||
if (Function *Callee = CS.getCalledFunction())
|
||||
if (Callees.insert(Callee).second) {
|
||||
Visited.insert(Callee);
|
||||
addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
|
||||
}
|
||||
if (!Callee->isDeclaration())
|
||||
if (Callees.insert(Callee).second) {
|
||||
Visited.insert(Callee);
|
||||
addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
|
||||
}
|
||||
|
||||
for (Value *Op : I.operand_values())
|
||||
if (Constant *C = dyn_cast<Constant>(Op))
|
||||
|
|
Loading…
Reference in New Issue