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
|
/// useful to code doing updates or otherwise wanting to walk the IR in the
|
||||||
/// same patterns as when we build the call graph.
|
/// 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>
|
template <typename CallbackT>
|
||||||
static void visitReferences(SmallVectorImpl<Constant *> &Worklist,
|
static void visitReferences(SmallVectorImpl<Constant *> &Worklist,
|
||||||
SmallPtrSetImpl<Constant *> &Visited,
|
SmallPtrSetImpl<Constant *> &Visited,
|
||||||
|
@ -961,7 +968,8 @@ public:
|
||||||
Constant *C = Worklist.pop_back_val();
|
Constant *C = Worklist.pop_back_val();
|
||||||
|
|
||||||
if (Function *F = dyn_cast<Function>(C)) {
|
if (Function *F = dyn_cast<Function>(C)) {
|
||||||
Callback(*F);
|
if (!F->isDeclaration())
|
||||||
|
Callback(*F);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -969,10 +977,10 @@ public:
|
||||||
if (Visited.insert(cast<Constant>(Op)).second)
|
if (Visited.insert(cast<Constant>(Op)).second)
|
||||||
Worklist.push_back(cast<Constant>(Op));
|
Worklist.push_back(cast<Constant>(Op));
|
||||||
}
|
}
|
||||||
|
|
||||||
///@}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef SmallVectorImpl<Node *>::reverse_iterator node_stack_iterator;
|
typedef SmallVectorImpl<Node *>::reverse_iterator node_stack_iterator;
|
||||||
typedef iterator_range<node_stack_iterator> node_stack_range;
|
typedef iterator_range<node_stack_iterator> node_stack_range;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "llvm/ADT/ScopeExit.h"
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include "llvm/ADT/Sequence.h"
|
#include "llvm/ADT/Sequence.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/ScopeExit.h"
|
||||||
#include "llvm/IR/CallSite.h"
|
#include "llvm/IR/CallSite.h"
|
||||||
#include "llvm/IR/InstVisitor.h"
|
#include "llvm/IR/InstVisitor.h"
|
||||||
#include "llvm/IR/Instructions.h"
|
#include "llvm/IR/Instructions.h"
|
||||||
|
@ -25,21 +26,11 @@ using namespace llvm;
|
||||||
static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges,
|
static void addEdge(SmallVectorImpl<LazyCallGraph::Edge> &Edges,
|
||||||
DenseMap<Function *, int> &EdgeIndexMap, Function &F,
|
DenseMap<Function *, int> &EdgeIndexMap, Function &F,
|
||||||
LazyCallGraph::Edge::Kind EK) {
|
LazyCallGraph::Edge::Kind EK) {
|
||||||
// Note that we consider *any* function with a definition to be a viable
|
if (!EdgeIndexMap.insert({&F, Edges.size()}).second)
|
||||||
// edge. Even if the function's definition is subject to replacement by
|
return;
|
||||||
// some other module (say, a weak definition) there may still be
|
|
||||||
// optimizations which essentially speculate based on the definition and
|
DEBUG(dbgs() << " Added callable function: " << F.getName() << "\n");
|
||||||
// a way to check that the specific definition is in fact the one being
|
Edges.emplace_back(LazyCallGraph::Edge(F, EK));
|
||||||
// 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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F)
|
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
|
// 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
|
// and add every operand which is a constant to the worklist to process
|
||||||
// afterward.
|
// 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 (BasicBlock &BB : F)
|
||||||
for (Instruction &I : BB) {
|
for (Instruction &I : BB) {
|
||||||
if (auto CS = CallSite(&I))
|
if (auto CS = CallSite(&I))
|
||||||
if (Function *Callee = CS.getCalledFunction())
|
if (Function *Callee = CS.getCalledFunction())
|
||||||
if (Callees.insert(Callee).second) {
|
if (!Callee->isDeclaration())
|
||||||
Visited.insert(Callee);
|
if (Callees.insert(Callee).second) {
|
||||||
addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
|
Visited.insert(Callee);
|
||||||
}
|
addEdge(Edges, EdgeIndexMap, *Callee, LazyCallGraph::Edge::Call);
|
||||||
|
}
|
||||||
|
|
||||||
for (Value *Op : I.operand_values())
|
for (Value *Op : I.operand_values())
|
||||||
if (Constant *C = dyn_cast<Constant>(Op))
|
if (Constant *C = dyn_cast<Constant>(Op))
|
||||||
|
|
Loading…
Reference in New Issue