Improve the accuracy of the inlining heuristic looking for the
[oota-llvm.git] / lib / Transforms / IPO / DeadTypeElimination.cpp
1 //===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This pass is used to cleanup the output of GCC.  It eliminate names for types
11 // that are unused in the entire translation unit, using the FindUsedTypes pass.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "deadtypeelim"
16 #include "llvm/Transforms/IPO.h"
17 #include "llvm/Analysis/FindUsedTypes.h"
18 #include "llvm/Module.h"
19 #include "llvm/TypeSymbolTable.h"
20 #include "llvm/DerivedTypes.h"
21 #include "llvm/ADT/Statistic.h"
22 using namespace llvm;
23
24 STATISTIC(NumKilled, "Number of unused typenames removed from symtab");
25
26 namespace {
27   struct DTE : public ModulePass {
28     static char ID; // Pass identification, replacement for typeid
29     DTE() : ModulePass(ID) {
30       initializeDTEPass(*PassRegistry::getPassRegistry());
31     }
32
33     // doPassInitialization - For this pass, it removes global symbol table
34     // entries for primitive types.  These are never used for linking in GCC and
35     // they make the output uglier to look at, so we nuke them.
36     //
37     // Also, initialize instance variables.
38     //
39     bool runOnModule(Module &M);
40
41     // getAnalysisUsage - This function needs FindUsedTypes to do its job...
42     //
43     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
44       AU.addRequired<FindUsedTypes>();
45     }
46   };
47 }
48
49 char DTE::ID = 0;
50 INITIALIZE_PASS_BEGIN(DTE, "deadtypeelim", "Dead Type Elimination",
51                       false, false)
52 INITIALIZE_PASS_DEPENDENCY(FindUsedTypes)
53 INITIALIZE_PASS_END(DTE, "deadtypeelim", "Dead Type Elimination", false, false)
54
55 ModulePass *llvm::createDeadTypeEliminationPass() {
56   return new DTE();
57 }
58
59
60 // ShouldNukeSymtabEntry - Return true if this module level symbol table entry
61 // should be eliminated.
62 //
63 static inline bool ShouldNukeSymtabEntry(const Type *Ty){
64   // Nuke all names for primitive types!
65   if (Ty->isPrimitiveType() || Ty->isIntegerTy()) 
66     return true;
67
68   // Nuke all pointers to primitive types as well...
69   if (const PointerType *PT = dyn_cast<PointerType>(Ty))
70     if (PT->getElementType()->isPrimitiveType() ||
71         PT->getElementType()->isIntegerTy()) 
72       return true;
73
74   return false;
75 }
76
77 // run - For this pass, it removes global symbol table entries for primitive
78 // types.  These are never used for linking in GCC and they make the output
79 // uglier to look at, so we nuke them.  Also eliminate types that are never used
80 // in the entire program as indicated by FindUsedTypes.
81 //
82 bool DTE::runOnModule(Module &M) {
83   bool Changed = false;
84
85   TypeSymbolTable &ST = M.getTypeSymbolTable();
86   std::set<const Type *> UsedTypes = getAnalysis<FindUsedTypes>().getTypes();
87
88   // Check the symbol table for superfluous type entries...
89   //
90   // Grab the 'type' plane of the module symbol...
91   TypeSymbolTable::iterator TI = ST.begin();
92   TypeSymbolTable::iterator TE = ST.end();
93   while ( TI != TE ) {
94     // If this entry should be unconditionally removed, or if we detect that
95     // the type is not used, remove it.
96     const Type *RHS = TI->second;
97     if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) {
98       ST.remove(TI++);
99       ++NumKilled;
100       Changed = true;
101     } else {
102       ++TI;
103       // We only need to leave one name for each type.
104       UsedTypes.erase(RHS);
105     }
106   }
107
108   return Changed;
109 }
110
111 // vim: sw=2