llvm.org GIT mirror llvm / b78ea51
Add new EliminateAvailableExternally module pass, which is performed in O2 compiles just before GlobalDCE, unless we are preparing for LTO. This pass eliminates available externally globals (turning them into declarations), regardless of whether they are dead/unreferenced, since we are guaranteed to have a copy available elsewhere at link time. This enables additional opportunities for GlobalDCE. If we are preparing for LTO (e.g. a -flto -c compile), the pass is not included as we want to preserve available externally functions for possible link time inlining. The FE indicates whether we are doing an -flto compile via the new PrepareForLTO flag on the PassManagerBuilder. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239480 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 4 years ago
6 changed file(s) with 117 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
129129 void initializeDataFlowSanitizerPass(PassRegistry&);
130130 void initializeScalarizerPass(PassRegistry&);
131131 void initializeEarlyCSELegacyPassPass(PassRegistry &);
132 void initializeEliminateAvailableExternallyPass(PassRegistry&);
132133 void initializeExpandISelPseudosPass(PassRegistry&);
133134 void initializeFunctionAttrsPass(PassRegistry&);
134135 void initializeGCMachineCodeAnalysisPass(PassRegistry&);
120120 bool VerifyInput;
121121 bool VerifyOutput;
122122 bool MergeFunctions;
123 bool PrepareForLTO;
123124
124125 private:
125126 /// ExtensionList - This is list of all of the extensions that are registered.
7070 ModulePass *createGlobalDCEPass();
7171
7272 //===----------------------------------------------------------------------===//
73 /// This transform is designed to eliminate available external globals
74 /// (functions or global variables)
75 ///
76 ModulePass *createEliminateAvailableExternallyPass();
77
78 //===----------------------------------------------------------------------===//
7379 /// createGVExtractionPass - If deleteFn is true, this pass deletes
7480 /// the specified global values. Otherwise, it deletes as much of the module as
7581 /// possible, except for the global values specified.
22 BarrierNoopPass.cpp
33 ConstantMerge.cpp
44 DeadArgumentElimination.cpp
5 ElimAvailExtern.cpp
56 ExtractGV.cpp
67 FunctionAttrs.cpp
78 GlobalDCE.cpp
0 //===-- ElimAvailExtern.cpp - DCE unreachable internal functions ----------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This transform is designed to eliminate available external global
10 // definitions from the program, turning them into declarations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Transforms/IPO.h"
15 #include "llvm/ADT/Statistic.h"
16 #include "llvm/IR/Constants.h"
17 #include "llvm/IR/Instructions.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/Transforms/Utils/CtorUtils.h"
20 #include "llvm/Transforms/Utils/GlobalStatus.h"
21 #include "llvm/Pass.h"
22 using namespace llvm;
23
24 #define DEBUG_TYPE "elim-avail-extern"
25
26 STATISTIC(NumAliases , "Number of global aliases removed");
27 STATISTIC(NumFunctions, "Number of functions removed");
28 STATISTIC(NumVariables, "Number of global variables removed");
29
30 namespace {
31 struct EliminateAvailableExternally : public ModulePass {
32 static char ID; // Pass identification, replacement for typeid
33 EliminateAvailableExternally() : ModulePass(ID) {
34 initializeEliminateAvailableExternallyPass(
35 *PassRegistry::getPassRegistry());
36 }
37
38 // run - Do the EliminateAvailableExternally pass on the specified module,
39 // optionally updating the specified callgraph to reflect the changes.
40 //
41 bool runOnModule(Module &M) override;
42 };
43 }
44
45 char EliminateAvailableExternally::ID = 0;
46 INITIALIZE_PASS(EliminateAvailableExternally, "elim-avail-extern",
47 "Eliminate Available Externally Globals", false, false)
48
49 ModulePass *llvm::createEliminateAvailableExternallyPass() {
50 return new EliminateAvailableExternally();
51 }
52
53 bool EliminateAvailableExternally::runOnModule(Module &M) {
54 bool Changed = false;
55
56 // Drop initializers of available externally global variables.
57 for (Module::global_iterator I = M.global_begin(), E = M.global_end();
58 I != E; ++I) {
59 if (!I->hasAvailableExternallyLinkage())
60 continue;
61 if (I->hasInitializer()) {
62 Constant *Init = I->getInitializer();
63 I->setInitializer(nullptr);
64 if (isSafeToDestroyConstant(Init))
65 Init->destroyConstant();
66 }
67 I->removeDeadConstantUsers();
68 I->setLinkage(GlobalValue::ExternalLinkage);
69 NumVariables++;
70 }
71
72 // Drop the bodies of available externally functions.
73 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
74 if (!I->hasAvailableExternallyLinkage())
75 continue;
76 if (!I->isDeclaration())
77 // This will set the linkage to external
78 I->deleteBody();
79 I->removeDeadConstantUsers();
80 NumFunctions++;
81 }
82
83 // Drop targets of available externally aliases.
84 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E;
85 ++I) {
86 if (!I->hasAvailableExternallyLinkage())
87 continue;
88 I->setAliasee(nullptr);
89 I->removeDeadConstantUsers();
90 I->setLinkage(GlobalValue::ExternalLinkage);
91 NumAliases++;
92 }
93
94 return Changed;
95 }
104104 VerifyInput = false;
105105 VerifyOutput = false;
106106 MergeFunctions = false;
107 PrepareForLTO = false;
107108 }
108109
109110 PassManagerBuilder::~PassManagerBuilder() {
400401 // GlobalOpt already deletes dead functions and globals, at -O2 try a
401402 // late pass of GlobalDCE. It is capable of deleting dead cycles.
402403 if (OptLevel > 1) {
404 if (!PrepareForLTO) {
405 // Remove avail extern fns and globals definitions if we aren't
406 // compiling an object file for later LTO. For LTO we want to preserve
407 // these so they are eligible for inlining at link-time. Note if they
408 // are unreferenced they will be removed by GlobalDCE below, so
409 // this only impacts referenced available externally globals.
410 // Eventually they will be suppressed during codegen, but eliminating
411 // here enables more opportunity for GlobalDCE as it may make
412 // globals referenced by available external functions dead.
413 MPM.add(createEliminateAvailableExternallyPass());
414 }
403415 MPM.add(createGlobalDCEPass()); // Remove dead fns and globals.
404416 MPM.add(createConstantMergePass()); // Merge dup global constants
405417 }