LLVM API Documentation

DeadTypeElimination.cpp

Go to the documentation of this file.
00001 //===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This pass is used to cleanup the output of GCC.  It eliminate names for types
00011 // that are unused in the entire translation unit, using the FindUsedTypes pass.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #define DEBUG_TYPE "deadtypeelim"
00016 #include "llvm/Transforms/IPO.h"
00017 #include "llvm/Analysis/FindUsedTypes.h"
00018 #include "llvm/Module.h"
00019 #include "llvm/TypeSymbolTable.h"
00020 #include "llvm/DerivedTypes.h"
00021 #include "llvm/ADT/Statistic.h"
00022 #include "llvm/Support/Compiler.h"
00023 using namespace llvm;
00024 
00025 STATISTIC(NumKilled, "Number of unused typenames removed from symtab");
00026 
00027 namespace {
00028   struct VISIBILITY_HIDDEN DTE : public ModulePass {
00029     static char ID; // Pass identification, replacement for typeid
00030     DTE() : ModulePass(&ID) {}
00031 
00032     // doPassInitialization - For this pass, it removes global symbol table
00033     // entries for primitive types.  These are never used for linking in GCC and
00034     // they make the output uglier to look at, so we nuke them.
00035     //
00036     // Also, initialize instance variables.
00037     //
00038     bool runOnModule(Module &M);
00039 
00040     // getAnalysisUsage - This function needs FindUsedTypes to do its job...
00041     //
00042     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00043       AU.addRequired<FindUsedTypes>();
00044     }
00045   };
00046 }
00047 
00048 char DTE::ID = 0;
00049 static RegisterPass<DTE> X("deadtypeelim", "Dead Type Elimination");
00050 
00051 ModulePass *llvm::createDeadTypeEliminationPass() {
00052   return new DTE();
00053 }
00054 
00055 
00056 // ShouldNukeSymtabEntry - Return true if this module level symbol table entry
00057 // should be eliminated.
00058 //
00059 static inline bool ShouldNukeSymtabEntry(const Type *Ty){
00060   // Nuke all names for primitive types!
00061   if (Ty->isPrimitiveType() || Ty->isInteger()) 
00062     return true;
00063 
00064   // Nuke all pointers to primitive types as well...
00065   if (const PointerType *PT = dyn_cast<PointerType>(Ty))
00066     if (PT->getElementType()->isPrimitiveType() ||
00067         PT->getElementType()->isInteger()) 
00068       return true;
00069 
00070   return false;
00071 }
00072 
00073 // run - For this pass, it removes global symbol table entries for primitive
00074 // types.  These are never used for linking in GCC and they make the output
00075 // uglier to look at, so we nuke them.  Also eliminate types that are never used
00076 // in the entire program as indicated by FindUsedTypes.
00077 //
00078 bool DTE::runOnModule(Module &M) {
00079   bool Changed = false;
00080 
00081   TypeSymbolTable &ST = M.getTypeSymbolTable();
00082   std::set<const Type *> UsedTypes = getAnalysis<FindUsedTypes>().getTypes();
00083 
00084   // Check the symbol table for superfluous type entries...
00085   //
00086   // Grab the 'type' plane of the module symbol...
00087   TypeSymbolTable::iterator TI = ST.begin();
00088   TypeSymbolTable::iterator TE = ST.end();
00089   while ( TI != TE ) {
00090     // If this entry should be unconditionally removed, or if we detect that
00091     // the type is not used, remove it.
00092     const Type *RHS = TI->second;
00093     if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) {
00094       ST.remove(TI++);
00095       ++NumKilled;
00096       Changed = true;
00097     } else {
00098       ++TI;
00099       // We only need to leave one name for each type.
00100       UsedTypes.erase(RHS);
00101     }
00102   }
00103 
00104   return Changed;
00105 }
00106 
00107 // vim: sw=2