FindUsedTypes.cpp revision f4de63f65fa995e68e3cd268117ab065068be413
1//===- FindUsedTypes.h - Find all Types used by a module --------------------=// 2// 3// This pass is used to seek out all of the types in use by the program. 4// 5//===----------------------------------------------------------------------===// 6 7#include "llvm/Analysis/FindUsedTypes.h" 8#include "llvm/Assembly/CachedWriter.h" 9#include "llvm/SymbolTable.h" 10#include "llvm/GlobalVariable.h" 11#include "llvm/DerivedTypes.h" 12 13// IncorporateType - Incorporate one type and all of its subtypes into the 14// collection of used types. 15// 16void FindUsedTypes::IncorporateType(const Type *Ty) { 17 if (UsedTypes.count(Ty)) return; // Already contain Ty. 18 19 // If ty doesn't already exist in the used types map, add it now. 20 // 21 UsedTypes.insert(Ty); 22 23 // Make sure to add any types this type references now. 24 // 25 for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); 26 I != E; ++I) 27 IncorporateType(*I); 28} 29 30// IncorporateSymbolTable - Add all types referenced by the specified symtab 31// into the collection of used types. 32// 33void FindUsedTypes::IncorporateSymbolTable(const SymbolTable *ST) { 34 assert(0 && "Unimp"); 35} 36 37 38// doInitialization - This loops over global constants defined in the 39// module, converting them to their new type. 40// 41bool FindUsedTypes::doInitialization(Module *m) { 42 const Module *M = m; 43 if (IncludeSymbolTables && M->hasSymbolTable()) 44 IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first... 45 46 // Loop over global variables, incorporating their types 47 for (Module::const_giterator I = M->gbegin(), E = M->gend(); I != E; ++I) 48 IncorporateType((*I)->getType()); 49 return false; 50} 51 52// doPerMethodWork - This incorporates all types used by the specified method 53// 54bool FindUsedTypes::runOnMethod(Method *m) { 55 const Method *M = m; 56 if (IncludeSymbolTables && M->hasSymbolTable()) 57 IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first... 58 59 // Loop over all of the instructions in the method, adding their return type 60 // as well as the types of their operands. 61 // 62 for (Method::const_inst_iterator II = M->inst_begin(), IE = M->inst_end(); 63 II != IE; ++II) { 64 const Instruction *I = *II; 65 const Type *Ty = I->getType(); 66 67 IncorporateType(Ty); // Incorporate the type of the instruction 68 for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end(); 69 OI != OE; ++OI) 70 if ((*OI)->getType() != Ty) // Avoid set lookup in common case 71 IncorporateType((*OI)->getType()); // Insert inst operand types as well 72 } 73 74 return false; 75} 76 77// Print the types found in the module. If the optional Module parameter is 78// passed in, then the types are printed symbolically if possible, using the 79// symbol table from the module. 80// 81void FindUsedTypes::printTypes(std::ostream &o, const Module *M = 0) const { 82 o << "Types in use by this module:\n"; 83 if (M) { 84 CachedWriter CW(M, o); 85 for (std::set<const Type *>::const_iterator I = UsedTypes.begin(), 86 E = UsedTypes.end(); I != E; ++I) 87 CW << " " << *I << "\n"; 88 } else 89 for (std::set<const Type *>::const_iterator I = UsedTypes.begin(), 90 E = UsedTypes.end(); I != E; ++I) 91 o << " " << *I << "\n"; 92} 93