- Cleaned up the interface to AnalysisUsage to take analysis class names
[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/StatisticReporter.h"
14
15 using std::vector;
16
17 namespace {
18   struct DTE : public Pass {
19     // doPassInitialization - For this pass, it removes global symbol table
20     // entries for primitive types.  These are never used for linking in GCC and
21     // they make the output uglier to look at, so we nuke them.
22     //
23     // Also, initialize instance variables.
24     //
25     bool run(Module &M);
26
27     // getAnalysisUsage - This function needs FindUsedTypes to do its job...
28     //
29     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
30       AU.addRequired<FindUsedTypes>();
31     }
32   };
33   RegisterOpt<DTE> X("deadtypeelim", "Dead Type Elimination");
34   Statistic<> NumKilled("deadtypeelim\t- Number of unused typenames removed from symtab");
35 }
36
37 Pass *createDeadTypeEliminationPass() {
38   return new DTE();
39 }
40
41
42
43 // ShouldNukSymtabEntry - Return true if this module level symbol table entry
44 // should be eliminated.
45 //
46 static inline bool ShouldNukeSymtabEntry(const std::pair<std::string,Value*>&E){
47   // Nuke all names for primitive types!
48   if (cast<Type>(E.second)->isPrimitiveType()) return true;
49
50   // Nuke all pointers to primitive types as well...
51   if (const PointerType *PT = dyn_cast<PointerType>(E.second))
52     if (PT->getElementType()->isPrimitiveType()) return true;
53
54   return false;
55 }
56
57 // run - For this pass, it removes global symbol table entries for primitive
58 // types.  These are never used for linking in GCC and they make the output
59 // uglier to look at, so we nuke them.  Also eliminate types that are never used
60 // in the entire program as indicated by FindUsedTypes.
61 //
62 bool DTE::run(Module &M) {
63   bool Changed = false;
64
65   if (SymbolTable *ST = M.getSymbolTable()) {
66     const std::set<const Type *> &UsedTypes =
67       getAnalysis<FindUsedTypes>().getTypes();
68
69     // Check the symbol table for superfluous type entries...
70     //
71     // Grab the 'type' plane of the module symbol...
72     SymbolTable::iterator STI = ST->find(Type::TypeTy);
73     if (STI != ST->end()) {
74       // Loop over all entries in the type plane...
75       SymbolTable::VarMap &Plane = STI->second;
76       for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();)
77         if (ShouldNukeSymtabEntry(*PI)) {    // Should we remove this entry?
78 #if MAP_IS_NOT_BRAINDEAD
79           PI = Plane.erase(PI);     // STD C++ Map should support this!
80 #else
81           Plane.erase(PI);          // Alas, GCC 2.95.3 doesn't  *SIGH*
82           PI = Plane.begin();
83 #endif
84           ++NumKilled;
85           Changed = true;
86         } else if (!UsedTypes.count(cast<Type>(PI->second))) {
87 #if MAP_IS_NOT_BRAINDEAD
88           PI = Plane.erase(PI);     // STD C++ Map should support this!
89 #else
90           Plane.erase(PI);          // Alas, GCC 2.95.3 doesn't  *SIGH*
91           PI = Plane.begin();       // N^2 algorithms are fun.  :(
92 #endif
93           ++NumKilled;
94           Changed = true;
95         } else {
96           ++PI;
97         }
98     }
99   }
100
101   return Changed;
102 }