109467b48Spatrick //===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This transform is designed to eliminate unreachable internal globals from the
1009467b48Spatrick // program.  It uses an aggressive algorithm, searching out globals that are
1109467b48Spatrick // known to be alive.  After it finds all of the globals which are needed, it
1209467b48Spatrick // deletes whatever is left over.  This allows it to delete recursive chunks of
1309467b48Spatrick // the program which are unreachable.
1409467b48Spatrick //
1509467b48Spatrick //===----------------------------------------------------------------------===//
1609467b48Spatrick 
1709467b48Spatrick #include "llvm/Transforms/IPO/GlobalDCE.h"
1809467b48Spatrick #include "llvm/ADT/SmallPtrSet.h"
1909467b48Spatrick #include "llvm/ADT/Statistic.h"
2009467b48Spatrick #include "llvm/Analysis/TypeMetadataUtils.h"
2109467b48Spatrick #include "llvm/IR/Instructions.h"
2209467b48Spatrick #include "llvm/IR/IntrinsicInst.h"
2309467b48Spatrick #include "llvm/IR/Module.h"
2409467b48Spatrick #include "llvm/InitializePasses.h"
2509467b48Spatrick #include "llvm/Pass.h"
2609467b48Spatrick #include "llvm/Support/CommandLine.h"
2709467b48Spatrick #include "llvm/Transforms/IPO.h"
2809467b48Spatrick #include "llvm/Transforms/Utils/CtorUtils.h"
2909467b48Spatrick #include "llvm/Transforms/Utils/GlobalStatus.h"
3009467b48Spatrick 
3109467b48Spatrick using namespace llvm;
3209467b48Spatrick 
3309467b48Spatrick #define DEBUG_TYPE "globaldce"
3409467b48Spatrick 
3509467b48Spatrick static cl::opt<bool>
36*d415bd75Srobert     ClEnableVFE("enable-vfe", cl::Hidden, cl::init(true),
3709467b48Spatrick                 cl::desc("Enable virtual function elimination"));
3809467b48Spatrick 
3909467b48Spatrick STATISTIC(NumAliases  , "Number of global aliases removed");
4009467b48Spatrick STATISTIC(NumFunctions, "Number of functions removed");
4109467b48Spatrick STATISTIC(NumIFuncs,    "Number of indirect functions removed");
4209467b48Spatrick STATISTIC(NumVariables, "Number of global variables removed");
4309467b48Spatrick STATISTIC(NumVFuncs,    "Number of virtual functions removed");
4409467b48Spatrick 
4509467b48Spatrick namespace {
4609467b48Spatrick   class GlobalDCELegacyPass : public ModulePass {
4709467b48Spatrick   public:
4809467b48Spatrick     static char ID; // Pass identification, replacement for typeid
GlobalDCELegacyPass()4909467b48Spatrick     GlobalDCELegacyPass() : ModulePass(ID) {
5009467b48Spatrick       initializeGlobalDCELegacyPassPass(*PassRegistry::getPassRegistry());
5109467b48Spatrick     }
5209467b48Spatrick 
5309467b48Spatrick     // run - Do the GlobalDCE pass on the specified module, optionally updating
5409467b48Spatrick     // the specified callgraph to reflect the changes.
5509467b48Spatrick     //
runOnModule(Module & M)5609467b48Spatrick     bool runOnModule(Module &M) override {
5709467b48Spatrick       if (skipModule(M))
5809467b48Spatrick         return false;
5909467b48Spatrick 
6009467b48Spatrick       // We need a minimally functional dummy module analysis manager. It needs
6109467b48Spatrick       // to at least know about the possibility of proxying a function analysis
6209467b48Spatrick       // manager.
6309467b48Spatrick       FunctionAnalysisManager DummyFAM;
6409467b48Spatrick       ModuleAnalysisManager DummyMAM;
6509467b48Spatrick       DummyMAM.registerPass(
6609467b48Spatrick           [&] { return FunctionAnalysisManagerModuleProxy(DummyFAM); });
6709467b48Spatrick 
6809467b48Spatrick       auto PA = Impl.run(M, DummyMAM);
6909467b48Spatrick       return !PA.areAllPreserved();
7009467b48Spatrick     }
7109467b48Spatrick 
7209467b48Spatrick   private:
7309467b48Spatrick     GlobalDCEPass Impl;
7409467b48Spatrick   };
7509467b48Spatrick }
7609467b48Spatrick 
7709467b48Spatrick char GlobalDCELegacyPass::ID = 0;
7809467b48Spatrick INITIALIZE_PASS(GlobalDCELegacyPass, "globaldce",
7909467b48Spatrick                 "Dead Global Elimination", false, false)
8009467b48Spatrick 
8109467b48Spatrick // Public interface to the GlobalDCEPass.
createGlobalDCEPass()8209467b48Spatrick ModulePass *llvm::createGlobalDCEPass() {
8309467b48Spatrick   return new GlobalDCELegacyPass();
8409467b48Spatrick }
8509467b48Spatrick 
8609467b48Spatrick /// Returns true if F is effectively empty.
isEmptyFunction(Function * F)8709467b48Spatrick static bool isEmptyFunction(Function *F) {
88*d415bd75Srobert   // Skip external functions.
89*d415bd75Srobert   if (F->isDeclaration())
90*d415bd75Srobert     return false;
9109467b48Spatrick   BasicBlock &Entry = F->getEntryBlock();
9209467b48Spatrick   for (auto &I : Entry) {
93*d415bd75Srobert     if (I.isDebugOrPseudoInst())
9409467b48Spatrick       continue;
9509467b48Spatrick     if (auto *RI = dyn_cast<ReturnInst>(&I))
9609467b48Spatrick       return !RI->getReturnValue();
9709467b48Spatrick     break;
9809467b48Spatrick   }
9909467b48Spatrick   return false;
10009467b48Spatrick }
10109467b48Spatrick 
10209467b48Spatrick /// Compute the set of GlobalValue that depends from V.
10309467b48Spatrick /// The recursion stops as soon as a GlobalValue is met.
ComputeDependencies(Value * V,SmallPtrSetImpl<GlobalValue * > & Deps)10409467b48Spatrick void GlobalDCEPass::ComputeDependencies(Value *V,
10509467b48Spatrick                                         SmallPtrSetImpl<GlobalValue *> &Deps) {
10609467b48Spatrick   if (auto *I = dyn_cast<Instruction>(V)) {
10709467b48Spatrick     Function *Parent = I->getParent()->getParent();
10809467b48Spatrick     Deps.insert(Parent);
10909467b48Spatrick   } else if (auto *GV = dyn_cast<GlobalValue>(V)) {
11009467b48Spatrick     Deps.insert(GV);
11109467b48Spatrick   } else if (auto *CE = dyn_cast<Constant>(V)) {
11209467b48Spatrick     // Avoid walking the whole tree of a big ConstantExprs multiple times.
11309467b48Spatrick     auto Where = ConstantDependenciesCache.find(CE);
11409467b48Spatrick     if (Where != ConstantDependenciesCache.end()) {
11509467b48Spatrick       auto const &K = Where->second;
11609467b48Spatrick       Deps.insert(K.begin(), K.end());
11709467b48Spatrick     } else {
11809467b48Spatrick       SmallPtrSetImpl<GlobalValue *> &LocalDeps = ConstantDependenciesCache[CE];
11909467b48Spatrick       for (User *CEUser : CE->users())
12009467b48Spatrick         ComputeDependencies(CEUser, LocalDeps);
12109467b48Spatrick       Deps.insert(LocalDeps.begin(), LocalDeps.end());
12209467b48Spatrick     }
12309467b48Spatrick   }
12409467b48Spatrick }
12509467b48Spatrick 
UpdateGVDependencies(GlobalValue & GV)12609467b48Spatrick void GlobalDCEPass::UpdateGVDependencies(GlobalValue &GV) {
12709467b48Spatrick   SmallPtrSet<GlobalValue *, 8> Deps;
12809467b48Spatrick   for (User *User : GV.users())
12909467b48Spatrick     ComputeDependencies(User, Deps);
13009467b48Spatrick   Deps.erase(&GV); // Remove self-reference.
13109467b48Spatrick   for (GlobalValue *GVU : Deps) {
13209467b48Spatrick     // If this is a dep from a vtable to a virtual function, and we have
13309467b48Spatrick     // complete information about all virtual call sites which could call
13409467b48Spatrick     // though this vtable, then skip it, because the call site information will
13509467b48Spatrick     // be more precise.
13609467b48Spatrick     if (VFESafeVTables.count(GVU) && isa<Function>(&GV)) {
13709467b48Spatrick       LLVM_DEBUG(dbgs() << "Ignoring dep " << GVU->getName() << " -> "
13809467b48Spatrick                         << GV.getName() << "\n");
13909467b48Spatrick       continue;
14009467b48Spatrick     }
14109467b48Spatrick     GVDependencies[GVU].insert(&GV);
14209467b48Spatrick   }
14309467b48Spatrick }
14409467b48Spatrick 
14509467b48Spatrick /// Mark Global value as Live
MarkLive(GlobalValue & GV,SmallVectorImpl<GlobalValue * > * Updates)14609467b48Spatrick void GlobalDCEPass::MarkLive(GlobalValue &GV,
14709467b48Spatrick                              SmallVectorImpl<GlobalValue *> *Updates) {
14809467b48Spatrick   auto const Ret = AliveGlobals.insert(&GV);
14909467b48Spatrick   if (!Ret.second)
15009467b48Spatrick     return;
15109467b48Spatrick 
15209467b48Spatrick   if (Updates)
15309467b48Spatrick     Updates->push_back(&GV);
15409467b48Spatrick   if (Comdat *C = GV.getComdat()) {
15509467b48Spatrick     for (auto &&CM : make_range(ComdatMembers.equal_range(C))) {
15609467b48Spatrick       MarkLive(*CM.second, Updates); // Recursion depth is only two because only
15709467b48Spatrick                                      // globals in the same comdat are visited.
15809467b48Spatrick     }
15909467b48Spatrick   }
16009467b48Spatrick }
16109467b48Spatrick 
ScanVTables(Module & M)16209467b48Spatrick void GlobalDCEPass::ScanVTables(Module &M) {
16309467b48Spatrick   SmallVector<MDNode *, 2> Types;
16409467b48Spatrick   LLVM_DEBUG(dbgs() << "Building type info -> vtable map\n");
16509467b48Spatrick 
16609467b48Spatrick   auto *LTOPostLinkMD =
16709467b48Spatrick       cast_or_null<ConstantAsMetadata>(M.getModuleFlag("LTOPostLink"));
16809467b48Spatrick   bool LTOPostLink =
16909467b48Spatrick       LTOPostLinkMD &&
17009467b48Spatrick       (cast<ConstantInt>(LTOPostLinkMD->getValue())->getZExtValue() != 0);
17109467b48Spatrick 
17209467b48Spatrick   for (GlobalVariable &GV : M.globals()) {
17309467b48Spatrick     Types.clear();
17409467b48Spatrick     GV.getMetadata(LLVMContext::MD_type, Types);
17509467b48Spatrick     if (GV.isDeclaration() || Types.empty())
17609467b48Spatrick       continue;
17709467b48Spatrick 
17809467b48Spatrick     // Use the typeid metadata on the vtable to build a mapping from typeids to
17909467b48Spatrick     // the list of (GV, offset) pairs which are the possible vtables for that
18009467b48Spatrick     // typeid.
18109467b48Spatrick     for (MDNode *Type : Types) {
18209467b48Spatrick       Metadata *TypeID = Type->getOperand(1).get();
18309467b48Spatrick 
18409467b48Spatrick       uint64_t Offset =
18509467b48Spatrick           cast<ConstantInt>(
18609467b48Spatrick               cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
18709467b48Spatrick               ->getZExtValue();
18809467b48Spatrick 
18909467b48Spatrick       TypeIdMap[TypeID].insert(std::make_pair(&GV, Offset));
19009467b48Spatrick     }
19109467b48Spatrick 
19209467b48Spatrick     // If the type corresponding to the vtable is private to this translation
19309467b48Spatrick     // unit, we know that we can see all virtual functions which might use it,
19409467b48Spatrick     // so VFE is safe.
19509467b48Spatrick     if (auto GO = dyn_cast<GlobalObject>(&GV)) {
19609467b48Spatrick       GlobalObject::VCallVisibility TypeVis = GO->getVCallVisibility();
19709467b48Spatrick       if (TypeVis == GlobalObject::VCallVisibilityTranslationUnit ||
19809467b48Spatrick           (LTOPostLink &&
19909467b48Spatrick            TypeVis == GlobalObject::VCallVisibilityLinkageUnit)) {
20009467b48Spatrick         LLVM_DEBUG(dbgs() << GV.getName() << " is safe for VFE\n");
20109467b48Spatrick         VFESafeVTables.insert(&GV);
20209467b48Spatrick       }
20309467b48Spatrick     }
20409467b48Spatrick   }
20509467b48Spatrick }
20609467b48Spatrick 
ScanVTableLoad(Function * Caller,Metadata * TypeId,uint64_t CallOffset)20709467b48Spatrick void GlobalDCEPass::ScanVTableLoad(Function *Caller, Metadata *TypeId,
20809467b48Spatrick                                    uint64_t CallOffset) {
209*d415bd75Srobert   for (const auto &VTableInfo : TypeIdMap[TypeId]) {
21009467b48Spatrick     GlobalVariable *VTable = VTableInfo.first;
21109467b48Spatrick     uint64_t VTableOffset = VTableInfo.second;
21209467b48Spatrick 
21309467b48Spatrick     Constant *Ptr =
21409467b48Spatrick         getPointerAtOffset(VTable->getInitializer(), VTableOffset + CallOffset,
215*d415bd75Srobert                            *Caller->getParent(), VTable);
21609467b48Spatrick     if (!Ptr) {
21709467b48Spatrick       LLVM_DEBUG(dbgs() << "can't find pointer in vtable!\n");
21809467b48Spatrick       VFESafeVTables.erase(VTable);
219*d415bd75Srobert       continue;
22009467b48Spatrick     }
22109467b48Spatrick 
22209467b48Spatrick     auto Callee = dyn_cast<Function>(Ptr->stripPointerCasts());
22309467b48Spatrick     if (!Callee) {
22409467b48Spatrick       LLVM_DEBUG(dbgs() << "vtable entry is not function pointer!\n");
22509467b48Spatrick       VFESafeVTables.erase(VTable);
226*d415bd75Srobert       continue;
22709467b48Spatrick     }
22809467b48Spatrick 
22909467b48Spatrick     LLVM_DEBUG(dbgs() << "vfunc dep " << Caller->getName() << " -> "
23009467b48Spatrick                       << Callee->getName() << "\n");
23109467b48Spatrick     GVDependencies[Caller].insert(Callee);
23209467b48Spatrick   }
23309467b48Spatrick }
23409467b48Spatrick 
ScanTypeCheckedLoadIntrinsics(Module & M)23509467b48Spatrick void GlobalDCEPass::ScanTypeCheckedLoadIntrinsics(Module &M) {
23609467b48Spatrick   LLVM_DEBUG(dbgs() << "Scanning type.checked.load intrinsics\n");
23709467b48Spatrick   Function *TypeCheckedLoadFunc =
23809467b48Spatrick       M.getFunction(Intrinsic::getName(Intrinsic::type_checked_load));
23909467b48Spatrick 
24009467b48Spatrick   if (!TypeCheckedLoadFunc)
24109467b48Spatrick     return;
24209467b48Spatrick 
243*d415bd75Srobert   for (auto *U : TypeCheckedLoadFunc->users()) {
24409467b48Spatrick     auto CI = dyn_cast<CallInst>(U);
24509467b48Spatrick     if (!CI)
24609467b48Spatrick       continue;
24709467b48Spatrick 
24809467b48Spatrick     auto *Offset = dyn_cast<ConstantInt>(CI->getArgOperand(1));
24909467b48Spatrick     Value *TypeIdValue = CI->getArgOperand(2);
25009467b48Spatrick     auto *TypeId = cast<MetadataAsValue>(TypeIdValue)->getMetadata();
25109467b48Spatrick 
25209467b48Spatrick     if (Offset) {
25309467b48Spatrick       ScanVTableLoad(CI->getFunction(), TypeId, Offset->getZExtValue());
25409467b48Spatrick     } else {
25509467b48Spatrick       // type.checked.load with a non-constant offset, so assume every entry in
25609467b48Spatrick       // every matching vtable is used.
257*d415bd75Srobert       for (const auto &VTableInfo : TypeIdMap[TypeId]) {
25809467b48Spatrick         VFESafeVTables.erase(VTableInfo.first);
25909467b48Spatrick       }
26009467b48Spatrick     }
26109467b48Spatrick   }
26209467b48Spatrick }
26309467b48Spatrick 
AddVirtualFunctionDependencies(Module & M)26409467b48Spatrick void GlobalDCEPass::AddVirtualFunctionDependencies(Module &M) {
26509467b48Spatrick   if (!ClEnableVFE)
26609467b48Spatrick     return;
26709467b48Spatrick 
268097a140dSpatrick   // If the Virtual Function Elim module flag is present and set to zero, then
269097a140dSpatrick   // the vcall_visibility metadata was inserted for another optimization (WPD)
270097a140dSpatrick   // and we may not have type checked loads on all accesses to the vtable.
271097a140dSpatrick   // Don't attempt VFE in that case.
272097a140dSpatrick   auto *Val = mdconst::dyn_extract_or_null<ConstantInt>(
273097a140dSpatrick       M.getModuleFlag("Virtual Function Elim"));
274097a140dSpatrick   if (!Val || Val->getZExtValue() == 0)
275097a140dSpatrick     return;
276097a140dSpatrick 
27709467b48Spatrick   ScanVTables(M);
27809467b48Spatrick 
27909467b48Spatrick   if (VFESafeVTables.empty())
28009467b48Spatrick     return;
28109467b48Spatrick 
28209467b48Spatrick   ScanTypeCheckedLoadIntrinsics(M);
28309467b48Spatrick 
28409467b48Spatrick   LLVM_DEBUG(
28509467b48Spatrick     dbgs() << "VFE safe vtables:\n";
28609467b48Spatrick     for (auto *VTable : VFESafeVTables)
28709467b48Spatrick       dbgs() << "  " << VTable->getName() << "\n";
28809467b48Spatrick   );
28909467b48Spatrick }
29009467b48Spatrick 
run(Module & M,ModuleAnalysisManager & MAM)29109467b48Spatrick PreservedAnalyses GlobalDCEPass::run(Module &M, ModuleAnalysisManager &MAM) {
29209467b48Spatrick   bool Changed = false;
29309467b48Spatrick 
29409467b48Spatrick   // The algorithm first computes the set L of global variables that are
29509467b48Spatrick   // trivially live.  Then it walks the initialization of these variables to
29609467b48Spatrick   // compute the globals used to initialize them, which effectively builds a
29709467b48Spatrick   // directed graph where nodes are global variables, and an edge from A to B
29809467b48Spatrick   // means B is used to initialize A.  Finally, it propagates the liveness
29909467b48Spatrick   // information through the graph starting from the nodes in L. Nodes note
30009467b48Spatrick   // marked as alive are discarded.
30109467b48Spatrick 
30209467b48Spatrick   // Remove empty functions from the global ctors list.
303*d415bd75Srobert   Changed |= optimizeGlobalCtorsList(
304*d415bd75Srobert       M, [](uint32_t, Function *F) { return isEmptyFunction(F); });
30509467b48Spatrick 
30609467b48Spatrick   // Collect the set of members for each comdat.
30709467b48Spatrick   for (Function &F : M)
30809467b48Spatrick     if (Comdat *C = F.getComdat())
30909467b48Spatrick       ComdatMembers.insert(std::make_pair(C, &F));
31009467b48Spatrick   for (GlobalVariable &GV : M.globals())
31109467b48Spatrick     if (Comdat *C = GV.getComdat())
31209467b48Spatrick       ComdatMembers.insert(std::make_pair(C, &GV));
31309467b48Spatrick   for (GlobalAlias &GA : M.aliases())
31409467b48Spatrick     if (Comdat *C = GA.getComdat())
31509467b48Spatrick       ComdatMembers.insert(std::make_pair(C, &GA));
31609467b48Spatrick 
31709467b48Spatrick   // Add dependencies between virtual call sites and the virtual functions they
31809467b48Spatrick   // might call, if we have that information.
31909467b48Spatrick   AddVirtualFunctionDependencies(M);
32009467b48Spatrick 
32109467b48Spatrick   // Loop over the module, adding globals which are obviously necessary.
32209467b48Spatrick   for (GlobalObject &GO : M.global_objects()) {
323*d415bd75Srobert     GO.removeDeadConstantUsers();
32409467b48Spatrick     // Functions with external linkage are needed if they have a body.
32509467b48Spatrick     // Externally visible & appending globals are needed, if they have an
32609467b48Spatrick     // initializer.
32709467b48Spatrick     if (!GO.isDeclaration())
32809467b48Spatrick       if (!GO.isDiscardableIfUnused())
32909467b48Spatrick         MarkLive(GO);
33009467b48Spatrick 
33109467b48Spatrick     UpdateGVDependencies(GO);
33209467b48Spatrick   }
33309467b48Spatrick 
33409467b48Spatrick   // Compute direct dependencies of aliases.
33509467b48Spatrick   for (GlobalAlias &GA : M.aliases()) {
336*d415bd75Srobert     GA.removeDeadConstantUsers();
33709467b48Spatrick     // Externally visible aliases are needed.
33809467b48Spatrick     if (!GA.isDiscardableIfUnused())
33909467b48Spatrick       MarkLive(GA);
34009467b48Spatrick 
34109467b48Spatrick     UpdateGVDependencies(GA);
34209467b48Spatrick   }
34309467b48Spatrick 
34409467b48Spatrick   // Compute direct dependencies of ifuncs.
34509467b48Spatrick   for (GlobalIFunc &GIF : M.ifuncs()) {
346*d415bd75Srobert     GIF.removeDeadConstantUsers();
34709467b48Spatrick     // Externally visible ifuncs are needed.
34809467b48Spatrick     if (!GIF.isDiscardableIfUnused())
34909467b48Spatrick       MarkLive(GIF);
35009467b48Spatrick 
35109467b48Spatrick     UpdateGVDependencies(GIF);
35209467b48Spatrick   }
35309467b48Spatrick 
35409467b48Spatrick   // Propagate liveness from collected Global Values through the computed
35509467b48Spatrick   // dependencies.
35609467b48Spatrick   SmallVector<GlobalValue *, 8> NewLiveGVs{AliveGlobals.begin(),
35709467b48Spatrick                                            AliveGlobals.end()};
35809467b48Spatrick   while (!NewLiveGVs.empty()) {
35909467b48Spatrick     GlobalValue *LGV = NewLiveGVs.pop_back_val();
36009467b48Spatrick     for (auto *GVD : GVDependencies[LGV])
36109467b48Spatrick       MarkLive(*GVD, &NewLiveGVs);
36209467b48Spatrick   }
36309467b48Spatrick 
36409467b48Spatrick   // Now that all globals which are needed are in the AliveGlobals set, we loop
36509467b48Spatrick   // through the program, deleting those which are not alive.
36609467b48Spatrick   //
36709467b48Spatrick 
36809467b48Spatrick   // The first pass is to drop initializers of global variables which are dead.
36909467b48Spatrick   std::vector<GlobalVariable *> DeadGlobalVars; // Keep track of dead globals
37009467b48Spatrick   for (GlobalVariable &GV : M.globals())
37109467b48Spatrick     if (!AliveGlobals.count(&GV)) {
37209467b48Spatrick       DeadGlobalVars.push_back(&GV);         // Keep track of dead globals
37309467b48Spatrick       if (GV.hasInitializer()) {
37409467b48Spatrick         Constant *Init = GV.getInitializer();
37509467b48Spatrick         GV.setInitializer(nullptr);
37609467b48Spatrick         if (isSafeToDestroyConstant(Init))
37709467b48Spatrick           Init->destroyConstant();
37809467b48Spatrick       }
37909467b48Spatrick     }
38009467b48Spatrick 
38109467b48Spatrick   // The second pass drops the bodies of functions which are dead...
38209467b48Spatrick   std::vector<Function *> DeadFunctions;
38309467b48Spatrick   for (Function &F : M)
38409467b48Spatrick     if (!AliveGlobals.count(&F)) {
38509467b48Spatrick       DeadFunctions.push_back(&F);         // Keep track of dead globals
38609467b48Spatrick       if (!F.isDeclaration())
38709467b48Spatrick         F.deleteBody();
38809467b48Spatrick     }
38909467b48Spatrick 
39009467b48Spatrick   // The third pass drops targets of aliases which are dead...
39109467b48Spatrick   std::vector<GlobalAlias*> DeadAliases;
39209467b48Spatrick   for (GlobalAlias &GA : M.aliases())
39309467b48Spatrick     if (!AliveGlobals.count(&GA)) {
39409467b48Spatrick       DeadAliases.push_back(&GA);
39509467b48Spatrick       GA.setAliasee(nullptr);
39609467b48Spatrick     }
39709467b48Spatrick 
39809467b48Spatrick   // The fourth pass drops targets of ifuncs which are dead...
39909467b48Spatrick   std::vector<GlobalIFunc*> DeadIFuncs;
40009467b48Spatrick   for (GlobalIFunc &GIF : M.ifuncs())
40109467b48Spatrick     if (!AliveGlobals.count(&GIF)) {
40209467b48Spatrick       DeadIFuncs.push_back(&GIF);
40309467b48Spatrick       GIF.setResolver(nullptr);
40409467b48Spatrick     }
40509467b48Spatrick 
40609467b48Spatrick   // Now that all interferences have been dropped, delete the actual objects
40709467b48Spatrick   // themselves.
40809467b48Spatrick   auto EraseUnusedGlobalValue = [&](GlobalValue *GV) {
409*d415bd75Srobert     GV->removeDeadConstantUsers();
41009467b48Spatrick     GV->eraseFromParent();
41109467b48Spatrick     Changed = true;
41209467b48Spatrick   };
41309467b48Spatrick 
41409467b48Spatrick   NumFunctions += DeadFunctions.size();
41509467b48Spatrick   for (Function *F : DeadFunctions) {
41609467b48Spatrick     if (!F->use_empty()) {
41709467b48Spatrick       // Virtual functions might still be referenced by one or more vtables,
41809467b48Spatrick       // but if we've proven them to be unused then it's safe to replace the
41909467b48Spatrick       // virtual function pointers with null, allowing us to remove the
42009467b48Spatrick       // function itself.
42109467b48Spatrick       ++NumVFuncs;
422*d415bd75Srobert 
423*d415bd75Srobert       // Detect vfuncs that are referenced as "relative pointers" which are used
424*d415bd75Srobert       // in Swift vtables, i.e. entries in the form of:
425*d415bd75Srobert       //
426*d415bd75Srobert       //   i32 trunc (i64 sub (i64 ptrtoint @f, i64 ptrtoint ...)) to i32)
427*d415bd75Srobert       //
428*d415bd75Srobert       // In this case, replace the whole "sub" expression with constant 0 to
429*d415bd75Srobert       // avoid leaving a weird sub(0, symbol) expression behind.
430*d415bd75Srobert       replaceRelativePointerUsersWithZero(F);
431*d415bd75Srobert 
43209467b48Spatrick       F->replaceNonMetadataUsesWith(ConstantPointerNull::get(F->getType()));
43309467b48Spatrick     }
43409467b48Spatrick     EraseUnusedGlobalValue(F);
43509467b48Spatrick   }
43609467b48Spatrick 
43709467b48Spatrick   NumVariables += DeadGlobalVars.size();
43809467b48Spatrick   for (GlobalVariable *GV : DeadGlobalVars)
43909467b48Spatrick     EraseUnusedGlobalValue(GV);
44009467b48Spatrick 
44109467b48Spatrick   NumAliases += DeadAliases.size();
44209467b48Spatrick   for (GlobalAlias *GA : DeadAliases)
44309467b48Spatrick     EraseUnusedGlobalValue(GA);
44409467b48Spatrick 
44509467b48Spatrick   NumIFuncs += DeadIFuncs.size();
44609467b48Spatrick   for (GlobalIFunc *GIF : DeadIFuncs)
44709467b48Spatrick     EraseUnusedGlobalValue(GIF);
44809467b48Spatrick 
44909467b48Spatrick   // Make sure that all memory is released
45009467b48Spatrick   AliveGlobals.clear();
45109467b48Spatrick   ConstantDependenciesCache.clear();
45209467b48Spatrick   GVDependencies.clear();
45309467b48Spatrick   ComdatMembers.clear();
45409467b48Spatrick   TypeIdMap.clear();
45509467b48Spatrick   VFESafeVTables.clear();
45609467b48Spatrick 
45709467b48Spatrick   if (Changed)
45809467b48Spatrick     return PreservedAnalyses::none();
45909467b48Spatrick   return PreservedAnalyses::all();
46009467b48Spatrick }
461