1193323Sed//===- FindUsedTypes.cpp - Find all Types used by a module ----------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This pass is used to seek out all of the types in use by the program. Note 11193323Sed// that this analysis explicitly does not include types only used by the symbol 12193323Sed// table. 13193323Sed// 14193323Sed//===----------------------------------------------------------------------===// 15193323Sed 16193323Sed#include "llvm/Analysis/FindUsedTypes.h" 17193323Sed#include "llvm/Assembly/Writer.h" 18249423Sdim#include "llvm/IR/Constants.h" 19249423Sdim#include "llvm/IR/DerivedTypes.h" 20249423Sdim#include "llvm/IR/Module.h" 21193323Sed#include "llvm/Support/InstIterator.h" 22193323Sed#include "llvm/Support/raw_ostream.h" 23193323Sedusing namespace llvm; 24193323Sed 25193323Sedchar FindUsedTypes::ID = 0; 26212904SdimINITIALIZE_PASS(FindUsedTypes, "print-used-types", 27218893Sdim "Find Used Types", false, true) 28193323Sed 29193323Sed// IncorporateType - Incorporate one type and all of its subtypes into the 30193323Sed// collection of used types. 31193323Sed// 32226633Sdimvoid FindUsedTypes::IncorporateType(Type *Ty) { 33193323Sed // If ty doesn't already exist in the used types map, add it now, otherwise 34193323Sed // return. 35223017Sdim if (!UsedTypes.insert(Ty)) return; // Already contain Ty. 36193323Sed 37193323Sed // Make sure to add any types this type references now. 38193323Sed // 39193323Sed for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); 40193323Sed I != E; ++I) 41193323Sed IncorporateType(*I); 42193323Sed} 43193323Sed 44193323Sedvoid FindUsedTypes::IncorporateValue(const Value *V) { 45193323Sed IncorporateType(V->getType()); 46193323Sed 47193323Sed // If this is a constant, it could be using other types... 48193323Sed if (const Constant *C = dyn_cast<Constant>(V)) { 49193323Sed if (!isa<GlobalValue>(C)) 50193323Sed for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end(); 51193323Sed OI != OE; ++OI) 52193323Sed IncorporateValue(*OI); 53193323Sed } 54193323Sed} 55193323Sed 56193323Sed 57193323Sed// run - This incorporates all types used by the specified module 58193323Sed// 59193323Sedbool FindUsedTypes::runOnModule(Module &m) { 60193323Sed UsedTypes.clear(); // reset if run multiple times... 61193323Sed 62193323Sed // Loop over global variables, incorporating their types 63193323Sed for (Module::const_global_iterator I = m.global_begin(), E = m.global_end(); 64193323Sed I != E; ++I) { 65193323Sed IncorporateType(I->getType()); 66193323Sed if (I->hasInitializer()) 67193323Sed IncorporateValue(I->getInitializer()); 68193323Sed } 69193323Sed 70193323Sed for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) { 71193323Sed IncorporateType(MI->getType()); 72193323Sed const Function &F = *MI; 73193323Sed 74193323Sed // Loop over all of the instructions in the function, adding their return 75193323Sed // type as well as the types of their operands. 76193323Sed // 77193323Sed for (const_inst_iterator II = inst_begin(F), IE = inst_end(F); 78193323Sed II != IE; ++II) { 79193323Sed const Instruction &I = *II; 80193323Sed 81193323Sed IncorporateType(I.getType()); // Incorporate the type of the instruction 82193323Sed for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); 83193323Sed OI != OE; ++OI) 84193323Sed IncorporateValue(*OI); // Insert inst operand types as well 85193323Sed } 86193323Sed } 87193323Sed 88193323Sed return false; 89193323Sed} 90193323Sed 91193323Sed// Print the types found in the module. If the optional Module parameter is 92193323Sed// passed in, then the types are printed symbolically if possible, using the 93193323Sed// symbol table from the module. 94193323Sed// 95198090Srdivackyvoid FindUsedTypes::print(raw_ostream &OS, const Module *M) const { 96198090Srdivacky OS << "Types in use by this module:\n"; 97226633Sdim for (SetVector<Type *>::const_iterator I = UsedTypes.begin(), 98193323Sed E = UsedTypes.end(); I != E; ++I) { 99224145Sdim OS << " " << **I << '\n'; 100193323Sed } 101193323Sed} 102