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