summaryrefslogtreecommitdiff
path: root/include/llvm/PassAnalysisSupport.h
blob: 5a716411d353f650d1a8c2c1d642730837b17580 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//===- llvm/PassAnalysisSupport.h - Analysis Pass Support code --*- C++ -*-===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
//
// This file defines stuff that is used to define and "use" Analysis Passes.
// This file is automatically #included by Pass.h, so:
//
//           NO .CPP FILES SHOULD INCLUDE THIS FILE DIRECTLY
//
// Instead, #include Pass.h
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_PASS_ANALYSIS_SUPPORT_H
#define LLVM_PASS_ANALYSIS_SUPPORT_H

namespace llvm {

// No need to include Pass.h, we are being included by it!

//===----------------------------------------------------------------------===//
// AnalysisUsage - Represent the analysis usage information of a pass.  This
// tracks analyses that the pass REQUIRES (must be available when the pass 
// runs), REQUIRES TRANSITIVE (must be available throughout the lifetime of the
// pass), and analyses that the pass PRESERVES (the pass does not invalidate the
// results of these analyses).  This information is provided by a pass to the 
// Pass infrastructure through the getAnalysisUsage virtual function.
//
class AnalysisUsage {
  // Sets of analyses required and preserved by a pass
  std::vector<AnalysisID> Required, RequiredTransitive, Preserved;
  bool PreservesAll;
public:
  AnalysisUsage() : PreservesAll(false) {}
  
  // addRequired - Add the specified ID to the required set of the usage info
  // for a pass.
  //
  AnalysisUsage &addRequiredID(AnalysisID ID) {
    Required.push_back(ID);
    return *this;
  }
  template<class PassClass>
  AnalysisUsage &addRequired() {
    assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!");
    Required.push_back(Pass::getClassPassInfo<PassClass>());
    return *this;
  }

  template<class PassClass>
  AnalysisUsage &addRequiredTransitive() {
    AnalysisID ID = Pass::getClassPassInfo<PassClass>();
    assert(ID && "Pass class not registered!");
    Required.push_back(ID);
    RequiredTransitive.push_back(ID);
    return *this;
  }

  // addPreserved - Add the specified ID to the set of analyses preserved by
  // this pass
  //
  AnalysisUsage &addPreservedID(AnalysisID ID) {
    Preserved.push_back(ID);
    return *this;
  }

  template<class PassClass>
  AnalysisUsage &addPreserved() {
    assert(Pass::getClassPassInfo<PassClass>() && "Pass class not registered!");
    Preserved.push_back(Pass::getClassPassInfo<PassClass>());
    return *this;
  }

  // setPreservesAll - Set by analyses that do not transform their input at all
  void setPreservesAll() { PreservesAll = true; }
  bool getPreservesAll() const { return PreservesAll; }

  /// setPreservesCFG - This function should be called by the pass, iff they do
  /// not:
  ///
  ///  1. Add or remove basic blocks from the function
  ///  2. Modify terminator instructions in any way.
  ///
  /// This function annotates the AnalysisUsage info object to say that analyses
  /// that only depend on the CFG are preserved by this pass.
  ///
  void setPreservesCFG();

  const std::vector<AnalysisID> &getRequiredSet() const { return Required; }
  const std::vector<AnalysisID> &getRequiredTransitiveSet() const {
    return RequiredTransitive;
  }
  const std::vector<AnalysisID> &getPreservedSet() const { return Preserved; }
};



//===----------------------------------------------------------------------===//
// AnalysisResolver - Simple interface implemented by PassManager objects that
// is used to pull analysis information out of them.
//
struct AnalysisResolver {
  virtual Pass *getAnalysisOrNullUp(AnalysisID ID) const = 0;
  virtual Pass *getAnalysisOrNullDown(AnalysisID ID) const = 0;
  virtual void addPass(ImmutablePass *IP, AnalysisUsage &AU) = 0;
  Pass *getAnalysis(AnalysisID ID) const {
    Pass *Result = getAnalysisOrNullUp(ID);
    assert(Result && "Pass has an incorrect analysis uses set!");
    return Result;
  }

  // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
  Pass *getAnalysisToUpdate(AnalysisID ID) const {
    return getAnalysisOrNullUp(ID);
  }

  // Methods for introspecting into pass manager objects...
  virtual unsigned getDepth() const = 0;
  virtual unsigned getNumContainedPasses() const = 0;
  virtual const Pass *getContainedPass(unsigned N) const = 0;

  virtual void markPassUsed(AnalysisID P, Pass *User) = 0;

  void startPass(Pass *P) {}
  void endPass(Pass *P) {}
protected:
  void setAnalysisResolver(Pass *P, AnalysisResolver *AR);
};

/// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
/// to get to the analysis information that might be around that needs to be
/// updated.  This is different than getAnalysis in that it can fail (ie the
/// analysis results haven't been computed), so should only be used if you
/// provide the capability to update an analysis that exists.  This method is
/// often used by transformation APIs to update analysis results for a pass
/// automatically as the transform is performed.
///
template<typename AnalysisType>
AnalysisType *Pass::getAnalysisToUpdate() const {
  assert(Resolver && "Pass not resident in a PassManager object!");
  const PassInfo *PI = getClassPassInfo<AnalysisType>();
  if (PI == 0) return 0;
  return dynamic_cast<AnalysisType*>(Resolver->getAnalysisToUpdate(PI));
}

} // End llvm namespace

#endif