1e9ea08a0SEugene Zelenko //===- ElimAvailExtern.cpp - DCE unreachable internal functions -----------===//
2d3a33a16STeresa Johnson //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6d3a33a16STeresa Johnson //
7d3a33a16STeresa Johnson //===----------------------------------------------------------------------===//
8d3a33a16STeresa Johnson //
9d3a33a16STeresa Johnson // This transform is designed to eliminate available external global
10d3a33a16STeresa Johnson // definitions from the program, turning them into declarations.
11d3a33a16STeresa Johnson //
12d3a33a16STeresa Johnson //===----------------------------------------------------------------------===//
13d3a33a16STeresa Johnson 
14344e838fSDavide Italiano #include "llvm/Transforms/IPO/ElimAvailExtern.h"
15d3a33a16STeresa Johnson #include "llvm/ADT/Statistic.h"
16e9ea08a0SEugene Zelenko #include "llvm/IR/Constant.h"
17e9ea08a0SEugene Zelenko #include "llvm/IR/Function.h"
18e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalValue.h"
19e9ea08a0SEugene Zelenko #include "llvm/IR/GlobalVariable.h"
20d3a33a16STeresa Johnson #include "llvm/IR/Module.h"
21*05da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
226bda14b3SChandler Carruth #include "llvm/Pass.h"
23344e838fSDavide Italiano #include "llvm/Transforms/IPO.h"
24d3a33a16STeresa Johnson #include "llvm/Transforms/Utils/GlobalStatus.h"
25e9ea08a0SEugene Zelenko 
26d3a33a16STeresa Johnson using namespace llvm;
27d3a33a16STeresa Johnson 
28d3a33a16STeresa Johnson #define DEBUG_TYPE "elim-avail-extern"
29d3a33a16STeresa Johnson 
30d3a33a16STeresa Johnson STATISTIC(NumFunctions, "Number of functions removed");
31d3a33a16STeresa Johnson STATISTIC(NumVariables, "Number of global variables removed");
32d3a33a16STeresa Johnson 
eliminateAvailableExternally(Module & M)33344e838fSDavide Italiano static bool eliminateAvailableExternally(Module &M) {
34d3a33a16STeresa Johnson   bool Changed = false;
35d3a33a16STeresa Johnson 
36d3a33a16STeresa Johnson   // Drop initializers of available externally global variables.
37771e3196SYaron Keren   for (GlobalVariable &GV : M.globals()) {
38771e3196SYaron Keren     if (!GV.hasAvailableExternallyLinkage())
39d3a33a16STeresa Johnson       continue;
40771e3196SYaron Keren     if (GV.hasInitializer()) {
41771e3196SYaron Keren       Constant *Init = GV.getInitializer();
42771e3196SYaron Keren       GV.setInitializer(nullptr);
43d3a33a16STeresa Johnson       if (isSafeToDestroyConstant(Init))
44d3a33a16STeresa Johnson         Init->destroyConstant();
45d3a33a16STeresa Johnson     }
46771e3196SYaron Keren     GV.removeDeadConstantUsers();
47771e3196SYaron Keren     GV.setLinkage(GlobalValue::ExternalLinkage);
48d3a33a16STeresa Johnson     NumVariables++;
49c7ed52f2STeresa Johnson     Changed = true;
50d3a33a16STeresa Johnson   }
51d3a33a16STeresa Johnson 
52d3a33a16STeresa Johnson   // Drop the bodies of available externally functions.
53771e3196SYaron Keren   for (Function &F : M) {
54771e3196SYaron Keren     if (!F.hasAvailableExternallyLinkage())
55d3a33a16STeresa Johnson       continue;
56771e3196SYaron Keren     if (!F.isDeclaration())
57d3a33a16STeresa Johnson       // This will set the linkage to external
58771e3196SYaron Keren       F.deleteBody();
59771e3196SYaron Keren     F.removeDeadConstantUsers();
60d3a33a16STeresa Johnson     NumFunctions++;
61c7ed52f2STeresa Johnson     Changed = true;
62d3a33a16STeresa Johnson   }
63d3a33a16STeresa Johnson 
64d3a33a16STeresa Johnson   return Changed;
65d3a33a16STeresa Johnson }
66344e838fSDavide Italiano 
67164a2aa6SChandler Carruth PreservedAnalyses
run(Module & M,ModuleAnalysisManager &)68164a2aa6SChandler Carruth EliminateAvailableExternallyPass::run(Module &M, ModuleAnalysisManager &) {
69344e838fSDavide Italiano   if (!eliminateAvailableExternally(M))
70344e838fSDavide Italiano     return PreservedAnalyses::all();
71344e838fSDavide Italiano   return PreservedAnalyses::none();
72344e838fSDavide Italiano }
73344e838fSDavide Italiano 
74344e838fSDavide Italiano namespace {
75e9ea08a0SEugene Zelenko 
76344e838fSDavide Italiano struct EliminateAvailableExternallyLegacyPass : public ModulePass {
77344e838fSDavide Italiano   static char ID; // Pass identification, replacement for typeid
78e9ea08a0SEugene Zelenko 
EliminateAvailableExternallyLegacyPass__anon806e13df0111::EliminateAvailableExternallyLegacyPass79344e838fSDavide Italiano   EliminateAvailableExternallyLegacyPass() : ModulePass(ID) {
80344e838fSDavide Italiano     initializeEliminateAvailableExternallyLegacyPassPass(
81344e838fSDavide Italiano         *PassRegistry::getPassRegistry());
82344e838fSDavide Italiano   }
83344e838fSDavide Italiano 
84344e838fSDavide Italiano   // run - Do the EliminateAvailableExternally pass on the specified module,
85344e838fSDavide Italiano   // optionally updating the specified callgraph to reflect the changes.
runOnModule__anon806e13df0111::EliminateAvailableExternallyLegacyPass86e9ea08a0SEugene Zelenko   bool runOnModule(Module &M) override {
87344e838fSDavide Italiano     if (skipModule(M))
88344e838fSDavide Italiano       return false;
89344e838fSDavide Italiano     return eliminateAvailableExternally(M);
90344e838fSDavide Italiano   }
91344e838fSDavide Italiano };
92e9ea08a0SEugene Zelenko 
93e9ea08a0SEugene Zelenko } // end anonymous namespace
94344e838fSDavide Italiano 
95344e838fSDavide Italiano char EliminateAvailableExternallyLegacyPass::ID = 0;
96e9ea08a0SEugene Zelenko 
97344e838fSDavide Italiano INITIALIZE_PASS(EliminateAvailableExternallyLegacyPass, "elim-avail-extern",
98344e838fSDavide Italiano                 "Eliminate Available Externally Globals", false, false)
99344e838fSDavide Italiano 
createEliminateAvailableExternallyPass()100344e838fSDavide Italiano ModulePass *llvm::createEliminateAvailableExternallyPass() {
101344e838fSDavide Italiano   return new EliminateAvailableExternallyLegacyPass();
102344e838fSDavide Italiano }
103