LLVM API Documentation
00001 //===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This pass is used to cleanup the output of GCC. It eliminate names for types 00011 // that are unused in the entire translation unit, using the FindUsedTypes pass. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #define DEBUG_TYPE "deadtypeelim" 00016 #include "llvm/Transforms/IPO.h" 00017 #include "llvm/Analysis/FindUsedTypes.h" 00018 #include "llvm/Module.h" 00019 #include "llvm/TypeSymbolTable.h" 00020 #include "llvm/DerivedTypes.h" 00021 #include "llvm/ADT/Statistic.h" 00022 #include "llvm/Support/Compiler.h" 00023 using namespace llvm; 00024 00025 STATISTIC(NumKilled, "Number of unused typenames removed from symtab"); 00026 00027 namespace { 00028 struct VISIBILITY_HIDDEN DTE : public ModulePass { 00029 static char ID; // Pass identification, replacement for typeid 00030 DTE() : ModulePass(&ID) {} 00031 00032 // doPassInitialization - For this pass, it removes global symbol table 00033 // entries for primitive types. These are never used for linking in GCC and 00034 // they make the output uglier to look at, so we nuke them. 00035 // 00036 // Also, initialize instance variables. 00037 // 00038 bool runOnModule(Module &M); 00039 00040 // getAnalysisUsage - This function needs FindUsedTypes to do its job... 00041 // 00042 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 00043 AU.addRequired<FindUsedTypes>(); 00044 } 00045 }; 00046 } 00047 00048 char DTE::ID = 0; 00049 static RegisterPass<DTE> X("deadtypeelim", "Dead Type Elimination"); 00050 00051 ModulePass *llvm::createDeadTypeEliminationPass() { 00052 return new DTE(); 00053 } 00054 00055 00056 // ShouldNukeSymtabEntry - Return true if this module level symbol table entry 00057 // should be eliminated. 00058 // 00059 static inline bool ShouldNukeSymtabEntry(const Type *Ty){ 00060 // Nuke all names for primitive types! 00061 if (Ty->isPrimitiveType() || Ty->isInteger()) 00062 return true; 00063 00064 // Nuke all pointers to primitive types as well... 00065 if (const PointerType *PT = dyn_cast<PointerType>(Ty)) 00066 if (PT->getElementType()->isPrimitiveType() || 00067 PT->getElementType()->isInteger()) 00068 return true; 00069 00070 return false; 00071 } 00072 00073 // run - For this pass, it removes global symbol table entries for primitive 00074 // types. These are never used for linking in GCC and they make the output 00075 // uglier to look at, so we nuke them. Also eliminate types that are never used 00076 // in the entire program as indicated by FindUsedTypes. 00077 // 00078 bool DTE::runOnModule(Module &M) { 00079 bool Changed = false; 00080 00081 TypeSymbolTable &ST = M.getTypeSymbolTable(); 00082 std::set<const Type *> UsedTypes = getAnalysis<FindUsedTypes>().getTypes(); 00083 00084 // Check the symbol table for superfluous type entries... 00085 // 00086 // Grab the 'type' plane of the module symbol... 00087 TypeSymbolTable::iterator TI = ST.begin(); 00088 TypeSymbolTable::iterator TE = ST.end(); 00089 while ( TI != TE ) { 00090 // If this entry should be unconditionally removed, or if we detect that 00091 // the type is not used, remove it. 00092 const Type *RHS = TI->second; 00093 if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) { 00094 ST.remove(TI++); 00095 ++NumKilled; 00096 Changed = true; 00097 } else { 00098 ++TI; 00099 // We only need to leave one name for each type. 00100 UsedTypes.erase(RHS); 00101 } 00102 } 00103 00104 return Changed; 00105 } 00106 00107 // vim: sw=2