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" 22 using namespace llvm; 23 24 #define DEBUG_TYPE "elim-avail-extern" 25 26 STATISTIC(NumFunctions, "Number of functions removed"); 27 STATISTIC(NumVariables, "Number of global variables removed"); 28 29 namespace { 30 struct EliminateAvailableExternally : public ModulePass { 31 static char ID; // Pass identification, replacement for typeid EliminateAvailableExternally__anon4676bb110111::EliminateAvailableExternally32 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 44 char EliminateAvailableExternally::ID = 0; 45 INITIALIZE_PASS(EliminateAvailableExternally, "elim-avail-extern", 46 "Eliminate Available Externally Globals", false, false) 47 createEliminateAvailableExternallyPass()48ModulePass *llvm::createEliminateAvailableExternallyPass() { 49 return new EliminateAvailableExternally(); 50 } 51 runOnModule(Module & M)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