becbf4a2d09809996e143f0d66c4d0954388d0e9
[oota-llvm.git] / lib / Transforms / IPO / DeadTypeElimination.cpp
1 //===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===//
2 //
3 // This pass is used to cleanup the output of GCC.  It eliminate names for types
4 // that are unused in the entire translation unit, using the FindUsedTypes pass.
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/Transforms/IPO.h"
9 #include "llvm/Analysis/FindUsedTypes.h"
10 #include "llvm/Module.h"
11 #include "llvm/SymbolTable.h"
12 #include "llvm/DerivedTypes.h"
13 #include "Support/Statistic.h"
14
15 namespace {
16   struct DTE : public Pass {
17     // doPassInitialization - For this pass, it removes global symbol table
18     // entries for primitive types.  These are never used for linking in GCC and
19     // they make the output uglier to look at, so we nuke them.
20     //
21     // Also, initialize instance variables.
22     //
23     bool run(Module &M);
24
25     // getAnalysisUsage - This function needs FindUsedTypes to do its job...
26     //
27     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
28       AU.addRequired<FindUsedTypes>();
29     }
30   };
31   RegisterOpt<DTE> X("deadtypeelim", "Dead Type Elimination");
32   Statistic<>
33   NumKilled("deadtypeelim", "Number of unused typenames removed from symtab");
34 }
35
36 Pass *createDeadTypeEliminationPass() {
37   return new DTE();
38 }
39
40
41
42 // ShouldNukSymtabEntry - Return true if this module level symbol table entry
43 // should be eliminated.
44 //
45 static inline bool ShouldNukeSymtabEntry(const std::pair<std::string,Value*>&E){
46   // Nuke all names for primitive types!
47   if (cast<Type>(E.second)->isPrimitiveType()) return true;
48
49   // Nuke all pointers to primitive types as well...
50   if (const PointerType *PT = dyn_cast<PointerType>(E.second))
51     if (PT->getElementType()->isPrimitiveType()) return true;
52
53   return false;
54 }
55
56 // run - For this pass, it removes global symbol table entries for primitive
57 // types.  These are never used for linking in GCC and they make the output
58 // uglier to look at, so we nuke them.  Also eliminate types that are never used
59 // in the entire program as indicated by FindUsedTypes.
60 //
61 bool DTE::run(Module &M) {
62   bool Changed = false;
63
64   SymbolTable &ST = M.getSymbolTable();
65   const std::set<const Type *> &UsedTypes =
66     getAnalysis<FindUsedTypes>().getTypes();
67
68   // Check the symbol table for superfluous type entries...
69   //
70   // Grab the 'type' plane of the module symbol...
71   SymbolTable::iterator STI = ST.find(Type::TypeTy);
72   if (STI != ST.end()) {
73     // Loop over all entries in the type plane...
74     SymbolTable::VarMap &Plane = STI->second;
75     for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();)
76       // If this entry should be unconditionally removed, or if we detect that
77       // the type is not used, remove it.
78       if (ShouldNukeSymtabEntry(*PI) ||
79           !UsedTypes.count(cast<Type>(PI->second))) {
80         SymbolTable::VarMap::iterator PJ = PI++;
81         Plane.erase(PJ);
82         ++NumKilled;
83         Changed = true;
84       } else {
85         ++PI;
86       }
87   }
88
89   return Changed;
90 }