From 430aa9ec1c462886be420f000d62ddd93fc45250 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 15 Nov 2001 04:34:46 +0000 Subject: [PATCH] -cleangcc pass now remove type names that are never referenced and type names for pointers to primitive types. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1312 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/IPO.h | 6 ++- lib/Transforms/IPO/DeadTypeElimination.cpp | 46 ++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/llvm/Transforms/IPO.h b/include/llvm/Transforms/IPO.h index 893b5d6bfc0..99ff169a1a0 100644 --- a/include/llvm/Transforms/IPO.h +++ b/include/llvm/Transforms/IPO.h @@ -6,10 +6,11 @@ #ifndef LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H #define LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H -#include "llvm/Pass.h" +#include "llvm/Analysis/FindUsedTypes.h" class CleanupGCCOutput : public Pass { Method *Malloc, *Free; // Pointers to external declarations, or null if none + FindUsedTypes FUT; // Use FUT to eliminate type names that are never used public: inline CleanupGCCOutput() : Malloc(0), Free(0) {} @@ -31,6 +32,9 @@ public: // doPerMethodWork - This method simplifies the specified method hopefully. // bool doPerMethodWork(Method *M); + + // doPassFinalization - Strip out type names that are unused by the program + bool doPassFinalization(Module *M); private: bool doOneCleanupPass(Method *M); }; diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp index 8e705ebff56..e02c022dbb2 100644 --- a/lib/Transforms/IPO/DeadTypeElimination.cpp +++ b/lib/Transforms/IPO/DeadTypeElimination.cpp @@ -5,9 +5,8 @@ // things to try to clean it up: // // * Eliminate names for GCC types that we know can't be needed by the user. -// - Eliminate names for types that are unused in the entire translation unit -// but only if they do not name a structure type! -// - Replace calls to 'sbyte *%malloc(uint)' and 'void %free(sbyte *)' with +// * Eliminate names for types that are unused in the entire translation unit +// * Replace calls to 'sbyte *%malloc(uint)' and 'void %free(sbyte *)' with // malloc and free instructions. // // Note: This code produces dead declarations, it is a good idea to run DCE @@ -206,6 +205,10 @@ static inline bool ShouldNukeSymtabEntry(const pair &E) { // Nuke all names for primitive types! if (cast(E.second)->isPrimitiveType()) return true; + // Nuke all pointers to primitive types as well... + if (const PointerType *PT = dyn_cast(E.second)) + if (PT->getValueType()->isPrimitiveType()) return true; + // The only types that could contain .'s in the program are things generated // by GCC itself, including "complex.float" and friends. Nuke them too. if (E.first.find('.') != string::npos) return true; @@ -220,6 +223,8 @@ static inline bool ShouldNukeSymtabEntry(const pair &E) { bool CleanupGCCOutput::doPassInitialization(Module *M) { bool Changed = false; + FUT.doPassInitialization(M); + if (PtrArrSByte == 0) { PtrArrSByte = PointerType::get(ArrayType::get(Type::SByteTy)); PtrSByte = PointerType::get(Type::SByteTy); @@ -547,5 +552,40 @@ static bool fixLocalProblems(Method *M) { bool CleanupGCCOutput::doPerMethodWork(Method *M) { bool Changed = fixLocalProblems(M); while (doOneCleanupPass(M)) Changed = true; + + FUT.doPerMethodWork(M); + return Changed; +} + +bool CleanupGCCOutput::doPassFinalization(Module *M) { + bool Changed = false; + FUT.doPassFinalization(M); + + if (M->hasSymbolTable()) { + SymbolTable *ST = M->getSymbolTable(); + const set &UsedTypes = FUT.getTypes(); + + // Check the symbol table for superfluous type entries that aren't used in + // the program + // + // Grab the 'type' plane of the module symbol... + SymbolTable::iterator STI = ST->find(Type::TypeTy); + if (STI != ST->end()) { + // Loop over all entries in the type plane... + SymbolTable::VarMap &Plane = STI->second; + for (SymbolTable::VarMap::iterator PI = Plane.begin(); PI != Plane.end();) + if (!UsedTypes.count(cast(PI->second))) { +#if MAP_IS_NOT_BRAINDEAD + PI = Plane.erase(PI); // STD C++ Map should support this! +#else + Plane.erase(PI); // Alas, GCC 2.95.3 doesn't *SIGH* + PI = Plane.begin(); // N^2 algorithms are fun. :( +#endif + Changed = true; + } else { + ++PI; + } + } + } return Changed; }