aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore/Pass.cpp
blob: 2f2fd0e2116bbd59e1a54c211906a27014379ff5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//===- Pass.cpp - LLVM Pass Infrastructure Impementation ------------------===//
//
// This file implements the LLVM Pass infrastructure.  It is primarily
// responsible with ensuring that passes are executed and batched together
// optimally.
//
//===----------------------------------------------------------------------===//

#include "llvm/Pass.h"
#include "Support/STLExtras.h"

PassManager::~PassManager() {
  for_each(Passes.begin(), Passes.end(), deleter<Pass>);
}

class BasicBlockPassBatcher : public MethodPass {
  typedef std::vector<BasicBlockPass*> SubPassesType;
  SubPassesType SubPasses;
public:
  ~BasicBlockPassBatcher() {
    for_each(SubPasses.begin(), SubPasses.end(), deleter<BasicBlockPass>);
  }

  void add(BasicBlockPass *P) { SubPasses.push_back(P); }

  virtual bool doPassInitialization(Module *M) {
    bool Changed = false;
    for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
         I != E; ++I)
      Changed |= (*I)->doInitialization(M);
    return Changed;
  }

  virtual bool runOnMethod(Method *M) {
    bool Changed = false;

    for (Method::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
      for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
           I != E; ++I)
        Changed |= (*I)->runOnBasicBlock(*MI);
    return Changed;
  }

  virtual bool doFinalization(Module *M) {
    bool Changed = false;
    for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
         I != E; ++I)
      Changed |= (*I)->doFinalization(M);

    return Changed;
  }
};

class MethodPassBatcher : public Pass {
  typedef std::vector<MethodPass*> SubPassesType;
  SubPassesType SubPasses;
  BasicBlockPassBatcher *BBPBatcher;
public:
  ~MethodPassBatcher() {
    for_each(SubPasses.begin(), SubPasses.end(), deleter<MethodPass>);
  }

  void add(MethodPass *P) {
    if (BasicBlockPass *BBP = dynamic_cast<BasicBlockPass*>(P)) {
      if (BBPBatcher == 0) {
        BBPBatcher = new BasicBlockPassBatcher();
        SubPasses.push_back(BBPBatcher);
      }
      BBPBatcher->add(BBP);
    } else {
      BBPBatcher = 0;  // Ensure that passes don't get accidentally reordered
      SubPasses.push_back(P);
    }
  }

  virtual bool run(Module *M) {
    bool Changed = false;
    for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
         I != E; ++I)
      Changed |= (*I)->doInitialization(M);

    for (Module::iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI)
      for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
           I != E; ++I)
        Changed |= (*I)->runOnMethod(*MI);

    for (SubPassesType::iterator I = SubPasses.begin(), E = SubPasses.end();
         I != E; ++I)
      Changed |= (*I)->doFinalization(M);

    return Changed;
  }
};




// add(MethodPass*) - MethodPass's must be batched together... make sure this
// happens now.
//
void PassManager::add(MethodPass *MP) {
  if (Batcher == 0) { // If we don't have a batcher yet, make one now.
    Batcher = new MethodPassBatcher();
    Passes.push_back(Batcher);
  }
  Batcher->add(MP);   // The Batcher will queue them passes up
}

// add - Add a pass to the PassManager, batching it up as appropriate...
void PassManager::add(Pass *P) {
  if (MethodPass *MP = dynamic_cast<MethodPass*>(P)) {
    add(MP);  // Use the methodpass specific code to do the addition
  } else {
    Batcher = 0;  // Ensure that passes don't get accidentally reordered
    Passes.push_back(P);
  }
}