xref: /aosp_15_r20/external/llvm/lib/Transforms/IPO/ElimAvailExtern.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- ElimAvailExtern.cpp - DCE unreachable internal functions
2*9880d681SAndroid Build Coastguard Worker //----------------===//
3*9880d681SAndroid Build Coastguard Worker //
4*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
5*9880d681SAndroid Build Coastguard Worker //
6*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
7*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
8*9880d681SAndroid Build Coastguard Worker //
9*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
10*9880d681SAndroid Build Coastguard Worker //
11*9880d681SAndroid Build Coastguard Worker // This transform is designed to eliminate available external global
12*9880d681SAndroid Build Coastguard Worker // definitions from the program, turning them into declarations.
13*9880d681SAndroid Build Coastguard Worker //
14*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
15*9880d681SAndroid Build Coastguard Worker 
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO/ElimAvailExtern.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Constants.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Module.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/IPO.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/Transforms/Utils/GlobalStatus.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
23*9880d681SAndroid Build Coastguard Worker using namespace llvm;
24*9880d681SAndroid Build Coastguard Worker 
25*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "elim-avail-extern"
26*9880d681SAndroid Build Coastguard Worker 
27*9880d681SAndroid Build Coastguard Worker STATISTIC(NumFunctions, "Number of functions removed");
28*9880d681SAndroid Build Coastguard Worker STATISTIC(NumVariables, "Number of global variables removed");
29*9880d681SAndroid Build Coastguard Worker 
eliminateAvailableExternally(Module & M)30*9880d681SAndroid Build Coastguard Worker static bool eliminateAvailableExternally(Module &M) {
31*9880d681SAndroid Build Coastguard Worker   bool Changed = false;
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker   // Drop initializers of available externally global variables.
34*9880d681SAndroid Build Coastguard Worker   for (GlobalVariable &GV : M.globals()) {
35*9880d681SAndroid Build Coastguard Worker     if (!GV.hasAvailableExternallyLinkage())
36*9880d681SAndroid Build Coastguard Worker       continue;
37*9880d681SAndroid Build Coastguard Worker     if (GV.hasInitializer()) {
38*9880d681SAndroid Build Coastguard Worker       Constant *Init = GV.getInitializer();
39*9880d681SAndroid Build Coastguard Worker       GV.setInitializer(nullptr);
40*9880d681SAndroid Build Coastguard Worker       if (isSafeToDestroyConstant(Init))
41*9880d681SAndroid Build Coastguard Worker         Init->destroyConstant();
42*9880d681SAndroid Build Coastguard Worker     }
43*9880d681SAndroid Build Coastguard Worker     GV.removeDeadConstantUsers();
44*9880d681SAndroid Build Coastguard Worker     GV.setLinkage(GlobalValue::ExternalLinkage);
45*9880d681SAndroid Build Coastguard Worker     NumVariables++;
46*9880d681SAndroid Build Coastguard Worker     Changed = true;
47*9880d681SAndroid Build Coastguard Worker   }
48*9880d681SAndroid Build Coastguard Worker 
49*9880d681SAndroid Build Coastguard Worker   // Drop the bodies of available externally functions.
50*9880d681SAndroid Build Coastguard Worker   for (Function &F : M) {
51*9880d681SAndroid Build Coastguard Worker     if (!F.hasAvailableExternallyLinkage())
52*9880d681SAndroid Build Coastguard Worker       continue;
53*9880d681SAndroid Build Coastguard Worker     if (!F.isDeclaration())
54*9880d681SAndroid Build Coastguard Worker       // This will set the linkage to external
55*9880d681SAndroid Build Coastguard Worker       F.deleteBody();
56*9880d681SAndroid Build Coastguard Worker     F.removeDeadConstantUsers();
57*9880d681SAndroid Build Coastguard Worker     NumFunctions++;
58*9880d681SAndroid Build Coastguard Worker     Changed = true;
59*9880d681SAndroid Build Coastguard Worker   }
60*9880d681SAndroid Build Coastguard Worker 
61*9880d681SAndroid Build Coastguard Worker   return Changed;
62*9880d681SAndroid Build Coastguard Worker }
63*9880d681SAndroid Build Coastguard Worker 
64*9880d681SAndroid Build Coastguard Worker PreservedAnalyses
run(Module & M,ModuleAnalysisManager &)65*9880d681SAndroid Build Coastguard Worker EliminateAvailableExternallyPass::run(Module &M, ModuleAnalysisManager &) {
66*9880d681SAndroid Build Coastguard Worker   if (!eliminateAvailableExternally(M))
67*9880d681SAndroid Build Coastguard Worker     return PreservedAnalyses::all();
68*9880d681SAndroid Build Coastguard Worker   return PreservedAnalyses::none();
69*9880d681SAndroid Build Coastguard Worker }
70*9880d681SAndroid Build Coastguard Worker 
71*9880d681SAndroid Build Coastguard Worker namespace {
72*9880d681SAndroid Build Coastguard Worker struct EliminateAvailableExternallyLegacyPass : public ModulePass {
73*9880d681SAndroid Build Coastguard Worker   static char ID; // Pass identification, replacement for typeid
EliminateAvailableExternallyLegacyPass__anona39f45470111::EliminateAvailableExternallyLegacyPass74*9880d681SAndroid Build Coastguard Worker   EliminateAvailableExternallyLegacyPass() : ModulePass(ID) {
75*9880d681SAndroid Build Coastguard Worker     initializeEliminateAvailableExternallyLegacyPassPass(
76*9880d681SAndroid Build Coastguard Worker         *PassRegistry::getPassRegistry());
77*9880d681SAndroid Build Coastguard Worker   }
78*9880d681SAndroid Build Coastguard Worker 
79*9880d681SAndroid Build Coastguard Worker   // run - Do the EliminateAvailableExternally pass on the specified module,
80*9880d681SAndroid Build Coastguard Worker   // optionally updating the specified callgraph to reflect the changes.
81*9880d681SAndroid Build Coastguard Worker   //
runOnModule__anona39f45470111::EliminateAvailableExternallyLegacyPass82*9880d681SAndroid Build Coastguard Worker   bool runOnModule(Module &M) {
83*9880d681SAndroid Build Coastguard Worker     if (skipModule(M))
84*9880d681SAndroid Build Coastguard Worker       return false;
85*9880d681SAndroid Build Coastguard Worker     return eliminateAvailableExternally(M);
86*9880d681SAndroid Build Coastguard Worker   }
87*9880d681SAndroid Build Coastguard Worker };
88*9880d681SAndroid Build Coastguard Worker }
89*9880d681SAndroid Build Coastguard Worker 
90*9880d681SAndroid Build Coastguard Worker char EliminateAvailableExternallyLegacyPass::ID = 0;
91*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(EliminateAvailableExternallyLegacyPass, "elim-avail-extern",
92*9880d681SAndroid Build Coastguard Worker                 "Eliminate Available Externally Globals", false, false)
93*9880d681SAndroid Build Coastguard Worker 
createEliminateAvailableExternallyPass()94*9880d681SAndroid Build Coastguard Worker ModulePass *llvm::createEliminateAvailableExternallyPass() {
95*9880d681SAndroid Build Coastguard Worker   return new EliminateAvailableExternallyLegacyPass();
96*9880d681SAndroid Build Coastguard Worker }
97