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.h" 17#include "llvm/ADT/Statistic.h" 18#include "llvm/IR/Constants.h" 19#include "llvm/IR/Module.h" 20#include "llvm/Transforms/Utils/GlobalStatus.h" 21#include "llvm/Pass.h" 22using namespace llvm; 23 24#define DEBUG_TYPE "elim-avail-extern" 25 26STATISTIC(NumFunctions, "Number of functions removed"); 27STATISTIC(NumVariables, "Number of global variables removed"); 28 29namespace { 30struct EliminateAvailableExternally : public ModulePass { 31 static char ID; // Pass identification, replacement for typeid 32 EliminateAvailableExternally() : ModulePass(ID) { 33 initializeEliminateAvailableExternallyPass( 34 *PassRegistry::getPassRegistry()); 35 } 36 37 // run - Do the EliminateAvailableExternally pass on the specified module, 38 // optionally updating the specified callgraph to reflect the changes. 39 // 40 bool runOnModule(Module &M) override; 41}; 42} 43 44char EliminateAvailableExternally::ID = 0; 45INITIALIZE_PASS(EliminateAvailableExternally, "elim-avail-extern", 46 "Eliminate Available Externally Globals", false, false) 47 48ModulePass *llvm::createEliminateAvailableExternallyPass() { 49 return new EliminateAvailableExternally(); 50} 51 52bool EliminateAvailableExternally::runOnModule(Module &M) { 53 bool Changed = false; 54 55 // Drop initializers of available externally global variables. 56 for (GlobalVariable &GV : M.globals()) { 57 if (!GV.hasAvailableExternallyLinkage()) 58 continue; 59 if (GV.hasInitializer()) { 60 Constant *Init = GV.getInitializer(); 61 GV.setInitializer(nullptr); 62 if (isSafeToDestroyConstant(Init)) 63 Init->destroyConstant(); 64 } 65 GV.removeDeadConstantUsers(); 66 GV.setLinkage(GlobalValue::ExternalLinkage); 67 NumVariables++; 68 Changed = true; 69 } 70 71 // Drop the bodies of available externally functions. 72 for (Function &F : M) { 73 if (!F.hasAvailableExternallyLinkage()) 74 continue; 75 if (!F.isDeclaration()) 76 // This will set the linkage to external 77 F.deleteBody(); 78 F.removeDeadConstantUsers(); 79 NumFunctions++; 80 Changed = true; 81 } 82 83 return Changed; 84} 85