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 return GV.getName().str() + ".__uniq" + getUniqueModuleId(&M);
46}
47
48/// Create a copy of the thinlto import, mark it local, and redirect direct
49/// calls to the copy. Only direct calls are replaced, so that e.g. indirect
50/// call function pointer tests would use the global identity of the function.
51///
52/// Currently, Value Profiling ("VP") MD_prof data isn't updated to refer to the
53/// clone's GUID (which will be different, because the name and linkage is
54/// different), under the assumption that the last consumer of this data is
55/// upstream the pipeline (e.g. ICP).
57 assert(F.hasAvailableExternallyLinkage());
58 assert(!F.isDeclaration());
59 // If we can't find a single use that's a call, just delete the function.
60 if (F.uses().end() == llvm::find_if(F.uses(), [&](Use &U) {
61 return isa<CallBase>(U.getUser());
62 }))
63 return deleteFunction(F);
64
65 auto OrigName = F.getName().str();
66 // Build a new name. We still need the old name (see below).
67 // We could just rely on internal linking allowing 2 modules have internal
68 // functions with the same name, but that just creates more trouble than
69 // necessary e.g. distinguishing profiles or debugging. Instead, we append the
70 // module identifier.
71 std::string NewName = getNewName(M, F);
72 F.setName(NewName);
73 if (auto *SP = F.getSubprogram())
74 SP->replaceLinkageName(MDString::get(F.getParent()->getContext(), NewName));
75
77 // Now make a declaration for the old name. We'll use it if there are non-call
78 // uses. For those, it would be incorrect to replace them with the local copy:
79 // for example, one such use could be taking the address of the function and
80 // passing it to an external function, which, in turn, might compare the
81 // function pointer to the original (non-local) function pointer, e.g. as part
82 // of indirect call promotion.
83 auto *Decl =
85 F.getAddressSpace(), OrigName, F.getParent());
86 F.replaceUsesWithIf(Decl,
87 [&](Use &U) { return !isa<CallBase>(U.getUser()); });
88 ++NumFunctionsConverted;
89}
90
91/// Similar to the function above, this is to convert an externally available
92/// global variable to local.
95 GV.setName(getNewName(M, GV));
97 ++NumGlobalVariablesConverted;
98}
99
100static bool eliminateAvailableExternally(Module &M, bool Convert) {
101 const IPOOptions &Opts = getIPOOptions(M);
102 bool Changed = false;
103
104 // If a global variable is available externally and in the specified address
105 // space, convert it to local linkage; otherwise, drop its initializer.
106 for (GlobalVariable &GV : M.globals()) {
107 if (!GV.hasAvailableExternallyLinkage())
108 continue;
109 if (GV.getAddressSpace() == Opts.avail_extern_gv_in_addrspace_to_local &&
110 !GV.use_empty()) {
111 convertToLocalCopy(M, GV);
112 Changed = true;
113 continue;
114 }
115 if (GV.hasInitializer()) {
116 Constant *Init = GV.getInitializer();
117 GV.setInitializer(nullptr);
119 Init->destroyConstant();
120 }
121 GV.removeDeadConstantUsers();
122 GV.setLinkage(GlobalValue::ExternalLinkage);
123 ++NumVariables;
124 Changed = true;
125 }
126
127 // Drop the bodies of available externally functions.
129 if (F.isDeclaration() || !F.hasAvailableExternallyLinkage())
130 continue;
131
132 if (Convert || Opts.avail_extern_to_local)
134 else
136
137 F.removeDeadConstantUsers();
138 Changed = true;
139 }
140
141 return Changed;
142}
143
146 auto *CtxProf = MAM.getCachedResult<CtxProfAnalysis>(M);
147 // Convert to local instead of eliding if we use contextual profiling in this
148 // module. This is because the IPO decisions performed with contextual
149 // information will likely differ from decisions made without. For a function
150 // that's imported, its optimizations will, thus, differ, and be specialized
151 // for this contextual information. Eliding it in favor of the original would
152 // undo these optimizations.
154 M, /*Convert=*/(CtxProf && CtxProf->isInSpecializedModule())))
155 return PreservedAnalyses::all();
157}
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:33
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