blob: 98c4b1740306dd665f0a0d994e1656431643c020 [file] [log] [blame]
Teresa Johnsonf72278f2015-11-02 18:02:11 +00001//===-- ElimAvailExtern.cpp - DCE unreachable internal functions
2//----------------===//
Teresa Johnsond3a33a12015-07-06 16:22:42 +00003//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10//
11// This transform is designed to eliminate available external global
12// definitions from the program, turning them into declarations.
13//
14//===----------------------------------------------------------------------===//
15
Davide Italiano344e8382016-05-05 02:37:32 +000016#include "llvm/Transforms/IPO/ElimAvailExtern.h"
Teresa Johnsond3a33a12015-07-06 16:22:42 +000017#include "llvm/ADT/Statistic.h"
18#include "llvm/IR/Constants.h"
Teresa Johnsond3a33a12015-07-06 16:22:42 +000019#include "llvm/IR/Module.h"
Davide Italiano344e8382016-05-05 02:37:32 +000020#include "llvm/Transforms/IPO.h"
Teresa Johnsond3a33a12015-07-06 16:22:42 +000021#include "llvm/Transforms/Utils/GlobalStatus.h"
22#include "llvm/Pass.h"
23using namespace llvm;
24
25#define DEBUG_TYPE "elim-avail-extern"
26
Teresa Johnsond3a33a12015-07-06 16:22:42 +000027STATISTIC(NumFunctions, "Number of functions removed");
28STATISTIC(NumVariables, "Number of global variables removed");
29
Davide Italiano344e8382016-05-05 02:37:32 +000030static bool eliminateAvailableExternally(Module &M) {
Teresa Johnsond3a33a12015-07-06 16:22:42 +000031 bool Changed = false;
32
33 // Drop initializers of available externally global variables.
Teresa Johnsonf72278f2015-11-02 18:02:11 +000034 for (GlobalVariable &GV : M.globals()) {
Yaron Keren771e3192015-09-04 20:24:24 +000035 if (!GV.hasAvailableExternallyLinkage())
Teresa Johnsond3a33a12015-07-06 16:22:42 +000036 continue;
Yaron Keren771e3192015-09-04 20:24:24 +000037 if (GV.hasInitializer()) {
38 Constant *Init = GV.getInitializer();
39 GV.setInitializer(nullptr);
Teresa Johnsond3a33a12015-07-06 16:22:42 +000040 if (isSafeToDestroyConstant(Init))
41 Init->destroyConstant();
42 }
Yaron Keren771e3192015-09-04 20:24:24 +000043 GV.removeDeadConstantUsers();
44 GV.setLinkage(GlobalValue::ExternalLinkage);
Teresa Johnsond3a33a12015-07-06 16:22:42 +000045 NumVariables++;
Teresa Johnsonc7ed52f2015-11-03 00:14:15 +000046 Changed = true;
Teresa Johnsond3a33a12015-07-06 16:22:42 +000047 }
48
49 // Drop the bodies of available externally functions.
Yaron Keren771e3192015-09-04 20:24:24 +000050 for (Function &F : M) {
51 if (!F.hasAvailableExternallyLinkage())
Teresa Johnsond3a33a12015-07-06 16:22:42 +000052 continue;
Yaron Keren771e3192015-09-04 20:24:24 +000053 if (!F.isDeclaration())
Teresa Johnsond3a33a12015-07-06 16:22:42 +000054 // This will set the linkage to external
Yaron Keren771e3192015-09-04 20:24:24 +000055 F.deleteBody();
56 F.removeDeadConstantUsers();
Teresa Johnsond3a33a12015-07-06 16:22:42 +000057 NumFunctions++;
Teresa Johnsonc7ed52f2015-11-03 00:14:15 +000058 Changed = true;
Teresa Johnsond3a33a12015-07-06 16:22:42 +000059 }
60
Teresa Johnsond3a33a12015-07-06 16:22:42 +000061 return Changed;
62}
Davide Italiano344e8382016-05-05 02:37:32 +000063
Chandler Carruth164a2aa62016-06-17 00:11:01 +000064PreservedAnalyses
65EliminateAvailableExternallyPass::run(Module &M, ModuleAnalysisManager &) {
Davide Italiano344e8382016-05-05 02:37:32 +000066 if (!eliminateAvailableExternally(M))
67 return PreservedAnalyses::all();
68 return PreservedAnalyses::none();
69}
70
71namespace {
72struct EliminateAvailableExternallyLegacyPass : public ModulePass {
73 static char ID; // Pass identification, replacement for typeid
74 EliminateAvailableExternallyLegacyPass() : ModulePass(ID) {
75 initializeEliminateAvailableExternallyLegacyPassPass(
76 *PassRegistry::getPassRegistry());
77 }
78
79 // run - Do the EliminateAvailableExternally pass on the specified module,
80 // optionally updating the specified callgraph to reflect the changes.
81 //
82 bool runOnModule(Module &M) {
83 if (skipModule(M))
84 return false;
85 return eliminateAvailableExternally(M);
86 }
87};
88}
89
90char EliminateAvailableExternallyLegacyPass::ID = 0;
91INITIALIZE_PASS(EliminateAvailableExternallyLegacyPass, "elim-avail-extern",
92 "Eliminate Available Externally Globals", false, false)
93
94ModulePass *llvm::createEliminateAvailableExternallyPass() {
95 return new EliminateAvailableExternallyLegacyPass();
96}