[LCG] Just move the allocator (now that we can) when moving a call
[oota-llvm.git] / lib / Analysis / LazyCallGraph.cpp
1 //===- LazyCallGraph.cpp - Analysis of a Module's call graph --------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Analysis/LazyCallGraph.h"
11 #include "llvm/ADT/SCCIterator.h"
12 #include "llvm/IR/CallSite.h"
13 #include "llvm/IR/InstVisitor.h"
14 #include "llvm/IR/Instructions.h"
15 #include "llvm/IR/PassManager.h"
16 #include "llvm/Support/raw_ostream.h"
17
18 using namespace llvm;
19
20 static void findCallees(
21     SmallVectorImpl<Constant *> &Worklist, SmallPtrSetImpl<Constant *> &Visited,
22     SmallVectorImpl<PointerUnion<Function *, LazyCallGraph::Node *>> &Callees,
23     SmallPtrSetImpl<Function *> &CalleeSet) {
24   while (!Worklist.empty()) {
25     Constant *C = Worklist.pop_back_val();
26
27     if (Function *F = dyn_cast<Function>(C)) {
28       // Note that we consider *any* function with a definition to be a viable
29       // edge. Even if the function's definition is subject to replacement by
30       // some other module (say, a weak definition) there may still be
31       // optimizations which essentially speculate based on the definition and
32       // a way to check that the specific definition is in fact the one being
33       // used. For example, this could be done by moving the weak definition to
34       // a strong (internal) definition and making the weak definition be an
35       // alias. Then a test of the address of the weak function against the new
36       // strong definition's address would be an effective way to determine the
37       // safety of optimizing a direct call edge.
38       if (!F->isDeclaration() && CalleeSet.insert(F))
39         Callees.push_back(F);
40       continue;
41     }
42
43     for (Value *Op : C->operand_values())
44       if (Visited.insert(cast<Constant>(Op)))
45         Worklist.push_back(cast<Constant>(Op));
46   }
47 }
48
49 LazyCallGraph::Node::Node(LazyCallGraph &G, Function &F) : G(&G), F(F) {
50   SmallVector<Constant *, 16> Worklist;
51   SmallPtrSet<Constant *, 16> Visited;
52   // Find all the potential callees in this function. First walk the
53   // instructions and add every operand which is a constant to the worklist.
54   for (BasicBlock &BB : F)
55     for (Instruction &I : BB)
56       for (Value *Op : I.operand_values())
57         if (Constant *C = dyn_cast<Constant>(Op))
58           if (Visited.insert(C))
59             Worklist.push_back(C);
60
61   // We've collected all the constant (and thus potentially function or
62   // function containing) operands to all of the instructions in the function.
63   // Process them (recursively) collecting every function found.
64   findCallees(Worklist, Visited, Callees, CalleeSet);
65 }
66
67 LazyCallGraph::Node::Node(LazyCallGraph &G, const Node &OtherN)
68     : G(&G), F(OtherN.F), CalleeSet(OtherN.CalleeSet) {
69   // Loop over the other node's callees, adding the Function*s to our list
70   // directly, and recursing to add the Node*s.
71   Callees.reserve(OtherN.Callees.size());
72   for (const auto &OtherCallee : OtherN.Callees)
73     if (Function *Callee = OtherCallee.dyn_cast<Function *>())
74       Callees.push_back(Callee);
75     else
76       Callees.push_back(G.copyInto(*OtherCallee.get<Node *>()));
77 }
78
79 LazyCallGraph::LazyCallGraph(Module &M) {
80   for (Function &F : M)
81     if (!F.isDeclaration() && !F.hasLocalLinkage())
82       if (EntryNodeSet.insert(&F))
83         EntryNodes.push_back(&F);
84
85   // Now add entry nodes for functions reachable via initializers to globals.
86   SmallVector<Constant *, 16> Worklist;
87   SmallPtrSet<Constant *, 16> Visited;
88   for (GlobalVariable &GV : M.globals())
89     if (GV.hasInitializer())
90       if (Visited.insert(GV.getInitializer()))
91         Worklist.push_back(GV.getInitializer());
92
93   findCallees(Worklist, Visited, EntryNodes, EntryNodeSet);
94 }
95
96 LazyCallGraph::LazyCallGraph(const LazyCallGraph &G)
97     : EntryNodeSet(G.EntryNodeSet) {
98   EntryNodes.reserve(G.EntryNodes.size());
99   for (const auto &EntryNode : G.EntryNodes)
100     if (Function *Callee = EntryNode.dyn_cast<Function *>())
101       EntryNodes.push_back(Callee);
102     else
103       EntryNodes.push_back(copyInto(*EntryNode.get<Node *>()));
104 }
105
106 LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
107     : BPA(std::move(G.BPA)), EntryNodes(std::move(G.EntryNodes)),
108       EntryNodeSet(std::move(G.EntryNodeSet)) {
109   // Process all nodes updating the graph pointers.
110   SmallVector<Node *, 16> Worklist;
111   for (auto &Entry : EntryNodes)
112     if (Node *EntryN = Entry.dyn_cast<Node *>())
113       Worklist.push_back(EntryN);
114
115   while (!Worklist.empty()) {
116     Node *N = Worklist.pop_back_val();
117     N->G = this;
118     for (auto &Callee : N->Callees)
119       if (Node *CalleeN = Callee.dyn_cast<Node *>())
120         Worklist.push_back(CalleeN);
121   }
122 }
123
124 LazyCallGraph::Node *LazyCallGraph::insertInto(Function &F, Node *&MappedN) {
125   return new (MappedN = BPA.Allocate()) Node(*this, F);
126 }
127
128 LazyCallGraph::Node *LazyCallGraph::copyInto(const Node &OtherN) {
129   Node *&N = NodeMap[&OtherN.F];
130   if (N)
131     return N;
132
133   return new (N = BPA.Allocate()) Node(*this, OtherN);
134 }
135
136 char LazyCallGraphAnalysis::PassID;
137
138 LazyCallGraphPrinterPass::LazyCallGraphPrinterPass(raw_ostream &OS) : OS(OS) {}
139
140 static void printNodes(raw_ostream &OS, LazyCallGraph::Node &N,
141                        SmallPtrSetImpl<LazyCallGraph::Node *> &Printed) {
142   // Recurse depth first through the nodes.
143   for (LazyCallGraph::Node *ChildN : N)
144     if (Printed.insert(ChildN))
145       printNodes(OS, *ChildN, Printed);
146
147   OS << "  Call edges in function: " << N.getFunction().getName() << "\n";
148   for (LazyCallGraph::iterator I = N.begin(), E = N.end(); I != E; ++I)
149     OS << "    -> " << I->getFunction().getName() << "\n";
150
151   OS << "\n";
152 }
153
154 PreservedAnalyses LazyCallGraphPrinterPass::run(Module *M,
155                                                 ModuleAnalysisManager *AM) {
156   LazyCallGraph &G = AM->getResult<LazyCallGraphAnalysis>(M);
157
158   OS << "Printing the call graph for module: " << M->getModuleIdentifier()
159      << "\n\n";
160
161   SmallPtrSet<LazyCallGraph::Node *, 16> Printed;
162   for (LazyCallGraph::Node *N : G)
163     if (Printed.insert(N))
164       printNodes(OS, *N, Printed);
165
166   return PreservedAnalyses::all();
167 }