llvm.org GIT mirror llvm / ed50411
[PM/LCG] Teach the LazyCallGraph to maintain reference edges from every function to every defined function known to LLVM as a library function. LLVM can introduce calls to these functions either by replacing other library calls or by recognizing patterns (such as memset_pattern or vector math patterns) and replacing those with calls. When these library functions are actually defined in the module, we need to have reference edges to them initially so that we visit them during the CGSCC walk in the right order and can effectively rebuild the call graph afterward. This was discovered when building code with Fortify enabled as that is a common case of both inline definitions of library calls and simplifications of code into calling them. This can in extreme cases of LTO-ing with libc introduce *many* more reference edges. I discussed a bunch of different options with folks but all of them are unsatisfying. They either make the graph operations substantially more complex even when there are *no* defined libfuncs, or they introduce some other complexity into the callgraph. So this patch goes with the simplest possible solution of actual synthetic reference edges. If this proves to be a memory problem, I'm happy to implement one of the clever techniques to save memory here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@308088 91177308-0d34-0410-b5e6-96231b3b80d8 Chandler Carruth 3 years ago
7 changed file(s) with 124 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
4242 #include "llvm/ADT/SmallVector.h"
4343 #include "llvm/ADT/iterator.h"
4444 #include "llvm/ADT/iterator_range.h"
45 #include "llvm/Analysis/TargetLibraryInfo.h"
4546 #include "llvm/IR/BasicBlock.h"
4647 #include "llvm/IR/Constants.h"
4748 #include "llvm/IR/Function.h"
907908 /// This sets up the graph and computes all of the entry points of the graph.
908909 /// No function definitions are scanned until their nodes in the graph are
909910 /// requested during traversal.
910 LazyCallGraph(Module &M);
911 LazyCallGraph(Module &M, TargetLibraryInfo &TLI);
911912
912913 LazyCallGraph(LazyCallGraph &&G);
913914 LazyCallGraph &operator=(LazyCallGraph &&RHS);
965966 return insertInto(F, N);
966967 }
967968
969 /// Get the sequence of known and defined library functions.
970 ///
971 /// These functions, because they are known to LLVM, can have calls
972 /// introduced out of thin air from arbitrary IR.
973 ArrayRef getLibFunctions() const { return LibFunctions; }
974
968975 ///@{
969976 /// \name Pre-SCC Mutation API
970977 ///
10981105 ///
10991106 /// These are all of the RefSCCs which have no children.
11001107 SmallVector LeafRefSCCs;
1108
1109 /// Defined functions that are also known library functions which the
1110 /// optimizer can reason about and therefore might introduce calls to out of
1111 /// thin air.
1112 SmallVector LibFunctions;
11011113
11021114 /// Helper to insert a new function, with an already looked-up entry in
11031115 /// the NodeMap.
12151227 ///
12161228 /// This just builds the set of entry points to the call graph. The rest is
12171229 /// built lazily as it is walked.
1218 LazyCallGraph run(Module &M, ModuleAnalysisManager &) {
1219 return LazyCallGraph(M);
1230 LazyCallGraph run(Module &M, ModuleAnalysisManager &AM) {
1231 return LazyCallGraph(M, AM.getResult(M));
12201232 }
12211233 };
12221234
432432 if (Visited.insert(C).second)
433433 Worklist.push_back(C);
434434
435 LazyCallGraph::visitReferences(Worklist, Visited, [&](Function &Referee) {
435 auto VisitRef = [&](Function &Referee) {
436436 Node &RefereeN = *G.lookup(Referee);
437437 Edge *E = N->lookup(RefereeN);
438438 // FIXME: Similarly to new calls, we also currently preclude
443443 RetainedEdges.insert(&RefereeN);
444444 if (E->isCall())
445445 DemotedCallTargets.insert(&RefereeN);
446 });
446 };
447 LazyCallGraph::visitReferences(Worklist, Visited, VisitRef);
448
449 // Include synthetic reference edges to known, defined lib functions.
450 for (auto *F : G.getLibFunctions())
451 VisitRef(*F);
447452
448453 // First remove all of the edges that are no longer present in this function.
449454 // We have to build a list of dead targets first and then remove them as the
105105 LazyCallGraph::Edge::Ref);
106106 });
107107
108 // Add implicit reference edges to any defined libcall functions (if we
109 // haven't found an explicit edge).
110 for (auto *F : G->LibFunctions)
111 if (!Visited.count(F))
112 addEdge(Edges->Edges, Edges->EdgeIndexMap, G->get(*F),
113 LazyCallGraph::Edge::Ref);
114
108115 return *Edges;
109116 }
110117
119126 }
120127 #endif
121128
122 LazyCallGraph::LazyCallGraph(Module &M) {
129 static bool isKnownLibFunction(Function &F, TargetLibraryInfo &TLI) {
130 LibFunc LF;
131
132 // Either this is a normal library function or a "vectorizable" function.
133 return TLI.getLibFunc(F, LF) || TLI.isFunctionVectorizable(F.getName());
134 }
135
136 LazyCallGraph::LazyCallGraph(Module &M, TargetLibraryInfo &TLI) {
123137 DEBUG(dbgs() << "Building CG for module: " << M.getModuleIdentifier()
124138 << "\n");
125 for (Function &F : M)
126 if (!F.isDeclaration() && !F.hasLocalLinkage()) {
127 DEBUG(dbgs() << " Adding '" << F.getName()
128 << "' to entry set of the graph.\n");
129 addEdge(EntryEdges.Edges, EntryEdges.EdgeIndexMap, get(F), Edge::Ref);
130 }
139 for (Function &F : M) {
140 if (F.isDeclaration())
141 continue;
142 // If this function is a known lib function to LLVM then we want to
143 // synthesize reference edges to it to model the fact that LLVM can turn
144 // arbitrary code into a library function call.
145 if (isKnownLibFunction(F, TLI))
146 LibFunctions.push_back(&F);
147
148 if (F.hasLocalLinkage())
149 continue;
150
151 // External linkage defined functions have edges to them from other
152 // modules.
153 DEBUG(dbgs() << " Adding '" << F.getName()
154 << "' to entry set of the graph.\n");
155 addEdge(EntryEdges.Edges, EntryEdges.EdgeIndexMap, get(F), Edge::Ref);
156 }
131157
132158 // Now add entry nodes for functions reachable via initializers to globals.
133159 SmallVector Worklist;
148174 LazyCallGraph::LazyCallGraph(LazyCallGraph &&G)
149175 : BPA(std::move(G.BPA)), NodeMap(std::move(G.NodeMap)),
150176 EntryEdges(std::move(G.EntryEdges)), SCCBPA(std::move(G.SCCBPA)),
151 SCCMap(std::move(G.SCCMap)), LeafRefSCCs(std::move(G.LeafRefSCCs)) {
177 SCCMap(std::move(G.SCCMap)), LeafRefSCCs(std::move(G.LeafRefSCCs)),
178 LibFunctions(std::move(G.LibFunctions)) {
152179 updateGraphPtrs();
153180 }
154181
159186 SCCBPA = std::move(G.SCCBPA);
160187 SCCMap = std::move(G.SCCMap);
161188 LeafRefSCCs = std::move(G.LeafRefSCCs);
189 LibFunctions = std::move(G.LibFunctions);
162190 updateGraphPtrs();
163191 return *this;
164192 }
0 ; Make sure that the CGSCC pass manager can handle when instcombine simplifies
1 ; one libcall into an unrelated libcall and update the call graph accordingly.
2 ;
3 ; RUN: opt -passes='cgscc(function(instcombine))' -S < %s | FileCheck %s
4
5 define i8* @wibble(i8* %arg1, i8* %arg2) {
6 ; CHECK-LABLE: define @wibble(
7 bb:
8 %tmp = alloca [1024 x i8], align 16
9 %tmp2 = getelementptr inbounds [1024 x i8], [1024 x i8]* %tmp, i64 0, i64 0
10 call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp2, i8* %arg1, i64 1024, i32 0, i1 false)
11 ; CHECK: call void @llvm.memcpy
12 %tmp3 = call i64 @llvm.objectsize.i64.p0i8(i8* %tmp2, i1 false, i1 true)
13 %tmp4 = call i8* @__strncpy_chk(i8* %arg2, i8* %tmp2, i64 1023, i64 %tmp3)
14 ; CHECK-NOT: call
15 ; CHECK: call i8* @strncpy(i8* %arg2, i8* %tmp2, i64 1023)
16 ; CHECK-NOT: call
17
18 ret i8* %tmp4
19 ; CHECK: ret
20 }
21
22 define i8* @strncpy(i8* %arg1, i8* %arg2, i64 %size) {
23 bb:
24 %result = call i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
25 ret i8* %result
26 }
27
28 declare i8* @my_special_strncpy(i8* %arg1, i8* %arg2, i64 %size)
29
30 declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1)
31
32 declare i8* @__strncpy_chk(i8*, i8*, i64, i64)
33
34 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture writeonly, i8* nocapture readonly, i64, i32, i1)
2222 ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(CGSCCAnalysisManager|AnalysisManager<.*LazyCallGraph::SCC.*>).*}},{{.*}}Module>
2323 ; CHECK-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
2424 ; CHECK-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
25 ; CHECK-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
2526 ; CHECK-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
2627 ; CHECK-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
2728 ; CHECK-CGSCC-PASS-NEXT: Running pass: NoOpCGSCCPass
406407 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(CGSCCAnalysisManager|AnalysisManager<.*LazyCallGraph::SCC.*>).*}},{{.*}}Module>
407408 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: InnerAnalysisManagerProxy<{{.*(FunctionAnalysisManager|AnalysisManager<.*Function.*>).*}},{{.*}}Module>
408409 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: LazyCallGraphAnalysis
410 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running analysis: TargetLibraryAnalysis
409411 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running an SCC pass across the RefSCC: [(foo)]
410412 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Starting CGSCC pass manager run
411413 ; CHECK-REPEAT-CGSCC-PASS-NEXT: Running pass: RepeatedPass
88
99 #include "llvm/Analysis/CGSCCPassManager.h"
1010 #include "llvm/Analysis/LazyCallGraph.h"
11 #include "llvm/Analysis/TargetLibraryInfo.h"
1112 #include "llvm/AsmParser/Parser.h"
1213 #include "llvm/IR/Function.h"
1314 #include "llvm/IR/InstIterator.h"
226227 "entry:\n"
227228 " ret void\n"
228229 "}\n")) {
230 MAM.registerPass([&] { return TargetLibraryAnalysis(); });
229231 MAM.registerPass([&] { return LazyCallGraphAnalysis(); });
230232 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
231233 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
215215 " ret void\n"
216216 "}\n";
217217
218 static LazyCallGraph buildCG(Module &M) {
219 TargetLibraryInfoImpl TLII(Triple(M.getTargetTriple()));
220 TargetLibraryInfo TLI(TLII);
221 LazyCallGraph CG(M, TLI);
222 return CG;
223 }
224
218225 TEST(LazyCallGraphTest, BasicGraphFormation) {
219226 LLVMContext Context;
220227 std::unique_ptr M = parseAssembly(Context, DiamondOfTriangles);
221 LazyCallGraph CG(*M);
228 LazyCallGraph CG = buildCG(*M);
222229
223230 // The order of the entry nodes should be stable w.r.t. the source order of
224231 // the IR, and everything in our module is an entry node, so just directly
406413 "entry:\n"
407414 " ret void\n"
408415 "}\n");
409 LazyCallGraph CG(*M);
416 LazyCallGraph CG = buildCG(*M);
410417
411418 LazyCallGraph::Node &A = CG.get(lookupFunction(*M, "a"));
412419 LazyCallGraph::Node &B = CG.get(lookupFunction(*M, "b"));
444451 TEST(LazyCallGraphTest, InnerSCCFormation) {
445452 LLVMContext Context;
446453 std::unique_ptr M = parseAssembly(Context, DiamondOfTriangles);
447 LazyCallGraph CG(*M);
454 LazyCallGraph CG = buildCG(*M);
448455
449456 // Now mutate the graph to connect every node into a single RefSCC to ensure
450457 // that our inner SCC formation handles the rest.
541548 " call void @f1()\n"
542549 " ret void\n"
543550 "}\n");
544 LazyCallGraph CG(*M);
551 LazyCallGraph CG = buildCG(*M);
545552
546553 // Force the graph to be fully expanded.
547554 CG.buildRefSCCs();
592599 "entry:\n"
593600 " ret void\n"
594601 "}\n");
595 LazyCallGraph CG(*M);
602 LazyCallGraph CG = buildCG(*M);
596603
597604 // Force the graph to be fully expanded.
598605 CG.buildRefSCCs();
738745 // a3--a2 |
739746 //
740747 std::unique_ptr M = parseAssembly(Context, DiamondOfTriangles);
741 LazyCallGraph CG(*M);
748 LazyCallGraph CG = buildCG(*M);
742749
743750 // Force the graph to be fully expanded.
744751 CG.buildRefSCCs();
830837 // references rather than calls.
831838 std::unique_ptr M =
832839 parseAssembly(Context, DiamondOfTrianglesRefGraph);
833 LazyCallGraph CG(*M);
840 LazyCallGraph CG = buildCG(*M);
834841
835842 // Force the graph to be fully expanded.
836843 CG.buildRefSCCs();
937944 "entry:\n"
938945 " ret void\n"
939946 "}\n");
940 LazyCallGraph CG(*M);
947 LazyCallGraph CG = buildCG(*M);
941948
942949 // Force the graph to be fully expanded.
943950 CG.buildRefSCCs();
10141021 "entry:\n"
10151022 " ret void\n"
10161023 "}\n");
1017 LazyCallGraph CG(*M);
1024 LazyCallGraph CG = buildCG(*M);
10181025
10191026 // Force the graph to be fully expanded.
10201027 CG.buildRefSCCs();
10761083 // a3--a2 |
10771084 //
10781085 std::unique_ptr M = parseAssembly(Context, DiamondOfTriangles);
1079 LazyCallGraph CG(*M);
1086 LazyCallGraph CG = buildCG(*M);
10801087
10811088 // Force the graph to be fully expanded.
10821089 CG.buildRefSCCs();
12201227 " call void @a()\n"
12211228 " ret void\n"
12221229 "}\n");
1223 LazyCallGraph CG(*M);
1230 LazyCallGraph CG = buildCG(*M);
12241231
12251232 // Force the graph to be fully expanded.
12261233 CG.buildRefSCCs();
13141321 " store i8* bitcast (void(i8**)* @c to i8*), i8** %ptr\n"
13151322 " ret void\n"
13161323 "}\n");
1317 LazyCallGraph CG(*M);
1324 LazyCallGraph CG = buildCG(*M);
13181325
13191326 // Force the graph to be fully expanded.
13201327 CG.buildRefSCCs();
13891396 " store i8* bitcast (void(i8**)* @b to i8*), i8** %ptr\n"
13901397 " ret void\n"
13911398 "}\n");
1392 LazyCallGraph CG(*M);
1399 LazyCallGraph CG = buildCG(*M);
13931400
13941401 // Force the graph to be fully expanded.
13951402 CG.buildRefSCCs();
14661473 " call void @c()\n"
14671474 " ret void\n"
14681475 "}\n");
1469 LazyCallGraph CG(*M);
1476 LazyCallGraph CG = buildCG(*M);
14701477
14711478 // Force the graph to be fully expanded.
14721479 CG.buildRefSCCs();
15591566 " store void()* @a, void()** undef\n"
15601567 " ret void\n"
15611568 "}\n");
1562 LazyCallGraph CG(*M);
1569 LazyCallGraph CG = buildCG(*M);
15631570
15641571 // Force the graph to be fully expanded.
15651572 CG.buildRefSCCs();
16711678 " store void()* @a, void()** undef\n"
16721679 " ret void\n"
16731680 "}\n");
1674 LazyCallGraph CG(*M);
1681 LazyCallGraph CG = buildCG(*M);
16751682
16761683 // Force the graph to be fully expanded.
16771684 CG.buildRefSCCs();
18011808 " store void()* @a, void()** undef\n"
18021809 " ret void\n"
18031810 "}\n");
1804 LazyCallGraph CG(*M);
1811 LazyCallGraph CG = buildCG(*M);
18051812
18061813 // Force the graph to be fully expanded.
18071814 CG.buildRefSCCs();
18841891 " store i8* blockaddress(@f, %bb), i8** %ptr\n"
18851892 " ret void\n"
18861893 "}\n");
1887 LazyCallGraph CG(*M);
1894 LazyCallGraph CG = buildCG(*M);
18881895
18891896 CG.buildRefSCCs();
18901897 auto I = CG.postorder_ref_scc_begin();
19321939 " store i8* bitcast (void(i8**)* @d to i8*), i8** %ptr\n"
19331940 " ret void\n"
19341941 "}\n");
1935 LazyCallGraph CG(*M);
1942 LazyCallGraph CG = buildCG(*M);
19361943
19371944 // Force the graph to be fully expanded.
19381945 CG.buildRefSCCs();
20102017 "entry:\n"
20112018 " ret void\n"
20122019 "}\n");
2013 LazyCallGraph CG(*M);
2020 LazyCallGraph CG = buildCG(*M);
20142021
20152022 // Insert spurious ref edges.
20162023 LazyCallGraph::Node &AN = CG.get(lookupFunction(*M, "a"));