LLVM 24.0.0git
GlobalDCE.cpp
Go to the documentation of this file.
1//===-- GlobalDCE.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 unreachable internal globals from the
10// program. It uses an aggressive algorithm, searching out globals that are
11// known to be alive. After it finds all of the globals which are needed, it
12// deletes whatever is left over. This allows it to delete recursive chunks of
13// the program which are unreachable.
14//
15//===----------------------------------------------------------------------===//
16
18#include "IPOOptions.h"
19#include "llvm/ADT/DenseSet.h"
21#include "llvm/ADT/Statistic.h"
25#include "llvm/IR/Module.h"
27#include "llvm/Pass.h"
28#include "llvm/Transforms/IPO.h"
31
32using namespace llvm;
33
34#define DEBUG_TYPE "globaldce"
35
36namespace {
37class GlobalDCELegacyPass : public ModulePass {
38public:
39 static char ID; // Pass identification, replacement for typeid
40 GlobalDCELegacyPass() : ModulePass(ID) {}
41 bool runOnModule(Module &M) override {
42 if (skipModule(M))
43 return false;
44 // Note: GlobalDCEPass does not use any analyses, so we're safe to call the
45 // new-pm style pass with a default-initialized analysis manager here
47 auto PA = Impl.run(M, MAM);
48 return !PA.areAllPreserved();
49 }
50
51private:
52 GlobalDCEPass Impl;
53};
54} // namespace
55
56char GlobalDCELegacyPass::ID = 0;
57INITIALIZE_PASS(GlobalDCELegacyPass, "globaldce", "Dead Global Elimination",
58 false, false)
59
60// Public interface to the GlobalDCEPass.
61ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCELegacyPass(); }
62
63STATISTIC(NumAliases , "Number of global aliases removed");
64STATISTIC(NumFunctions, "Number of functions removed");
65STATISTIC(NumIFuncs, "Number of indirect functions removed");
66STATISTIC(NumVariables, "Number of global variables removed");
67STATISTIC(NumVFuncs, "Number of virtual functions removed");
68
69/// Returns true if F is effectively empty.
70static bool isEmptyFunction(Function *F) {
71 // Skip external functions.
72 if (F->isDeclaration())
73 return false;
74 BasicBlock &Entry = F->getEntryBlock();
75 for (auto &I : Entry) {
77 continue;
78 if (auto *RI = dyn_cast<ReturnInst>(&I))
79 return !RI->getReturnValue();
80 break;
81 }
82 return false;
83}
84
85/// Compute the set of GlobalValue that depends from V.
86/// The recursion stops as soon as a GlobalValue is met.
87void GlobalDCEPass::ComputeDependencies(Value *V,
89 if (auto *I = dyn_cast<Instruction>(V)) {
90 Function *Parent = I->getParent()->getParent();
91 Deps.insert(Parent);
92 } else if (auto *GV = dyn_cast<GlobalValue>(V)) {
93 Deps.insert(GV);
94 } else if (auto *CE = dyn_cast<Constant>(V)) {
95 // Avoid walking the whole tree of a big ConstantExprs multiple times.
96 auto Where = ConstantDependenciesCache.find(CE);
97 if (Where == ConstantDependenciesCache.end()) {
98 // Compute into a local set first: the recursion can insert into the
99 // cache, which would invalidate references into it.
100 SmallPtrSet<GlobalValue *, 8> LocalDeps;
101 for (User *CEUser : CE->users())
102 ComputeDependencies(CEUser, LocalDeps);
103 Where =
104 ConstantDependenciesCache.try_emplace(CE, std::move(LocalDeps)).first;
105 }
106 Deps.insert_range(Where->second);
107 }
108}
109
110void GlobalDCEPass::UpdateGVDependencies(GlobalValue &GV) {
111 SmallPtrSet<GlobalValue *, 8> Deps;
112 for (User *User : GV.users())
113 ComputeDependencies(User, Deps);
114 Deps.erase(&GV); // Remove self-reference.
115 for (GlobalValue *GVU : Deps) {
116 // If this is a dep from a vtable to a virtual function, and we have
117 // complete information about all virtual call sites which could call
118 // though this vtable, then skip it, because the call site information will
119 // be more precise.
120 if (VFESafeVTables.count(GVU) && isa<Function>(&GV)) {
121 LLVM_DEBUG(dbgs() << "Ignoring dep " << GVU->getName() << " -> "
122 << GV.getName() << "\n");
123 continue;
124 }
125 GVDependencies[GVU].insert(&GV);
126 }
127}
128
129/// Mark Global value as Live
130void GlobalDCEPass::MarkLive(GlobalValue &GV,
132 auto const Ret = AliveGlobals.insert(&GV);
133 if (!Ret.second)
134 return;
135
136 if (Updates)
137 Updates->push_back(&GV);
138 if (Comdat *C = GV.getComdat()) {
139 for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {
140 MarkLive(*CM.second, Updates); // Recursion depth is only two because only
141 // globals in the same comdat are visited.
142 }
143 }
144}
145
146void GlobalDCEPass::ScanVTables(Module &M) {
148 LLVM_DEBUG(dbgs() << "Building type info -> vtable map\n");
149
150 for (GlobalVariable &GV : M.globals()) {
151 Types.clear();
152 GV.getMetadata(LLVMContext::MD_type, Types);
153 if (GV.isDeclaration() || Types.empty())
154 continue;
155
156 // Use the typeid metadata on the vtable to build a mapping from typeids to
157 // the list of (GV, offset) pairs which are the possible vtables for that
158 // typeid.
159 for (MDNode *Type : Types) {
160 Metadata *TypeID = Type->getOperand(1).get();
161
164 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
165 ->getZExtValue();
166
167 TypeIdMap[TypeID].insert(std::make_pair(&GV, Offset));
168 }
169
170 // If the type corresponding to the vtable is private to this translation
171 // unit, we know that we can see all virtual functions which might use it,
172 // so VFE is safe.
173 GlobalObject::VCallVisibility TypeVis = GV.getVCallVisibility();
175 (InLTOPostLink &&
177 LLVM_DEBUG(dbgs() << GV.getName() << " is safe for VFE\n");
178 VFESafeVTables.insert(&GV);
179 }
180 }
181}
182
183void GlobalDCEPass::ScanVTableLoad(Function *Caller, Metadata *TypeId,
184 uint64_t CallOffset) {
185 for (const auto &VTableInfo : TypeIdMap[TypeId]) {
186 GlobalVariable *VTable = VTableInfo.first;
187 uint64_t VTableOffset = VTableInfo.second;
188
189 Constant *Ptr =
190 getPointerAtOffset(VTable->getInitializer(), VTableOffset + CallOffset,
191 *Caller->getParent(), VTable);
192 if (!Ptr) {
193 LLVM_DEBUG(dbgs() << "can't find pointer in vtable!\n");
194 VFESafeVTables.erase(VTable);
195 continue;
196 }
197
199 if (!Callee) {
200 LLVM_DEBUG(dbgs() << "vtable entry is not function pointer!\n");
201 VFESafeVTables.erase(VTable);
202 continue;
203 }
204
205 LLVM_DEBUG(dbgs() << "vfunc dep " << Caller->getName() << " -> "
206 << Callee->getName() << "\n");
207 VFuncDependencies[Caller].insert({VTable, Callee});
208 }
209}
210
211void GlobalDCEPass::ScanTypeCheckedLoadIntrinsics(Module &M) {
212 LLVM_DEBUG(dbgs() << "Scanning type.checked.load intrinsics\n");
213 Function *TypeCheckedLoadFunc =
214 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_checked_load);
215 Function *TypeCheckedLoadRelativeFunc = Intrinsic::getDeclarationIfExists(
216 &M, Intrinsic::type_checked_load_relative);
217
218 // Keep track of which (function, type id, offset) triples we've already
219 // scanned, to prevent repeated work.
220 DenseSet<std::tuple<Function *, Metadata *, uint64_t>> ScannedLoads;
221
222 auto scan = [&](Function *CheckedLoadFunc) {
223 if (!CheckedLoadFunc)
224 return;
225
226 for (auto *U : CheckedLoadFunc->users()) {
227 auto CI = dyn_cast<CallInst>(U);
228 if (!CI)
229 continue;
230
231 auto *Offset = dyn_cast<ConstantInt>(CI->getArgOperand(1));
232 Value *TypeIdValue = CI->getArgOperand(2);
233 auto *TypeId = cast<MetadataAsValue>(TypeIdValue)->getMetadata();
234
235 if (Offset) {
236 if (ScannedLoads
237 .insert({CI->getFunction(), TypeId, Offset->getZExtValue()})
238 .second)
239 ScanVTableLoad(CI->getFunction(), TypeId, Offset->getZExtValue());
240 } else {
241 // type.checked.load with a non-constant offset, so assume every entry
242 // in every matching vtable is used.
243 for (const auto &VTableInfo : TypeIdMap[TypeId]) {
244 VFESafeVTables.erase(VTableInfo.first);
245 }
246 }
247 }
248 };
249
250 scan(TypeCheckedLoadFunc);
251 scan(TypeCheckedLoadRelativeFunc);
252}
253
254void GlobalDCEPass::AddVirtualFunctionDependencies(Module &M) {
255 if (!getIPOOptions(M).enable_vfe)
256 return;
257
258 // If the Virtual Function Elim module flag is present and set to zero, then
259 // the vcall_visibility metadata was inserted for another optimization (WPD)
260 // and we may not have type checked loads on all accesses to the vtable.
261 // Don't attempt VFE in that case.
263 M.getModuleFlag("Virtual Function Elim"));
264 if (!Val || Val->isZero())
265 return;
266
267 ScanVTables(M);
268
269 if (VFESafeVTables.empty())
270 return;
271
272 ScanTypeCheckedLoadIntrinsics(M);
273
275 dbgs() << "VFE safe vtables:\n";
276 for (auto *VTable : VFESafeVTables)
277 dbgs() << " " << VTable->getName() << "\n";
278 );
279}
280
282 bool Changed = false;
283
284 // The algorithm first computes the set L of global variables that are
285 // trivially live.
286 //
287 // Then it walks the initialization of these variables to compute the globals
288 // used to initialize them, which effectively builds a directed graph where
289 // nodes are global variables, and an edge from A to B means B is used to
290 // initialize A.
291 //
292 // Finally, it propagates the liveness information through the graph starting
293 // from the nodes in L. A virtual call only keeps a virtual function alive
294 // when its vtable is also live.
295 //
296 // Nodes not marked as alive are discarded.
297
298 // Remove empty functions from the global ctors list.
300 M, [](uint32_t, Function *F) { return isEmptyFunction(F); });
301
302 // Collect the set of members for each comdat.
303 for (Function &F : M)
304 if (Comdat *C = F.getComdat())
305 ComdatMembers.insert(std::make_pair(C, &F));
306 for (GlobalVariable &GV : M.globals())
307 if (Comdat *C = GV.getComdat())
308 ComdatMembers.insert(std::make_pair(C, &GV));
309 for (GlobalAlias &GA : M.aliases())
310 if (Comdat *C = GA.getComdat())
311 ComdatMembers.insert(std::make_pair(C, &GA));
312
313 // Add dependencies between virtual call sites and the virtual functions they
314 // might call, if we have that information.
315 AddVirtualFunctionDependencies(M);
316
317 // Loop over the module, adding globals which are obviously necessary.
318 for (GlobalObject &GO : M.global_objects()) {
319 GO.removeDeadConstantUsers();
320 // Functions with external linkage are needed if they have a body.
321 // Externally visible & appending globals are needed, if they have an
322 // initializer.
323 if (!GO.isDeclaration())
324 if (!GO.isDiscardableIfUnused())
325 MarkLive(GO);
326
327 UpdateGVDependencies(GO);
328 }
329
330 // Compute direct dependencies of aliases.
331 for (GlobalAlias &GA : M.aliases()) {
332 GA.removeDeadConstantUsers();
333 // Externally visible aliases are needed.
334 if (!GA.isDiscardableIfUnused())
335 MarkLive(GA);
336
337 UpdateGVDependencies(GA);
338 }
339
340 // Compute direct dependencies of ifuncs.
341 for (GlobalIFunc &GIF : M.ifuncs()) {
342 GIF.removeDeadConstantUsers();
343 // Externally visible ifuncs are needed.
344 if (!GIF.isDiscardableIfUnused())
345 MarkLive(GIF);
346
347 UpdateGVDependencies(GIF);
348 }
349
350 // Propagate liveness from collected Global Values through the computed
351 // dependencies.
352 SmallVector<GlobalValue *, 8> NewLiveGVs{AliveGlobals.begin(),
353 AliveGlobals.end()};
354 while (!NewLiveGVs.empty()) {
355 GlobalValue *LGV = NewLiveGVs.pop_back_val();
356 for (auto *GVD : GVDependencies[LGV])
357 MarkLive(*GVD, &NewLiveGVs);
358
359 // A virtual call keeps a virtual function alive only if the vtable it is
360 // loaded from is alive too. If the vtable is not live, defer the function:
361 // the vtable may become live later.
362 if (auto *F = dyn_cast<Function>(LGV)) {
363 if (auto It = VFuncDependencies.find(F); It != VFuncDependencies.end()) {
364 for (auto [VTable, VFunc] : It->second) {
365 if (AliveGlobals.contains(VTable))
366 MarkLive(*VFunc, &NewLiveGVs);
367 else
368 PendingVFuncs[VTable].push_back(VFunc);
369 }
370 }
371 }
372
373 // If LGV is a vtable that became alive later, mark its deferred functions
374 // live.
375 if (auto *VT = dyn_cast<GlobalVariable>(LGV)) {
376 if (auto It = PendingVFuncs.find(VT); It != PendingVFuncs.end()) {
377 for (auto *VFunc : It->second)
378 MarkLive(*VFunc, &NewLiveGVs);
379 }
380 }
381 }
382
383 // Now that all globals which are needed are in the AliveGlobals set, we loop
384 // through the program, deleting those which are not alive.
385 //
386
387 // The first pass is to drop initializers of global variables which are dead.
388 std::vector<GlobalVariable *> DeadGlobalVars; // Keep track of dead globals
389 for (GlobalVariable &GV : M.globals())
390 if (!AliveGlobals.count(&GV)) {
391 DeadGlobalVars.push_back(&GV); // Keep track of dead globals
392 if (GV.hasInitializer()) {
393 Constant *Init = GV.getInitializer();
394 GV.setInitializer(nullptr);
396 Init->destroyConstant();
397 }
398 }
399
400 // The second pass drops the bodies of functions which are dead...
401 std::vector<Function *> DeadFunctions;
402 for (Function &F : M)
403 if (!AliveGlobals.count(&F)) {
404 DeadFunctions.push_back(&F); // Keep track of dead globals
405 if (!F.isDeclaration())
406 F.deleteBody();
407 }
408
409 // The third pass drops targets of aliases which are dead...
410 std::vector<GlobalAlias*> DeadAliases;
411 for (GlobalAlias &GA : M.aliases())
412 if (!AliveGlobals.count(&GA)) {
413 DeadAliases.push_back(&GA);
414 GA.setAliasee(nullptr);
415 }
416
417 // The fourth pass drops targets of ifuncs which are dead...
418 std::vector<GlobalIFunc*> DeadIFuncs;
419 for (GlobalIFunc &GIF : M.ifuncs())
420 if (!AliveGlobals.count(&GIF)) {
421 DeadIFuncs.push_back(&GIF);
422 GIF.setResolver(nullptr);
423 }
424
425 // Now that all interferences have been dropped, delete the actual objects
426 // themselves.
427 auto EraseUnusedGlobalValue = [&](GlobalValue *GV) {
429 GV->eraseFromParent();
430 Changed = true;
431 };
432
433 NumFunctions += DeadFunctions.size();
434 for (Function *F : DeadFunctions) {
435 if (!F->use_empty()) {
436 // Virtual functions might still be referenced by one or more vtables,
437 // but if we've proven them to be unused then it's safe to replace the
438 // virtual function pointers with null, allowing us to remove the
439 // function itself.
440 ++NumVFuncs;
441
442 // Detect vfuncs that are referenced as "relative pointers" which are used
443 // in Swift vtables, i.e. entries in the form of:
444 //
445 // i32 trunc (i64 sub (i64 ptrtoint @f, i64 ptrtoint ...)) to i32)
446 //
447 // In this case, replace the whole "sub" expression with constant 0 to
448 // avoid leaving a weird sub(0, symbol) expression behind.
450
451 F->replaceNonMetadataUsesWith(ConstantPointerNull::get(F->getType()));
452 }
453 EraseUnusedGlobalValue(F);
454 }
455
456 NumVariables += DeadGlobalVars.size();
457 for (GlobalVariable *GV : DeadGlobalVars)
458 EraseUnusedGlobalValue(GV);
459
460 NumAliases += DeadAliases.size();
461 for (GlobalAlias *GA : DeadAliases)
462 EraseUnusedGlobalValue(GA);
463
464 NumIFuncs += DeadIFuncs.size();
465 for (GlobalIFunc *GIF : DeadIFuncs)
466 EraseUnusedGlobalValue(GIF);
467
468 // Make sure that all memory is released
469 AliveGlobals.clear();
470 ConstantDependenciesCache.clear();
471 GVDependencies.clear();
472 VFuncDependencies.clear();
473 PendingVFuncs.clear();
474 ComdatMembers.clear();
475 TypeIdMap.clear();
476 VFESafeVTables.clear();
477
478 if (Changed)
480 return PreservedAnalyses::all();
481}
482
484 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
485 static_cast<PassInfoMixin<GlobalDCEPass> *>(this)->printPipeline(
486 OS, MapClassName2PassName);
487 if (InLTOPostLink)
488 OS << "<vfe-linkage-unit-visibility>";
489}
uint64_t uint64_t
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
dxil translate DXIL Translate Metadata
This file defines the DenseSet and SmallDenseSet classes.
static bool isEmptyFunction(Function *F)
Returns true if F is effectively empty.
Definition GlobalDCE.cpp:70
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Type::TypeID TypeID
ModuleAnalysisManager MAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
This file defines the SmallPtrSet class.
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
#define LLVM_DEBUG(...)
Definition Debug.h:119
LLVM Basic Block Representation.
Definition BasicBlock.h:62
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This is an important base class in LLVM.
Definition Constant.h:44
const Constant * stripPointerCasts() const
Definition Constant.h:243
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
Pass to remove unused function declarations.
Definition GlobalDCE.h:39
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LLVM_ABI const Comdat * getComdat() const
Definition Globals.cpp:274
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
Definition Globals.cpp:158
Root of the metadata hierarchy.
Definition Metadata.h:64
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition Pass.h:253
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
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
LLVM Value Representation.
Definition Value.h:75
iterator_range< user_iterator > users()
Definition Value.h:428
LLVM_ABI MDNode * getMetadata(StringRef Kind) const LLVM_READONLY
Get the current metadata attachments for the given kind, if any.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:314
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:51
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > dyn_extract_or_null(Y &&MD)
Extract a Value from Metadata, if any, allowing null.
Definition Metadata.h:720
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI ModulePass * createGlobalDCEPass()
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
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 bool optimizeGlobalCtorsList(Module &M, function_ref< bool(uint32_t, Function *)> ShouldRemove)
Call "ShouldRemove" for every entry in M's global_ctor list and remove the entries for which it retur...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
LLVM_ABI void replaceRelativePointerUsersWithZero(Constant *C)
Finds the same "relative pointer" pattern as described above, where the target is C,...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI Constant * getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, Constant *TopLevelGlobal=nullptr)
Processes a Constant recursively looking into elements of arrays, structs and expressions to find a t...