1 //===-- StripDeadPrototypes.cpp - Remove unused function declarations ----===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This pass loops over all of the functions in the input module, looking for 10 // dead declarations and removes them. Dead declarations are declarations of 11 // functions for which no implementation is available (i.e., declarations for 12 // unused library functions). 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/Transforms/IPO/StripDeadPrototypes.h" 17 #include "llvm/ADT/Statistic.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/InitializePasses.h" 20 #include "llvm/Pass.h" 21 #include "llvm/Transforms/IPO.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "strip-dead-prototypes" 26 27 STATISTIC(NumDeadPrototypes, "Number of dead prototypes removed"); 28 29 static bool stripDeadPrototypes(Module &M) { 30 bool MadeChange = false; 31 32 // Erase dead function prototypes. 33 for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { 34 Function *F = &*I++; 35 // Function must be a prototype and unused. 36 if (F->isDeclaration() && F->use_empty()) { 37 F->eraseFromParent(); 38 ++NumDeadPrototypes; 39 MadeChange = true; 40 } 41 } 42 43 // Erase dead global var prototypes. 44 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); 45 I != E; ) { 46 GlobalVariable *GV = &*I++; 47 // Global must be a prototype and unused. 48 if (GV->isDeclaration() && GV->use_empty()) 49 GV->eraseFromParent(); 50 } 51 52 // Return an indication of whether we changed anything or not. 53 return MadeChange; 54 } 55 56 PreservedAnalyses StripDeadPrototypesPass::run(Module &M, 57 ModuleAnalysisManager &) { 58 if (stripDeadPrototypes(M)) 59 return PreservedAnalyses::none(); 60 return PreservedAnalyses::all(); 61 } 62 63 namespace { 64 65 class StripDeadPrototypesLegacyPass : public ModulePass { 66 public: 67 static char ID; // Pass identification, replacement for typeid 68 StripDeadPrototypesLegacyPass() : ModulePass(ID) { 69 initializeStripDeadPrototypesLegacyPassPass( 70 *PassRegistry::getPassRegistry()); 71 } 72 bool runOnModule(Module &M) override { 73 if (skipModule(M)) 74 return false; 75 76 return stripDeadPrototypes(M); 77 } 78 }; 79 80 } // end anonymous namespace 81 82 char StripDeadPrototypesLegacyPass::ID = 0; 83 INITIALIZE_PASS(StripDeadPrototypesLegacyPass, "strip-dead-prototypes", 84 "Strip Unused Function Prototypes", false, false) 85 86 ModulePass *llvm::createStripDeadPrototypesPass() { 87 return new StripDeadPrototypesLegacyPass(); 88 } 89