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