blob: 129fb3b86213d4fc2024988908a98774d7bfc6f7 [file] [log] [blame]
Chris Lattner2f7c9632001-06-06 20:29:01 +00001//===-- 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"
Chris Lattner2f7c9632001-06-06 20:29:01 +000010#include "llvm/Method.h"
11#include "llvm/Module.h"
12#include "llvm/BasicBlock.h"
13#include "llvm/DerivedTypes.h"
Chris Lattner5de22042001-11-27 00:03:19 +000014#include "Support/STLExtras.h"
Chris Lattner2f7c9632001-06-06 20:29:01 +000015#include <map>
16
17// processModule - Driver function to call all of my subclasses virtual methods.
18//
19bool ModuleAnalyzer::processModule(const Module *M) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000020 return processMethods(M);
21}
22
23inline 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: {
Chris Lattnerda558102001-10-02 03:41:24 +000048 const StructType *ST = cast<const StructType>(T);
Chris Lattner2f7c9632001-06-06 20:29:01 +000049 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:
Chris Lattner2413b162001-12-04 00:03:30 +000057 if (handleType(TypeSet, cast<const PointerType>(T)->getElementType()))
Chris Lattner2f7c9632001-06-06 20:29:01 +000058 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
Chris Lattner2f7c9632001-06-06 20:29:01 +000071bool ModuleAnalyzer::processMethods(const Module *M) {
Chris Lattner4cee8d82001-06-27 23:41:11 +000072 return apply_until(M->begin(), M->end(),
73 bind_obj(this, &ModuleAnalyzer::processMethod));
Chris Lattner2f7c9632001-06-06 20:29:01 +000074}
75
76bool ModuleAnalyzer::processMethod(const Method *M) {
77 // Loop over the arguments, processing them...
Chris Lattner4cee8d82001-06-27 23:41:11 +000078 if (apply_until(M->getArgumentList().begin(), M->getArgumentList().end(),
79 bind_obj(this, &ModuleAnalyzer::processMethodArgument)))
80 return true;
Chris Lattner2f7c9632001-06-06 20:29:01 +000081
Chris Lattner2f7c9632001-06-06 20:29:01 +000082 // Loop over all the basic blocks, in order...
Chris Lattner4cee8d82001-06-27 23:41:11 +000083 return apply_until(M->begin(), M->end(),
84 bind_obj(this, &ModuleAnalyzer::processBasicBlock));
Chris Lattner2f7c9632001-06-06 20:29:01 +000085}
86
87bool ModuleAnalyzer::processBasicBlock(const BasicBlock *BB) {
88 // Process all of the instructions in the basic block
Chris Lattner4cee8d82001-06-27 23:41:11 +000089 BasicBlock::const_iterator Inst = BB->begin();
90 for (; Inst != BB->end(); Inst++) {
Chris Lattner2f7c9632001-06-06 20:29:01 +000091 if (preProcessInstruction(*Inst) || processInstruction(*Inst)) return true;
92 }
93 return false;
94}
95
96bool ModuleAnalyzer::preProcessInstruction(const Instruction *I) {
97
98 return false;
99}