1 //===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===//
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.
6 //===----------------------------------------------------------------------===//
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"
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.
23 // Also, initialize instance variables.
27 // getAnalysisUsage - This function needs FindUsedTypes to do its job...
29 virtual void getAnalysisUsage(AnalysisUsage &AU) const {
30 AU.addRequired(FindUsedTypes::ID);
33 RegisterPass<DTE> X("deadtypeelim", "Dead Type Elimination");
34 Statistic<> NumKilled("deadtypeelim\t- Number of unused typenames removed from symtab");
37 Pass *createDeadTypeEliminationPass() {
43 // ShouldNukSymtabEntry - Return true if this module level symbol table entry
44 // should be eliminated.
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;
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;
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.
62 bool DTE::run(Module &M) {
65 if (SymbolTable *ST = M.getSymbolTable()) {
66 const std::set<const Type *> &UsedTypes =
67 getAnalysis<FindUsedTypes>().getTypes();
69 // Check the symbol table for superfluous type entries...
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!
81 Plane.erase(PI); // Alas, GCC 2.95.3 doesn't *SIGH*
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!
90 Plane.erase(PI); // Alas, GCC 2.95.3 doesn't *SIGH*
91 PI = Plane.begin(); // N^2 algorithms are fun. :(