From fa395ec03639614925a111e91c7623efc14e8e3d Mon Sep 17 00:00:00 2001
From: Chris Lattner <sabre@nondot.org>
Date: Sun, 2 Nov 2003 01:29:27 +0000
Subject: [PATCH] The "correct" fix for CBackend/2003-10-23-UnusedType.ll is to
 not even try to emit types which are not used.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@9647 91177308-0d34-0410-b5e6-96231b3b80d8
---
 lib/Target/CBackend/CBackend.cpp | 39 ++++++++++++++++++++------------
 lib/Target/CBackend/Writer.cpp   | 39 ++++++++++++++++++++------------
 2 files changed, 48 insertions(+), 30 deletions(-)

diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index b1f8793d64d..9a84311f4a7 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -36,6 +36,8 @@ namespace {
     std::ostream &Out; 
     Mangler *Mang;
     const Module *TheModule;
+    FindUsedTypes *FUT;
+
     std::map<const Type *, std::string> TypeNames;
     std::set<const Value*> MangledGlobals;
     bool needsMalloc, emittedInvoke;
@@ -52,6 +54,7 @@ namespace {
     virtual bool run(Module &M) {
       // Initialize
       TheModule = &M;
+      FUT = &getAnalysis<FindUsedTypes>();
 
       // Ensure that all structure types have names...
       bool Changed = nameAllUsedStructureTypes(M);
@@ -542,7 +545,7 @@ void CWriter::writeOperand(Value *Operand) {
 //
 bool CWriter::nameAllUsedStructureTypes(Module &M) {
   // Get a set of types that are used by the program...
-  std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();
+  std::set<const Type *> UT = FUT->getTypes();
 
   // Loop over the module symbol table, removing types from UT that are already
   // named.
@@ -786,24 +789,28 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   // Print out forward declarations for structure types before anything else!
   Out << "/* Structure forward decls */\n";
   for (; I != End; ++I)
-    if (const Type *STy = dyn_cast<StructType>(I->second)) {
-      std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
-      Out << Name << ";\n";
-      TypeNames.insert(std::make_pair(STy, Name));
-    }
+    if (const Type *STy = dyn_cast<StructType>(I->second))
+      // Only print out used types!
+      if (FUT->getTypes().count(STy)) {
+        std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
+        Out << Name << ";\n";
+        TypeNames.insert(std::make_pair(STy, Name));
+      }
 
   Out << "\n";
 
   // Now we can print out typedefs...
   Out << "/* Typedefs */\n";
-  for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
-    const Type *Ty = cast<Type>(I->second);
-    std::string Name = "l_" + Mangler::makeNameProper(I->first);
-    Out << "typedef ";
-    printType(Out, Ty, Name);
-    Out << ";\n";
-  }
-
+  for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
+    // Only print out used types!
+    if (FUT->getTypes().count(cast<Type>(I->second))) {
+      const Type *Ty = cast<Type>(I->second);
+      std::string Name = "l_" + Mangler::makeNameProper(I->first);
+      Out << "typedef ";
+      printType(Out, Ty, Name);
+      Out << ";\n";
+    }
+  
   Out << "\n";
 
   // Keep track of which structures have been printed so far...
@@ -815,7 +822,9 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   Out << "/* Structure contents */\n";
   for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
     if (const StructType *STy = dyn_cast<StructType>(I->second))
-      printContainedStructs(STy, StructPrinted);
+      // Only print out used types!
+      if (FUT->getTypes().count(STy))
+        printContainedStructs(STy, StructPrinted);
 }
 
 // Push the struct onto the stack and recursively push all structs
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index b1f8793d64d..9a84311f4a7 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -36,6 +36,8 @@ namespace {
     std::ostream &Out; 
     Mangler *Mang;
     const Module *TheModule;
+    FindUsedTypes *FUT;
+
     std::map<const Type *, std::string> TypeNames;
     std::set<const Value*> MangledGlobals;
     bool needsMalloc, emittedInvoke;
@@ -52,6 +54,7 @@ namespace {
     virtual bool run(Module &M) {
       // Initialize
       TheModule = &M;
+      FUT = &getAnalysis<FindUsedTypes>();
 
       // Ensure that all structure types have names...
       bool Changed = nameAllUsedStructureTypes(M);
@@ -542,7 +545,7 @@ void CWriter::writeOperand(Value *Operand) {
 //
 bool CWriter::nameAllUsedStructureTypes(Module &M) {
   // Get a set of types that are used by the program...
-  std::set<const Type *> UT = getAnalysis<FindUsedTypes>().getTypes();
+  std::set<const Type *> UT = FUT->getTypes();
 
   // Loop over the module symbol table, removing types from UT that are already
   // named.
@@ -786,24 +789,28 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   // Print out forward declarations for structure types before anything else!
   Out << "/* Structure forward decls */\n";
   for (; I != End; ++I)
-    if (const Type *STy = dyn_cast<StructType>(I->second)) {
-      std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
-      Out << Name << ";\n";
-      TypeNames.insert(std::make_pair(STy, Name));
-    }
+    if (const Type *STy = dyn_cast<StructType>(I->second))
+      // Only print out used types!
+      if (FUT->getTypes().count(STy)) {
+        std::string Name = "struct l_" + Mangler::makeNameProper(I->first);
+        Out << Name << ";\n";
+        TypeNames.insert(std::make_pair(STy, Name));
+      }
 
   Out << "\n";
 
   // Now we can print out typedefs...
   Out << "/* Typedefs */\n";
-  for (I = ST.type_begin(Type::TypeTy); I != End; ++I) {
-    const Type *Ty = cast<Type>(I->second);
-    std::string Name = "l_" + Mangler::makeNameProper(I->first);
-    Out << "typedef ";
-    printType(Out, Ty, Name);
-    Out << ";\n";
-  }
-
+  for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
+    // Only print out used types!
+    if (FUT->getTypes().count(cast<Type>(I->second))) {
+      const Type *Ty = cast<Type>(I->second);
+      std::string Name = "l_" + Mangler::makeNameProper(I->first);
+      Out << "typedef ";
+      printType(Out, Ty, Name);
+      Out << ";\n";
+    }
+  
   Out << "\n";
 
   // Keep track of which structures have been printed so far...
@@ -815,7 +822,9 @@ void CWriter::printSymbolTable(const SymbolTable &ST) {
   Out << "/* Structure contents */\n";
   for (I = ST.type_begin(Type::TypeTy); I != End; ++I)
     if (const StructType *STy = dyn_cast<StructType>(I->second))
-      printContainedStructs(STy, StructPrinted);
+      // Only print out used types!
+      if (FUT->getTypes().count(STy))
+        printContainedStructs(STy, StructPrinted);
 }
 
 // Push the struct onto the stack and recursively push all structs