llvm.org GIT mirror llvm / c3ce5d9
PM: Port Internalize to the new pass manager git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@267596 91177308-0d34-0410-b5e6-96231b3b80d8 Justin Bogner 3 years ago
8 changed file(s) with 149 addition(s) and 118 deletion(s). Raw diff Collapse all Expand all
153153 void initializeInstructionCombiningPassPass(PassRegistry&);
154154 void initializeInstCountPass(PassRegistry&);
155155 void initializeInstNamerPass(PassRegistry&);
156 void initializeInternalizePassPass(PassRegistry&);
156 void initializeInternalizeLegacyPassPass(PassRegistry&);
157157 void initializeIntervalPartitionPass(PassRegistry&);
158158 void initializeIRTranslatorPass(PassRegistry &);
159159 void initializeJumpThreadingPass(PassRegistry&);
55 // License. See LICENSE.TXT for details.
66 //
77 //===----------------------------------------------------------------------===//
8 //
9 // This pass loops over all of the functions and variables in the input module.
10 // If the function or variable does not need to be preserved according to the
11 // client supplied callback, it is marked as internal.
12 //
13 // This transformation would not be legal in a regular compilation, but it gets
14 // extra information from the linker about what is safe.
15 //
16 // For example: Internalizing a function with external linkage. Only if we are
17 // told it is only used from within this module, it is safe to do it.
18 //
19 //===----------------------------------------------------------------------===//
820
921 #ifndef LLVM_TRANSFORMS_IPO_INTERNALIZE_H
1022 #define LLVM_TRANSFORMS_IPO_INTERNALIZE_H
1123
24 #include "llvm/ADT/StringSet.h"
1225 #include "llvm/IR/GlobalValue.h"
13
26 #include "llvm/IR/PassManager.h"
1427 #include
28 #include
1529
1630 namespace llvm {
1731 class Module;
1832 class CallGraph;
1933
20 bool internalizeModule(
34 /// A pass that internalizes all functions and variables other than those that
35 /// must be preserved according to \c MustPreserveGV.
36 class InternalizePass : public PassInfoMixin {
37 /// Client supplied callback to control wheter a symbol must be preserved.
38 const std::function MustPreserveGV;
39 /// Set of symbols private to the compiler that this pass should not touch.
40 StringSet<> AlwaysPreserved;
41
42 /// Return false if we're allowed to internalize this GV.
43 bool shouldPreserveGV(const GlobalValue &GV);
44 /// Internalize GV if it is possible to do so, i.e. it is not externally
45 /// visible and is not a member of an externally visible comdat.
46 bool maybeInternalize(GlobalValue &GV,
47 const std::set &ExternalComdats);
48 /// If GV is part of a comdat and is externally visible, keep track of its
49 /// comdat so that we don't internalize any of its members.
50 void checkComdatVisibility(GlobalValue &GV,
51 std::set &ExternalComdats);
52
53 public:
54 InternalizePass();
55 InternalizePass(
56 const std::function MustPreserveGV)
57 : MustPreserveGV(std::move(MustPreserveGV)) {}
58
59 /// Run the internalizer on \p TheModule, returns true if any changes was
60 /// made.
61 ///
62 /// If the CallGraph \p CG is supplied, it will be updated when
63 /// internalizing a function (by removing any edge from the "external node")
64 bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr);
65
66 PreservedAnalyses run(Module &M, AnalysisManager &AM);
67 };
68
69 /// Helper function to internalize functions and variables in a Module.
70 inline bool internalizeModule(
2171 Module &TheModule,
22 const std::function &MustPreserveGV,
23 CallGraph *CG = nullptr);
72 const std::function MustPreserveGV,
73 CallGraph *CG = nullptr) {
74 return InternalizePass(std::move(MustPreserveGV))
75 .internalizeModule(TheModule, CG);
2476 }
77 } // end namespace llvm
2578
2679 #endif // LLVM_TRANSFORMS_IPO_INTERNALIZE_H
9595 void LTOCodeGenerator::initializeLTOPasses() {
9696 PassRegistry &R = *PassRegistry::getPassRegistry();
9797
98 initializeInternalizePassPass(R);
98 initializeInternalizeLegacyPassPass(R);
9999 initializeIPSCCPPass(R);
100100 initializeGlobalOptLegacyPassPass(R);
101101 initializeConstantMergePass(R);
4848 #include "llvm/Transforms/IPO/FunctionAttrs.h"
4949 #include "llvm/Transforms/IPO/GlobalOpt.h"
5050 #include "llvm/Transforms/IPO/InferFunctionAttrs.h"
51 #include "llvm/Transforms/IPO/Internalize.h"
5152 #include "llvm/Transforms/IPO/StripDeadPrototypes.h"
5253 #include "llvm/Transforms/InstCombine/InstCombine.h"
5354 #include "llvm/Transforms/InstrProfiling.h"
3737 MODULE_PASS("forceattrs", ForceFunctionAttrsPass())
3838 MODULE_PASS("globalopt", GlobalOptPass())
3939 MODULE_PASS("inferattrs", InferFunctionAttrsPass())
40 MODULE_PASS("internalize", InternalizePass())
4041 MODULE_PASS("instrprof", InstrProfiling())
4142 MODULE_PASS("invalidate", InvalidateAllAnalysesPass())
4243 MODULE_PASS("no-op-module", NoOpModulePass())
3434 initializeAlwaysInlinerPass(Registry);
3535 initializeSimpleInlinerPass(Registry);
3636 initializeInferFunctionAttrsLegacyPassPass(Registry);
37 initializeInternalizePassPass(Registry);
37 initializeInternalizeLegacyPassPass(Registry);
3838 initializeLoopExtractorPass(Registry);
3939 initializeBlockExtractorPassPass(Registry);
4040 initializeSingleLoopExtractorPass(Registry);
77 //===----------------------------------------------------------------------===//
88 //
99 // This pass loops over all of the functions and variables in the input module.
10 // If the function or variable is not in the list of external names given to
11 // the pass it is marked as internal.
10 // If the function or variable does not need to be preserved according to the
11 // client supplied callback, it is marked as internal.
1212 //
1313 // This transformation would not be legal in a regular compilation, but it gets
1414 // extra information from the linker about what is safe.
1919 //===----------------------------------------------------------------------===//
2020
2121 #include "llvm/Transforms/IPO/Internalize.h"
22 #include "llvm/Transforms/IPO.h"
2322 #include "llvm/ADT/SmallPtrSet.h"
2423 #include "llvm/ADT/Statistic.h"
2524 #include "llvm/ADT/StringSet.h"
2928 #include "llvm/Support/CommandLine.h"
3029 #include "llvm/Support/Debug.h"
3130 #include "llvm/Support/raw_ostream.h"
31 #include "llvm/Transforms/IPO.h"
3232 #include "llvm/Transforms/Utils/GlobalStatus.h"
3333 #include
3434 #include
5252 cl::desc("A list of symbol names to preserve"), cl::CommaSeparated);
5353
5454 namespace {
55
5655 // Helper to load an API list to preserve from file and expose it as a functor
5756 // for internalization.
5857 class PreserveAPIList {
8786 }
8887 }
8988 };
90
91 // Internalization exposed as a pass
92 class InternalizePass : public ModulePass {
93 // Client supplied callback to control wheter a symbol must be preserved.
94 std::function MustPreserveGV;
95
96 public:
97 static char ID; // Pass identification, replacement for typeid
98
99 InternalizePass() : ModulePass(ID), MustPreserveGV(PreserveAPIList()) {}
100
101 InternalizePass(std::function MustPreserveGV)
102 : ModulePass(ID), MustPreserveGV(std::move(MustPreserveGV)) {
103 initializeInternalizePassPass(*PassRegistry::getPassRegistry());
104 }
105
106 bool runOnModule(Module &M) override {
107 if (skipModule(M))
108 return false;
109
110 CallGraphWrapperPass *CGPass =
111 getAnalysisIfAvailable();
112 CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr;
113 return internalizeModule(M, MustPreserveGV, CG);
114 }
115
116 void getAnalysisUsage(AnalysisUsage &AU) const override {
117 AU.setPreservesCFG();
118 AU.addPreserved();
119 }
120 };
121
122 // Helper class to perform internalization.
123 class Internalizer {
124 // Client supplied callback to control wheter a symbol must be preserved.
125 const std::function &MustPreserveGV;
126
127 // Set of symbols private to the compiler that this pass should not touch.
128 StringSet<> AlwaysPreserved;
129
130 // Return false if we're allowed to internalize this GV.
131 bool ShouldPreserveGV(const GlobalValue &GV) {
132 // Function must be defined here
133 if (GV.isDeclaration())
134 return true;
135
136 // Available externally is really just a "declaration with a body".
137 if (GV.hasAvailableExternallyLinkage())
138 return true;
139
140 // Assume that dllexported symbols are referenced elsewhere
141 if (GV.hasDLLExportStorageClass())
142 return true;
143
144 // Already local, has nothing to do.
145 if (GV.hasLocalLinkage())
146 return false;
147
148 // Check some special cases
149 if (AlwaysPreserved.count(GV.getName()))
150 return true;
151
152 return MustPreserveGV(GV);
153 }
154
155 bool maybeInternalize(GlobalValue &GV,
156 const std::set &ExternalComdats);
157 void checkComdatVisibility(GlobalValue &GV,
158 std::set &ExternalComdats);
159
160 public:
161 Internalizer(const std::function &MustPreserveGV)
162 : MustPreserveGV(MustPreserveGV) {}
163
164 /// Run the internalizer on \p TheModule, returns true if any changes was
165 /// made.
166 ///
167 /// If the CallGraph \p CG is supplied, it will be updated when
168 /// internalizing a function (by removing any edge from the "external node")
169 bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr);
170 };
171
172 // Internalize GV if it is possible to do so, i.e. it is not externally visible
173 // and is not a member of an externally visible comdat.
174 bool Internalizer::maybeInternalize(
89 } // end anonymous namespace
90
91 bool InternalizePass::shouldPreserveGV(const GlobalValue &GV) {
92 // Function must be defined here
93 if (GV.isDeclaration())
94 return true;
95
96 // Available externally is really just a "declaration with a body".
97 if (GV.hasAvailableExternallyLinkage())
98 return true;
99
100 // Assume that dllexported symbols are referenced elsewhere
101 if (GV.hasDLLExportStorageClass())
102 return true;
103
104 // Already local, has nothing to do.
105 if (GV.hasLocalLinkage())
106 return false;
107
108 // Check some special cases
109 if (AlwaysPreserved.count(GV.getName()))
110 return true;
111
112 return MustPreserveGV(GV);
113 }
114
115 bool InternalizePass::maybeInternalize(
175116 GlobalValue &GV, const std::set &ExternalComdats) {
176117 if (Comdat *C = GV.getComdat()) {
177118 if (ExternalComdats.count(C))
187128 if (GV.hasLocalLinkage())
188129 return false;
189130
190 if (ShouldPreserveGV(GV))
131 if (shouldPreserveGV(GV))
191132 return false;
192133 }
193134
198139
199140 // If GV is part of a comdat and is externally visible, keep track of its
200141 // comdat so that we don't internalize any of its members.
201 void Internalizer::checkComdatVisibility(
142 void InternalizePass::checkComdatVisibility(
202143 GlobalValue &GV, std::set &ExternalComdats) {
203144 Comdat *C = GV.getComdat();
204145 if (!C)
205146 return;
206147
207 if (ShouldPreserveGV(GV))
148 if (shouldPreserveGV(GV))
208149 ExternalComdats.insert(C);
209150 }
210151
211 bool Internalizer::internalizeModule(Module &M, CallGraph *CG) {
152 bool InternalizePass::internalizeModule(Module &M, CallGraph *CG) {
212153 bool Changed = false;
213154 CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : nullptr;
214155
295236 return Changed;
296237 }
297238
298 } // end anonymous namespace
299
300 char InternalizePass::ID = 0;
301 INITIALIZE_PASS(InternalizePass, "internalize", "Internalize Global Symbols",
302 false, false)
303
304 /// Public API below
305
306 bool llvm::internalizeModule(
307 Module &TheModule,
308 const std::function &MustPreserveGV,
309 CallGraph *CG) {
310 return Internalizer(MustPreserveGV).internalizeModule(TheModule, CG);
311 }
312
313 ModulePass *llvm::createInternalizePass() { return new InternalizePass(); }
239 InternalizePass::InternalizePass() : MustPreserveGV(PreserveAPIList()) {}
240
241 PreservedAnalyses InternalizePass::run(Module &M, AnalysisManager &AM) {
242 if (!internalizeModule(M, AM.getCachedResult(M)))
243 return PreservedAnalyses::all();
244
245 PreservedAnalyses PA;
246 PA.preserve();
247 return PA;
248 }
249
250 namespace {
251 class InternalizeLegacyPass : public ModulePass {
252 // Client supplied callback to control wheter a symbol must be preserved.
253 std::function MustPreserveGV;
254
255 public:
256 static char ID; // Pass identification, replacement for typeid
257
258 InternalizeLegacyPass() : ModulePass(ID), MustPreserveGV(PreserveAPIList()) {}
259
260 InternalizeLegacyPass(std::function MustPreserveGV)
261 : ModulePass(ID), MustPreserveGV(std::move(MustPreserveGV)) {
262 initializeInternalizeLegacyPassPass(*PassRegistry::getPassRegistry());
263 }
264
265 bool runOnModule(Module &M) override {
266 if (skipModule(M))
267 return false;
268
269 CallGraphWrapperPass *CGPass =
270 getAnalysisIfAvailable();
271 CallGraph *CG = CGPass ? &CGPass->getCallGraph() : nullptr;
272 return internalizeModule(M, MustPreserveGV, CG);
273 }
274
275 void getAnalysisUsage(AnalysisUsage &AU) const override {
276 AU.setPreservesCFG();
277 AU.addPreserved();
278 }
279 };
280 }
281
282 char InternalizeLegacyPass::ID = 0;
283 INITIALIZE_PASS(InternalizeLegacyPass, "internalize",
284 "Internalize Global Symbols", false, false)
285
286 ModulePass *llvm::createInternalizePass() {
287 return new InternalizeLegacyPass();
288 }
314289
315290 ModulePass *llvm::createInternalizePass(
316291 std::function MustPreserveGV) {
317 return new InternalizePass(std::move(MustPreserveGV));
318 }
292 return new InternalizeLegacyPass(std::move(MustPreserveGV));
293 }
0 ; RUN: opt < %s -internalize -S | FileCheck %s
1 ; RUN: opt < %s -passes=internalize -S | FileCheck %s
12
23 @llvm.used = appending global [1 x void ()*] [void ()* @f], section "llvm.metadata"
34