* Remove lots of dead stuff
[oota-llvm.git] / lib / Transforms / IPO / DeadTypeElimination.cpp
1 //===- CleanupGCCOutput.cpp - Cleanup GCC Output --------------------------===//
2 //
3 // This pass is used to cleanup the output of GCC.  GCC's output is
4 // unneccessarily gross for a couple of reasons. This pass does the following
5 // things to try to clean it up:
6 //
7 // * Eliminate names for GCC types that we know can't be needed by the user.
8 // * Eliminate names for types that are unused in the entire translation unit
9 // * Fix various problems that we might have in PHI nodes and casts
10 //
11 // Note:  This code produces dead declarations, it is a good idea to run DCE
12 //        after this pass.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "llvm/Transforms/CleanupGCCOutput.h"
17 #include "llvm/Analysis/FindUsedTypes.h"
18 #include "llvm/Module.h"
19 #include "llvm/SymbolTable.h"
20 #include "llvm/DerivedTypes.h"
21 #include "Support/StatisticReporter.h"
22
23 static Statistic<> NumTypeSymtabEntriesKilled("cleangcc\t- Number of unused typenames removed from symtab");
24
25 using std::vector;
26
27 namespace {
28   struct CleanupGCCOutput : public FunctionPass {
29     // doPassInitialization - For this pass, it removes global symbol table
30     // entries for primitive types.  These are never used for linking in GCC and
31     // they make the output uglier to look at, so we nuke them.
32     //
33     // Also, initialize instance variables.
34     //
35     bool doInitialization(Module &M);
36
37     // FIXME:
38     // FIXME: This FunctionPass should be a PASS!
39     // FIXME:
40     bool runOnFunction(Function &F) { return false; }
41     
42     // doPassFinalization - Strip out type names that are unused by the program
43     bool doFinalization(Module &M);
44     
45     // getAnalysisUsage - This function needs FindUsedTypes to do its job...
46     //
47     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
48       AU.addRequired(FindUsedTypes::ID);
49     }
50   };
51   RegisterPass<CleanupGCCOutput> X("cleangcc", "Cleanup GCC Output");
52 }
53
54 Pass *createCleanupGCCOutputPass() {
55   return new CleanupGCCOutput();
56 }
57
58
59
60 // ShouldNukSymtabEntry - Return true if this module level symbol table entry
61 // should be eliminated.
62 //
63 static inline bool ShouldNukeSymtabEntry(const std::pair<std::string,Value*>&E){
64   // Nuke all names for primitive types!
65   if (cast<Type>(E.second)->isPrimitiveType()) return true;
66
67   // Nuke all pointers to primitive types as well...
68   if (const PointerType *PT = dyn_cast<PointerType>(E.second))
69     if (PT->getElementType()->isPrimitiveType()) return true;
70
71   return false;
72 }
73
74 // doInitialization - For this pass, it removes global symbol table
75 // entries for primitive types.  These are never used for linking in GCC and
76 // they make the output uglier to look at, so we nuke them.
77 //
78 bool CleanupGCCOutput::doInitialization(Module &M) {
79   bool Changed = false;
80
81   if (SymbolTable *ST = M.getSymbolTable()) {
82     // Check the symbol table for superfluous type entries...
83     //
84     // Grab the 'type' plane of the module symbol...
85     SymbolTable::iterator STI = ST->find(Type::TypeTy);
86     if (STI != ST->end()) {
87       // Loop over all entries in the type plane...
88       SymbolTable::VarMap &Plane = STI->second;
89       for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();)
90         if (ShouldNukeSymtabEntry(*PI)) {    // Should we remove this entry?
91 #if MAP_IS_NOT_BRAINDEAD
92           PI = Plane.erase(PI);     // STD C++ Map should support this!
93 #else
94           Plane.erase(PI);          // Alas, GCC 2.95.3 doesn't  *SIGH*
95           PI = Plane.begin();
96 #endif
97           ++NumTypeSymtabEntriesKilled;
98           Changed = true;
99         } else {
100           ++PI;
101         }
102     }
103   }
104
105   return Changed;
106 }
107
108
109 bool CleanupGCCOutput::doFinalization(Module &M) {
110   bool Changed = false;
111
112   if (SymbolTable *ST = M.getSymbolTable()) {
113     const std::set<const Type *> &UsedTypes =
114       getAnalysis<FindUsedTypes>().getTypes();
115
116     // Check the symbol table for superfluous type entries that aren't used in
117     // the program
118     //
119     // Grab the 'type' plane of the module symbol...
120     SymbolTable::iterator STI = ST->find(Type::TypeTy);
121     if (STI != ST->end()) {
122       // Loop over all entries in the type plane...
123       SymbolTable::VarMap &Plane = STI->second;
124       for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();)
125         if (!UsedTypes.count(cast<Type>(PI->second))) {
126 #if MAP_IS_NOT_BRAINDEAD
127           PI = Plane.erase(PI);     // STD C++ Map should support this!
128 #else
129           Plane.erase(PI);          // Alas, GCC 2.95.3 doesn't  *SIGH*
130           PI = Plane.begin();       // N^2 algorithms are fun.  :(
131 #endif
132           Changed = true;
133         } else {
134           ++PI;
135         }
136     }
137   }
138   return Changed;
139 }