1//===-- ElimAvailExtern.cpp - DCE unreachable internal functions 2//----------------===// 3// 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 16#include "llvm/Transforms/IPO/ElimAvailExtern.h" 17#include "llvm/ADT/Statistic.h" 18#include "llvm/IR/Constants.h" 19#include "llvm/IR/Module.h" 20#include "llvm/Transforms/IPO.h" 21#include "llvm/Transforms/Utils/GlobalStatus.h" 22#include "llvm/Pass.h" 23using namespace llvm; 24 25#define DEBUG_TYPE "elim-avail-extern" 26 27STATISTIC(NumFunctions, "Number of functions removed"); 28STATISTIC(NumVariables, "Number of global variables removed"); 29 30static bool eliminateAvailableExternally(Module &M) { 31 bool Changed = false; 32 33 // Drop initializers of available externally global variables. 34 for (GlobalVariable &GV : M.globals()) { 35 if (!GV.hasAvailableExternallyLinkage()) 36 continue; 37 if (GV.hasInitializer()) { 38 Constant *Init = GV.getInitializer(); 39 GV.setInitializer(nullptr); 40 if (isSafeToDestroyConstant(Init)) 41 Init->destroyConstant(); 42 } 43 GV.removeDeadConstantUsers(); 44 GV.setLinkage(GlobalValue::ExternalLinkage); 45 NumVariables++; 46 Changed = true; 47 } 48 49 // Drop the bodies of available externally functions. 50 for (Function &F : M) { 51 if (!F.hasAvailableExternallyLinkage()) 52 continue; 53 if (!F.isDeclaration()) 54 // This will set the linkage to external 55 F.deleteBody(); 56 F.removeDeadConstantUsers(); 57 NumFunctions++; 58 Changed = true; 59 } 60 61 return Changed; 62} 63 64PreservedAnalyses 65EliminateAvailableExternallyPass::run(Module &M, ModuleAnalysisManager &) { 66 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} 97