1 //===-- llvm/Analysis/ModuleAnalyzer.cpp - Module analysis driver ----------==//
3 // This class provides a nice interface to traverse a module in a predictable
4 // way. This is used by the AssemblyWriter, BytecodeWriter, and SlotCalculator
5 // to do analysis of a module.
7 //===----------------------------------------------------------------------===//
9 #include "llvm/Analysis/ModuleAnalyzer.h"
10 #include "llvm/ConstantPool.h"
11 #include "llvm/Method.h"
12 #include "llvm/Module.h"
13 #include "llvm/BasicBlock.h"
14 #include "llvm/DerivedTypes.h"
15 #include "llvm/ConstPoolVals.h"
16 #include "llvm/Support/STLExtras.h"
19 // processModule - Driver function to call all of my subclasses virtual methods.
21 bool ModuleAnalyzer::processModule(const Module *M) {
22 // Loop over the constant pool, process all of the constants...
23 if (processConstPool(M->getConstantPool(), false))
26 return processMethods(M);
29 inline bool ModuleAnalyzer::handleType(set<const Type *> &TypeSet,
31 if (!T->isDerivedType()) return false; // Boring boring types...
32 if (TypeSet.count(T) != 0) return false; // Already found this type...
33 TypeSet.insert(T); // Add it to the set
35 // Recursively process interesting types...
36 switch (T->getPrimitiveID()) {
37 case Type::MethodTyID: {
38 const MethodType *MT = (const MethodType *)T;
39 if (handleType(TypeSet, MT->getReturnType())) return true;
40 const MethodType::ParamTypes &Params = MT->getParamTypes();
42 for (MethodType::ParamTypes::const_iterator I = Params.begin();
43 I != Params.end(); ++I)
44 if (handleType(TypeSet, *I)) return true;
49 if (handleType(TypeSet, ((const ArrayType *)T)->getElementType()))
53 case Type::StructTyID: {
54 const StructType *ST = (const StructType*)T;
55 const StructType::ElementTypes &Elements = ST->getElementTypes();
56 for (StructType::ElementTypes::const_iterator I = Elements.begin();
57 I != Elements.end(); ++I)
58 if (handleType(TypeSet, *I)) return true;
62 case Type::PointerTyID:
63 if (handleType(TypeSet, ((const PointerType *)T)->getValueType()))
68 cerr << "ModuleAnalyzer::handleType, type unknown: '"
69 << T->getName() << "'\n";
73 return processType(T);
77 bool ModuleAnalyzer::processConstPool(const ConstantPool &CP, bool isMethod) {
78 // TypeSet - Keep track of which types have already been processType'ed. We
79 // don't want to reprocess the same type more than once.
81 set<const Type *> TypeSet;
83 for (ConstantPool::plane_const_iterator PI = CP.begin();
84 PI != CP.end(); ++PI) {
85 const ConstantPool::PlaneType &Plane = **PI;
86 if (Plane.empty()) continue; // Skip empty type planes...
88 if (processConstPoolPlane(CP, Plane, isMethod)) return true;
90 for (ConstantPool::PlaneType::const_iterator CI = Plane.begin();
91 CI != Plane.end(); ++CI) {
92 if ((*CI)->getType() == Type::TypeTy)
93 if (handleType(TypeSet, ((const ConstPoolType*)(*CI))->getValue()))
95 if (handleType(TypeSet, (*CI)->getType())) return true;
97 if (processConstant(*CI)) return true;
102 const Module *M = CP.getParentV()->castModuleAsserting();
103 // Process the method types after the constant pool...
104 for (Module::const_iterator I = M->begin(); I != M->end(); ++I) {
105 if (handleType(TypeSet, (*I)->getType())) return true;
106 if (visitMethod(*I)) return true;
112 bool ModuleAnalyzer::processMethods(const Module *M) {
113 return apply_until(M->begin(), M->end(),
114 bind_obj(this, &ModuleAnalyzer::processMethod));
117 bool ModuleAnalyzer::processMethod(const Method *M) {
118 // Loop over the arguments, processing them...
119 if (apply_until(M->getArgumentList().begin(), M->getArgumentList().end(),
120 bind_obj(this, &ModuleAnalyzer::processMethodArgument)))
123 // Loop over the constant pool, adding the constants to the table...
124 processConstPool(M->getConstantPool(), true);
126 // Loop over all the basic blocks, in order...
127 return apply_until(M->begin(), M->end(),
128 bind_obj(this, &ModuleAnalyzer::processBasicBlock));
131 bool ModuleAnalyzer::processBasicBlock(const BasicBlock *BB) {
132 // Process all of the instructions in the basic block
133 BasicBlock::const_iterator Inst = BB->begin();
134 for (; Inst != BB->end(); Inst++) {
135 if (preProcessInstruction(*Inst) || processInstruction(*Inst)) return true;
140 bool ModuleAnalyzer::preProcessInstruction(const Instruction *I) {