FindUsedTypes.cpp revision e53883837ddb3f431788c31c7340bd63da8c3ac6
1//===- FindUsedTypes.cpp - Find all Types used by a module ----------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass is used to seek out all of the types in use by the program.  Note
11// that this analysis explicitly does not include types only used by the symbol
12// table.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Analysis/FindUsedTypes.h"
17#include "llvm/Constants.h"
18#include "llvm/DerivedTypes.h"
19#include "llvm/Module.h"
20#include "llvm/Assembly/Writer.h"
21#include "llvm/Support/InstIterator.h"
22using namespace llvm;
23
24static RegisterPass<FindUsedTypes>
25X("printusedtypes", "Find Used Types");
26
27// IncorporateType - Incorporate one type and all of its subtypes into the
28// collection of used types.
29//
30void FindUsedTypes::IncorporateType(const Type *Ty) {
31  // If ty doesn't already exist in the used types map, add it now, otherwise
32  // return.
33  if (!UsedTypes.insert(Ty).second) return;  // Already contain Ty.
34
35  // Make sure to add any types this type references now.
36  //
37  for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
38       I != E; ++I)
39    IncorporateType(*I);
40}
41
42void FindUsedTypes::IncorporateValue(const Value *V) {
43  IncorporateType(V->getType());
44
45  // If this is a constant, it could be using other types...
46  if (const Constant *C = dyn_cast<Constant>(V)) {
47    if (!isa<GlobalValue>(C))
48      for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
49           OI != OE; ++OI)
50        IncorporateValue(*OI);
51  }
52}
53
54
55// run - This incorporates all types used by the specified module
56//
57bool FindUsedTypes::runOnModule(Module &m) {
58  UsedTypes.clear();  // reset if run multiple times...
59
60  // Loop over global variables, incorporating their types
61  for (Module::const_global_iterator I = m.global_begin(), E = m.global_end(); I != E; ++I) {
62    IncorporateType(I->getType());
63    if (I->hasInitializer())
64      IncorporateValue(I->getInitializer());
65  }
66
67  for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) {
68    IncorporateType(MI->getType());
69    const Function &F = *MI;
70
71    // Loop over all of the instructions in the function, adding their return
72    // type as well as the types of their operands.
73    //
74    for (const_inst_iterator II = inst_begin(F), IE = inst_end(F);
75         II != IE; ++II) {
76      const Instruction &I = *II;
77
78      IncorporateType(I.getType());  // Incorporate the type of the instruction
79      for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
80           OI != OE; ++OI)
81        IncorporateValue(*OI);  // Insert inst operand types as well
82    }
83  }
84
85  return false;
86}
87
88// Print the types found in the module.  If the optional Module parameter is
89// passed in, then the types are printed symbolically if possible, using the
90// symbol table from the module.
91//
92void FindUsedTypes::print(std::ostream &o, const Module *M) const {
93  o << "Types in use by this module:\n";
94  for (std::set<const Type *>::const_iterator I = UsedTypes.begin(),
95       E = UsedTypes.end(); I != E; ++I)
96    WriteTypeSymbolic(o << "  ", *I, M) << "\n";
97}
98
99// Ensure that this file gets linked in when FindUsedTypes.h is used.
100DEFINING_FILE_FOR(FindUsedTypes)
101