LLVM 24.0.0git
ElimAvailExtern.cpp
Go to the documentation of this file.
1//===- ElimAvailExtern.cpp - DCE unreachable internal functions -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
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
15#include "IPOOptions.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/ADT/Statistic.h"
19#include "llvm/IR/Constant.h"
21#include "llvm/IR/Function.h"
22#include "llvm/IR/GlobalValue.h"
24#include "llvm/IR/MDBuilder.h"
25#include "llvm/IR/Module.h"
28
29using namespace llvm;
30
31#define DEBUG_TYPE "elim-avail-extern"
32
33STATISTIC(NumRemovals, "Number of functions removed");
34STATISTIC(NumFunctionsConverted, "Number of functions converted");
35STATISTIC(NumGlobalVariablesConverted, "Number of global variables converted");
36STATISTIC(NumVariables, "Number of global variables removed");
37
39 // This will set the linkage to external
40 F.deleteBody();
41 ++NumRemovals;
42}
43
44static std::string getNewName(Module &M, const GlobalValue &GV) {
45 std::string Name = GV.getName().str() + ".__uniq";
46 std::string ModuleId = getUniqueModuleId(&M);
47 if (!ModuleId.empty())
48 Name += "." + ModuleId;
49 return Name;
50}
51
52/// Create a copy of the thinlto import, mark it local, and redirect direct
53/// calls to the copy. Only direct calls are replaced, so that e.g. indirect
54/// call function pointer tests would use the global identity of the function.
55///
56/// Currently, Value Profiling ("VP") MD_prof data isn't updated to refer to the
57/// clone's GUID (which will be different, because the name and linkage is
58/// different), under the assumption that the last consumer of this data is
59/// upstream the pipeline (e.g. ICP).
61 assert(F.hasAvailableExternallyLinkage());
62 assert(!F.isDeclaration());
63 // If we can't find a single use that's a call, just delete the function.
64 if (F.uses().end() == llvm::find_if(F.uses(), [&](Use &U) {
65 return isa<CallBase>(U.getUser());
66 }))
67 return deleteFunction(F);
68
69 auto OrigName = F.getName().str();
70 // Build a new name. We still need the old name (see below).
71 // We could just rely on internal linking allowing 2 modules have internal
72 // functions with the same name, but that just creates more trouble than
73 // necessary e.g. distinguishing profiles or debugging. Instead, we append the
74 // module identifier.
75 std::string NewName = getNewName(M, F);
76 F.setName(NewName);
77 if (auto *SP = F.getSubprogram())
78 SP->replaceLinkageName(MDString::get(F.getParent()->getContext(), NewName));
79
81 // Now make a declaration for the old name. We'll use it if there are non-call
82 // uses. For those, it would be incorrect to replace them with the local copy:
83 // for example, one such use could be taking the address of the function and
84 // passing it to an external function, which, in turn, might compare the
85 // function pointer to the original (non-local) function pointer, e.g. as part
86 // of indirect call promotion.
87 auto *Decl =
89 F.getAddressSpace(), OrigName, F.getParent());
90 F.replaceUsesWithIf(Decl,
91 [&](Use &U) { return !isa<CallBase>(U.getUser()); });
92 ++NumFunctionsConverted;
93}
94
95/// Similar to the function above, this is to convert an externally available
96/// global variable to local.
99 GV.setName(getNewName(M, GV));
101 ++NumGlobalVariablesConverted;
102}
103
104static bool eliminateAvailableExternally(Module &M, bool Convert) {
105 const IPOOptions &Opts = getIPOOptions(M);
106 bool Changed = false;
107
108 // If a global variable is available externally and in the specified address
109 // space, convert it to local linkage; otherwise, drop its initializer.
110 for (GlobalVariable &GV : M.globals()) {
111 if (!GV.hasAvailableExternallyLinkage())
112 continue;
113 if (GV.getAddressSpace() == Opts.avail_extern_gv_in_addrspace_to_local &&
114 !GV.use_empty()) {
115 convertToLocalCopy(M, GV);
116 Changed = true;
117 continue;
118 }
119 if (GV.hasInitializer()) {
120 Constant *Init = GV.getInitializer();
121 GV.setInitializer(nullptr);
123 Init->destroyConstant();
124 }
125 GV.removeDeadConstantUsers();
126 GV.setLinkage(GlobalValue::ExternalLinkage);
127 ++NumVariables;
128 Changed = true;
129 }
130
131 // Drop the bodies of available externally functions.
133 if (F.isDeclaration() || !F.hasAvailableExternallyLinkage())
134 continue;
135
136 if (Convert || Opts.avail_extern_to_local)
138 else
140
141 F.removeDeadConstantUsers();
142 Changed = true;
143 }
144
145 return Changed;
146}
147
150 auto *CtxProf = MAM.getCachedResult<CtxProfAnalysis>(M);
151 // Convert to local instead of eliding if we use contextual profiling in this
152 // module. This is because the IPO decisions performed with contextual
153 // information will likely differ from decisions made without. For a function
154 // that's imported, its optimizations will, thus, differ, and be specialized
155 // for this contextual information. Eliding it in favor of the original would
156 // undo these optimizations.
158 M, /*Convert=*/(CtxProf && CtxProf->isInSpecializedModule())))
159 return PreservedAnalyses::all();
161}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static std::string getNewName(Module &M, const GlobalValue &GV)
static void convertToLocalCopy(Module &M, Function &F)
Create a copy of the thinlto import, mark it local, and redirect direct calls to the copy.
void deleteFunction(Function &F)
static bool eliminateAvailableExternally(Module &M, bool Convert)
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
ModuleAnalysisManager MAM
This file contains some templates that are useful if you are working with the STL at all.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
This is an important base class in LLVM.
Definition Constant.h:44
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition Function.h:169
void setLinkage(LinkageTypes LT)
bool hasAvailableExternallyLinkage() const
@ InternalLinkage
Rename collisions when linking (static functions).
Definition GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:595
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:389
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
This is an optimization pass for GlobalISel generic memory operations.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
const IPOOptions & getIPOOptions(const LLVMContext &C)
Definition IPOOptions.h:36
LLVM_ABI bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39