[Modules] Include the header needed for make_unique, otherwise we can't
[oota-llvm.git] / include / llvm / IR / PassManagerInternal.h
1 //===- PassManager internal APIs and implementation details -----*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This header provides internal APIs and implementation details used by the
12 /// pass management interfaces exposed in PassManager.h. To understand more
13 /// context of why these particular interfaces are needed, see that header
14 /// file. None of these APIs should be used elsewhere.
15 ///
16 //===----------------------------------------------------------------------===//
17
18 #ifndef LLVM_IR_PASSMANAGERINTERNAL_H
19 #define LLVM_IR_PASSMANAGERINTERNAL_H
20
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/ADT/STLExtras.h"
23
24 namespace llvm {
25
26 template <typename IRUnitT> class AnalysisManager;
27 class PreservedAnalyses;
28
29 /// \brief Implementation details of the pass manager interfaces.
30 namespace detail {
31
32 /// \brief Template for the abstract base class used to dispatch
33 /// polymorphically over pass objects.
34 template <typename IRUnitT> struct PassConcept {
35   // Boiler plate necessary for the container of derived classes.
36   virtual ~PassConcept() {}
37
38   /// \brief The polymorphic API which runs the pass over a given IR entity.
39   ///
40   /// Note that actual pass object can omit the analysis manager argument if
41   /// desired. Also that the analysis manager may be null if there is no
42   /// analysis manager in the pass pipeline.
43   virtual PreservedAnalyses run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) = 0;
44
45   /// \brief Polymorphic method to access the name of a pass.
46   virtual StringRef name() = 0;
47 };
48
49 /// \brief SFINAE metafunction for computing whether \c PassT has a run method
50 /// accepting an \c AnalysisManager<IRUnitT>.
51 template <typename IRUnitT, typename PassT, typename ResultT>
52 class PassRunAcceptsAnalysisManager {
53   typedef char SmallType;
54   struct BigType {
55     char a, b;
56   };
57
58   template <typename T, ResultT (T::*)(IRUnitT &, AnalysisManager<IRUnitT> *)>
59   struct Checker;
60
61   template <typename T> static SmallType f(Checker<T, &T::run> *);
62   template <typename T> static BigType f(...);
63
64 public:
65   enum { Value = sizeof(f<PassT>(nullptr)) == sizeof(SmallType) };
66 };
67
68 /// \brief A template wrapper used to implement the polymorphic API.
69 ///
70 /// Can be instantiated for any object which provides a \c run method accepting
71 /// an \c IRUnitT. It requires the pass to be a copyable object. When the
72 /// \c run method also accepts an \c AnalysisManager<IRUnitT>*, we pass it
73 /// along.
74 template <typename IRUnitT, typename PassT,
75           typename PreservedAnalysesT = PreservedAnalyses,
76           bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
77               IRUnitT, PassT, PreservedAnalysesT>::Value>
78 struct PassModel;
79
80 /// \brief Specialization of \c PassModel for passes that accept an analyis
81 /// manager.
82 template <typename IRUnitT, typename PassT, typename PreservedAnalysesT>
83 struct PassModel<IRUnitT, PassT, PreservedAnalysesT, true>
84     : PassConcept<IRUnitT> {
85   explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
86   // We have to explicitly define all the special member functions because MSVC
87   // refuses to generate them.
88   PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
89   PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
90   friend void swap(PassModel &LHS, PassModel &RHS) {
91     using std::swap;
92     swap(LHS.Pass, RHS.Pass);
93   }
94   PassModel &operator=(PassModel RHS) {
95     swap(*this, RHS);
96     return *this;
97   }
98
99   PreservedAnalysesT run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) override {
100     return Pass.run(IR, AM);
101   }
102   StringRef name() override { return PassT::name(); }
103   PassT Pass;
104 };
105
106 /// \brief Specialization of \c PassModel for passes that accept an analyis
107 /// manager.
108 template <typename IRUnitT, typename PassT, typename PreservedAnalysesT>
109 struct PassModel<IRUnitT, PassT, PreservedAnalysesT, false>
110     : PassConcept<IRUnitT> {
111   explicit PassModel(PassT Pass) : Pass(std::move(Pass)) {}
112   // We have to explicitly define all the special member functions because MSVC
113   // refuses to generate them.
114   PassModel(const PassModel &Arg) : Pass(Arg.Pass) {}
115   PassModel(PassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
116   friend void swap(PassModel &LHS, PassModel &RHS) {
117     using std::swap;
118     swap(LHS.Pass, RHS.Pass);
119   }
120   PassModel &operator=(PassModel RHS) {
121     swap(*this, RHS);
122     return *this;
123   }
124
125   PreservedAnalysesT run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) override {
126     return Pass.run(IR);
127   }
128   StringRef name() override { return PassT::name(); }
129   PassT Pass;
130 };
131
132 /// \brief Abstract concept of an analysis result.
133 ///
134 /// This concept is parameterized over the IR unit that this result pertains
135 /// to.
136 template <typename IRUnitT> struct AnalysisResultConcept {
137   virtual ~AnalysisResultConcept() {}
138
139   /// \brief Method to try and mark a result as invalid.
140   ///
141   /// When the outer analysis manager detects a change in some underlying
142   /// unit of the IR, it will call this method on all of the results cached.
143   ///
144   /// This method also receives a set of preserved analyses which can be used
145   /// to avoid invalidation because the pass which changed the underlying IR
146   /// took care to update or preserve the analysis result in some way.
147   ///
148   /// \returns true if the result is indeed invalid (the default).
149   virtual bool invalidate(IRUnitT &IR, const PreservedAnalyses &PA) = 0;
150 };
151
152 /// \brief SFINAE metafunction for computing whether \c ResultT provides an
153 /// \c invalidate member function.
154 template <typename IRUnitT, typename ResultT> class ResultHasInvalidateMethod {
155   typedef char SmallType;
156   struct BigType {
157     char a, b;
158   };
159
160   template <typename T, bool (T::*)(IRUnitT &, const PreservedAnalyses &)>
161   struct Checker;
162
163   template <typename T> static SmallType f(Checker<T, &T::invalidate> *);
164   template <typename T> static BigType f(...);
165
166 public:
167   enum { Value = sizeof(f<ResultT>(nullptr)) == sizeof(SmallType) };
168 };
169
170 /// \brief Wrapper to model the analysis result concept.
171 ///
172 /// By default, this will implement the invalidate method with a trivial
173 /// implementation so that the actual analysis result doesn't need to provide
174 /// an invalidation handler. It is only selected when the invalidation handler
175 /// is not part of the ResultT's interface.
176 template <typename IRUnitT, typename PassT, typename ResultT,
177           typename PreservedAnalysesT = PreservedAnalyses,
178           bool HasInvalidateHandler =
179               ResultHasInvalidateMethod<IRUnitT, ResultT>::Value>
180 struct AnalysisResultModel;
181
182 /// \brief Specialization of \c AnalysisResultModel which provides the default
183 /// invalidate functionality.
184 template <typename IRUnitT, typename PassT, typename ResultT,
185           typename PreservedAnalysesT>
186 struct AnalysisResultModel<IRUnitT, PassT, ResultT, PreservedAnalysesT, false>
187     : AnalysisResultConcept<IRUnitT> {
188   explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
189   // We have to explicitly define all the special member functions because MSVC
190   // refuses to generate them.
191   AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
192   AnalysisResultModel(AnalysisResultModel &&Arg)
193       : Result(std::move(Arg.Result)) {}
194   friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
195     using std::swap;
196     swap(LHS.Result, RHS.Result);
197   }
198   AnalysisResultModel &operator=(AnalysisResultModel RHS) {
199     swap(*this, RHS);
200     return *this;
201   }
202
203   /// \brief The model bases invalidation solely on being in the preserved set.
204   //
205   // FIXME: We should actually use two different concepts for analysis results
206   // rather than two different models, and avoid the indirect function call for
207   // ones that use the trivial behavior.
208   bool invalidate(IRUnitT &, const PreservedAnalysesT &PA) override {
209     return !PA.preserved(PassT::ID());
210   }
211
212   ResultT Result;
213 };
214
215 /// \brief Specialization of \c AnalysisResultModel which delegates invalidate
216 /// handling to \c ResultT.
217 template <typename IRUnitT, typename PassT, typename ResultT,
218           typename PreservedAnalysesT>
219 struct AnalysisResultModel<IRUnitT, PassT, ResultT, PreservedAnalysesT, true>
220     : AnalysisResultConcept<IRUnitT> {
221   explicit AnalysisResultModel(ResultT Result) : Result(std::move(Result)) {}
222   // We have to explicitly define all the special member functions because MSVC
223   // refuses to generate them.
224   AnalysisResultModel(const AnalysisResultModel &Arg) : Result(Arg.Result) {}
225   AnalysisResultModel(AnalysisResultModel &&Arg)
226       : Result(std::move(Arg.Result)) {}
227   friend void swap(AnalysisResultModel &LHS, AnalysisResultModel &RHS) {
228     using std::swap;
229     swap(LHS.Result, RHS.Result);
230   }
231   AnalysisResultModel &operator=(AnalysisResultModel RHS) {
232     swap(*this, RHS);
233     return *this;
234   }
235
236   /// \brief The model delegates to the \c ResultT method.
237   bool invalidate(IRUnitT &IR, const PreservedAnalysesT &PA) override {
238     return Result.invalidate(IR, PA);
239   }
240
241   ResultT Result;
242 };
243
244 /// \brief Abstract concept of an analysis pass.
245 ///
246 /// This concept is parameterized over the IR unit that it can run over and
247 /// produce an analysis result.
248 template <typename IRUnitT> struct AnalysisPassConcept {
249   virtual ~AnalysisPassConcept() {}
250
251   /// \brief Method to run this analysis over a unit of IR.
252   /// \returns A unique_ptr to the analysis result object to be queried by
253   /// users.
254   virtual std::unique_ptr<AnalysisResultConcept<IRUnitT>>
255   run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) = 0;
256
257   /// \brief Polymorphic method to access the name of a pass.
258   virtual StringRef name() = 0;
259 };
260
261 /// \brief Wrapper to model the analysis pass concept.
262 ///
263 /// Can wrap any type which implements a suitable \c run method. The method
264 /// must accept the IRUnitT as an argument and produce an object which can be
265 /// wrapped in a \c AnalysisResultModel.
266 template <typename IRUnitT, typename PassT,
267           bool AcceptsAnalysisManager = PassRunAcceptsAnalysisManager<
268               IRUnitT, PassT, typename PassT::Result>::Value>
269 struct AnalysisPassModel;
270
271 /// \brief Specialization of \c AnalysisPassModel which passes an
272 /// \c AnalysisManager to PassT's run method.
273 template <typename IRUnitT, typename PassT>
274 struct AnalysisPassModel<IRUnitT, PassT, true> : AnalysisPassConcept<IRUnitT> {
275   explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
276   // We have to explicitly define all the special member functions because MSVC
277   // refuses to generate them.
278   AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
279   AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
280   friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
281     using std::swap;
282     swap(LHS.Pass, RHS.Pass);
283   }
284   AnalysisPassModel &operator=(AnalysisPassModel RHS) {
285     swap(*this, RHS);
286     return *this;
287   }
288
289   // FIXME: Replace PassT::Result with type traits when we use C++11.
290   typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
291       ResultModelT;
292
293   /// \brief The model delegates to the \c PassT::run method.
294   ///
295   /// The return is wrapped in an \c AnalysisResultModel.
296   std::unique_ptr<AnalysisResultConcept<IRUnitT>>
297   run(IRUnitT &IR, AnalysisManager<IRUnitT> *AM) override {
298     return make_unique<ResultModelT>(Pass.run(IR, AM));
299   }
300
301   /// \brief The model delegates to a static \c PassT::name method.
302   ///
303   /// The returned string ref must point to constant immutable data!
304   StringRef name() override { return PassT::name(); }
305
306   PassT Pass;
307 };
308
309 /// \brief Specialization of \c AnalysisPassModel which does not pass an
310 /// \c AnalysisManager to PassT's run method.
311 template <typename IRUnitT, typename PassT>
312 struct AnalysisPassModel<IRUnitT, PassT, false> : AnalysisPassConcept<IRUnitT> {
313   explicit AnalysisPassModel(PassT Pass) : Pass(std::move(Pass)) {}
314   // We have to explicitly define all the special member functions because MSVC
315   // refuses to generate them.
316   AnalysisPassModel(const AnalysisPassModel &Arg) : Pass(Arg.Pass) {}
317   AnalysisPassModel(AnalysisPassModel &&Arg) : Pass(std::move(Arg.Pass)) {}
318   friend void swap(AnalysisPassModel &LHS, AnalysisPassModel &RHS) {
319     using std::swap;
320     swap(LHS.Pass, RHS.Pass);
321   }
322   AnalysisPassModel &operator=(AnalysisPassModel RHS) {
323     swap(*this, RHS);
324     return *this;
325   }
326
327   // FIXME: Replace PassT::Result with type traits when we use C++11.
328   typedef AnalysisResultModel<IRUnitT, PassT, typename PassT::Result>
329       ResultModelT;
330
331   /// \brief The model delegates to the \c PassT::run method.
332   ///
333   /// The return is wrapped in an \c AnalysisResultModel.
334   std::unique_ptr<AnalysisResultConcept<IRUnitT>>
335   run(IRUnitT &IR, AnalysisManager<IRUnitT> *) override {
336     return make_unique<ResultModelT>(Pass.run(IR));
337   }
338
339   /// \brief The model delegates to a static \c PassT::name method.
340   ///
341   /// The returned string ref must point to constant immutable data!
342   StringRef name() override { return PassT::name(); }
343
344   PassT Pass;
345 };
346
347 } // End namespace detail
348 }
349
350 #endif