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