-cleangcc pass now remove type names that are never referenced and type names for...
authorChris Lattner <sabre@nondot.org>
Thu, 15 Nov 2001 04:34:46 +0000 (04:34 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 15 Nov 2001 04:34:46 +0000 (04:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1312 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/IPO.h
lib/Transforms/IPO/DeadTypeElimination.cpp

index 893b5d6bfc0bd7101cc70ee2cdee77a9add70340..99ff169a1a0b21f851262d6dc1fe3e014a0fed05 100644 (file)
@@ -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);
 };
index 8e705ebff56b3189d4507497320de5c0d25bd848..e02c022dbb24b903f6656e9de3c17b420174d977 100644 (file)
@@ -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<string, Value*> &E) {
   // Nuke all names for primitive types!
   if (cast<Type>(E.second)->isPrimitiveType()) return true;
 
+  // Nuke all pointers to primitive types as well...
+  if (const PointerType *PT = dyn_cast<PointerType>(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<string, Value*> &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<const Type *> &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<Type>(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;
 }