129fb3b86213d4fc2024988908a98774d7bfc6f7
[oota-llvm.git] / lib / Analysis / ModuleAnalyzer.cpp
1 //===-- llvm/Analysis/ModuleAnalyzer.cpp - Module analysis driver ----------==//
2 //
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.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/Analysis/ModuleAnalyzer.h"
10 #include "llvm/Method.h"
11 #include "llvm/Module.h"
12 #include "llvm/BasicBlock.h"
13 #include "llvm/DerivedTypes.h"
14 #include "Support/STLExtras.h"
15 #include <map>
16
17 // processModule - Driver function to call all of my subclasses virtual methods.
18 //
19 bool ModuleAnalyzer::processModule(const Module *M) {
20   return processMethods(M);
21 }
22
23 inline bool ModuleAnalyzer::handleType(set<const Type *> &TypeSet, 
24                                        const Type *T) {
25   if (!T->isDerivedType()) return false;    // Boring boring types...
26   if (TypeSet.count(T) != 0) return false;  // Already found this type...
27   TypeSet.insert(T);                        // Add it to the set
28   
29   // Recursively process interesting types...
30   switch (T->getPrimitiveID()) {
31   case Type::MethodTyID: {
32     const MethodType *MT = (const MethodType *)T;
33     if (handleType(TypeSet, MT->getReturnType())) return true;
34     const MethodType::ParamTypes &Params = MT->getParamTypes();
35
36     for (MethodType::ParamTypes::const_iterator I = Params.begin();
37          I != Params.end(); ++I)
38       if (handleType(TypeSet, *I)) return true;
39     break;
40   }
41
42   case Type::ArrayTyID:
43     if (handleType(TypeSet, ((const ArrayType *)T)->getElementType()))
44       return true;
45     break;
46
47   case Type::StructTyID: {
48     const StructType *ST = cast<const StructType>(T);
49     const StructType::ElementTypes &Elements = ST->getElementTypes();
50     for (StructType::ElementTypes::const_iterator I = Elements.begin();
51          I != Elements.end(); ++I)
52       if (handleType(TypeSet, *I)) return true;
53     break;
54   }
55
56   case Type::PointerTyID:
57     if (handleType(TypeSet, cast<const PointerType>(T)->getElementType()))
58       return true;
59     break;
60
61   default:
62     cerr << "ModuleAnalyzer::handleType, type unknown: '" 
63          << T->getName() << "'\n";
64     break;
65   }
66
67   return processType(T);
68 }
69
70
71 bool ModuleAnalyzer::processMethods(const Module *M) {
72   return apply_until(M->begin(), M->end(),
73                      bind_obj(this, &ModuleAnalyzer::processMethod));
74 }
75
76 bool ModuleAnalyzer::processMethod(const Method *M) {
77   // Loop over the arguments, processing them...
78   if (apply_until(M->getArgumentList().begin(), M->getArgumentList().end(),
79                   bind_obj(this, &ModuleAnalyzer::processMethodArgument)))
80     return true;
81
82   // Loop over all the basic blocks, in order...
83   return apply_until(M->begin(), M->end(),
84                      bind_obj(this, &ModuleAnalyzer::processBasicBlock));
85 }
86
87 bool ModuleAnalyzer::processBasicBlock(const BasicBlock *BB) {
88   // Process all of the instructions in the basic block
89   BasicBlock::const_iterator Inst = BB->begin();
90   for (; Inst != BB->end(); Inst++) {
91     if (preProcessInstruction(*Inst) || processInstruction(*Inst)) return true;
92   }
93   return false;
94 }
95
96 bool ModuleAnalyzer::preProcessInstruction(const Instruction *I) {
97   
98   return false;
99 }