Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===- PassManager.h --- Pass management for CodeGen ------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This header defines the pass manager interface for codegen. The codegen
10
// pipeline consists of only machine function passes. There is no container
11
// relationship between IR module/function and machine function in terms of pass
12
// manager organization. So there is no need for adaptor classes (for example
13
// ModuleToMachineFunctionAdaptor). Since invalidation could only happen among
14
// machine function passes, there is no proxy classes to handle cross-IR-unit
15
// invalidation. IR analysis results are provided for machine function passes by
16
// their respective analysis managers such as ModuleAnalysisManager and
17
// FunctionAnalysisManager.
18
//
19
// TODO: Add MachineFunctionProperties support.
20
//
21
//===----------------------------------------------------------------------===//
22
 
23
#ifndef LLVM_CODEGEN_MACHINEPASSMANAGER_H
24
#define LLVM_CODEGEN_MACHINEPASSMANAGER_H
25
 
26
#include "llvm/ADT/FunctionExtras.h"
27
#include "llvm/ADT/SmallVector.h"
28
#include "llvm/IR/PassManager.h"
29
#include "llvm/Support/Error.h"
30
 
31
#include <map>
32
 
33
namespace llvm {
34
class Module;
35
class Function;
36
class MachineFunction;
37
 
38
extern template class AnalysisManager<MachineFunction>;
39
 
40
/// An AnalysisManager<MachineFunction> that also exposes IR analysis results.
41
class MachineFunctionAnalysisManager : public AnalysisManager<MachineFunction> {
42
public:
43
  using Base = AnalysisManager<MachineFunction>;
44
 
45
  MachineFunctionAnalysisManager() : FAM(nullptr), MAM(nullptr) {}
46
  MachineFunctionAnalysisManager(FunctionAnalysisManager &FAM,
47
                                 ModuleAnalysisManager &MAM)
48
      : FAM(&FAM), MAM(&MAM) {}
49
  MachineFunctionAnalysisManager(MachineFunctionAnalysisManager &&) = default;
50
  MachineFunctionAnalysisManager &
51
  operator=(MachineFunctionAnalysisManager &&) = default;
52
 
53
  /// Get the result of an analysis pass for a Function.
54
  ///
55
  /// Runs the analysis if a cached result is not available.
56
  template <typename PassT> typename PassT::Result &getResult(Function &F) {
57
    return FAM->getResult<PassT>(F);
58
  }
59
 
60
  /// Get the cached result of an analysis pass for a Function.
61
  ///
62
  /// This method never runs the analysis.
63
  ///
64
  /// \returns null if there is no cached result.
65
  template <typename PassT>
66
  typename PassT::Result *getCachedResult(Function &F) {
67
    return FAM->getCachedResult<PassT>(F);
68
  }
69
 
70
  /// Get the result of an analysis pass for a Module.
71
  ///
72
  /// Runs the analysis if a cached result is not available.
73
  template <typename PassT> typename PassT::Result &getResult(Module &M) {
74
    return MAM->getResult<PassT>(M);
75
  }
76
 
77
  /// Get the cached result of an analysis pass for a Module.
78
  ///
79
  /// This method never runs the analysis.
80
  ///
81
  /// \returns null if there is no cached result.
82
  template <typename PassT> typename PassT::Result *getCachedResult(Module &M) {
83
    return MAM->getCachedResult<PassT>(M);
84
  }
85
 
86
  /// Get the result of an analysis pass for a MachineFunction.
87
  ///
88
  /// Runs the analysis if a cached result is not available.
89
  using Base::getResult;
90
 
91
  /// Get the cached result of an analysis pass for a MachineFunction.
92
  ///
93
  /// This method never runs the analysis.
94
  ///
95
  /// returns null if there is no cached result.
96
  using Base::getCachedResult;
97
 
98
  // FIXME: Add LoopAnalysisManager or CGSCCAnalysisManager if needed.
99
  FunctionAnalysisManager *FAM;
100
  ModuleAnalysisManager *MAM;
101
};
102
 
103
extern template class PassManager<MachineFunction>;
104
 
105
/// MachineFunctionPassManager adds/removes below features to/from the base
106
/// PassManager template instantiation.
107
///
108
/// - Support passes that implement doInitialization/doFinalization. This is for
109
///   machine function passes to work on module level constructs. One such pass
110
///   is AsmPrinter.
111
///
112
/// - Support machine module pass which runs over the module (for example,
113
///   MachineOutliner). A machine module pass needs to define the method:
114
///
115
///   ```Error run(Module &, MachineFunctionAnalysisManager &)```
116
///
117
///   FIXME: machine module passes still need to define the usual machine
118
///          function pass interface, namely,
119
///          `PreservedAnalyses run(MachineFunction &,
120
///                                 MachineFunctionAnalysisManager &)`
121
///          But this interface wouldn't be executed. It is just a placeholder
122
///          to satisfy the pass manager type-erased inteface. This
123
///          special-casing of machine module pass is due to its limited use
124
///          cases and the unnecessary complexity it may bring to the machine
125
///          pass manager.
126
///
127
/// - The base class `run` method is replaced by an alternative `run` method.
128
///   See details below.
129
///
130
/// - Support codegening in the SCC order. Users include interprocedural
131
///   register allocation (IPRA).
132
class MachineFunctionPassManager
133
    : public PassManager<MachineFunction, MachineFunctionAnalysisManager> {
134
  using Base = PassManager<MachineFunction, MachineFunctionAnalysisManager>;
135
 
136
public:
137
  MachineFunctionPassManager(bool DebugLogging = false,
138
                             bool RequireCodeGenSCCOrder = false,
139
                             bool VerifyMachineFunction = false)
140
      : RequireCodeGenSCCOrder(RequireCodeGenSCCOrder),
141
        VerifyMachineFunction(VerifyMachineFunction) {}
142
  MachineFunctionPassManager(MachineFunctionPassManager &&) = default;
143
  MachineFunctionPassManager &
144
  operator=(MachineFunctionPassManager &&) = default;
145
 
146
  /// Run machine passes for a Module.
147
  ///
148
  /// The intended use is to start the codegen pipeline for a Module. The base
149
  /// class's `run` method is deliberately hidden by this due to the observation
150
  /// that we don't yet have the use cases of compositing two instances of
151
  /// machine pass managers, or compositing machine pass managers with other
152
  /// types of pass managers.
153
  Error run(Module &M, MachineFunctionAnalysisManager &MFAM);
154
 
155
  template <typename PassT> void addPass(PassT &&Pass) {
156
    Base::addPass(std::forward<PassT>(Pass));
157
    PassConceptT *P = Passes.back().get();
158
    addDoInitialization<PassT>(P);
159
    addDoFinalization<PassT>(P);
160
 
161
    // Add machine module pass.
162
    addRunOnModule<PassT>(P);
163
  }
164
 
165
private:
166
  template <typename PassT>
167
  using has_init_t = decltype(std::declval<PassT &>().doInitialization(
168
      std::declval<Module &>(),
169
      std::declval<MachineFunctionAnalysisManager &>()));
170
 
171
  template <typename PassT>
172
  std::enable_if_t<!is_detected<has_init_t, PassT>::value>
173
  addDoInitialization(PassConceptT *Pass) {}
174
 
175
  template <typename PassT>
176
  std::enable_if_t<is_detected<has_init_t, PassT>::value>
177
  addDoInitialization(PassConceptT *Pass) {
178
    using PassModelT =
179
        detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
180
                          MachineFunctionAnalysisManager>;
181
    auto *P = static_cast<PassModelT *>(Pass);
182
    InitializationFuncs.emplace_back(
183
        [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
184
          return P->Pass.doInitialization(M, MFAM);
185
        });
186
  }
187
 
188
  template <typename PassT>
189
  using has_fini_t = decltype(std::declval<PassT &>().doFinalization(
190
      std::declval<Module &>(),
191
      std::declval<MachineFunctionAnalysisManager &>()));
192
 
193
  template <typename PassT>
194
  std::enable_if_t<!is_detected<has_fini_t, PassT>::value>
195
  addDoFinalization(PassConceptT *Pass) {}
196
 
197
  template <typename PassT>
198
  std::enable_if_t<is_detected<has_fini_t, PassT>::value>
199
  addDoFinalization(PassConceptT *Pass) {
200
    using PassModelT =
201
        detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
202
                          MachineFunctionAnalysisManager>;
203
    auto *P = static_cast<PassModelT *>(Pass);
204
    FinalizationFuncs.emplace_back(
205
        [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
206
          return P->Pass.doFinalization(M, MFAM);
207
        });
208
  }
209
 
210
  template <typename PassT>
211
  using is_machine_module_pass_t = decltype(std::declval<PassT &>().run(
212
      std::declval<Module &>(),
213
      std::declval<MachineFunctionAnalysisManager &>()));
214
 
215
  template <typename PassT>
216
  using is_machine_function_pass_t = decltype(std::declval<PassT &>().run(
217
      std::declval<MachineFunction &>(),
218
      std::declval<MachineFunctionAnalysisManager &>()));
219
 
220
  template <typename PassT>
221
  std::enable_if_t<!is_detected<is_machine_module_pass_t, PassT>::value>
222
  addRunOnModule(PassConceptT *Pass) {}
223
 
224
  template <typename PassT>
225
  std::enable_if_t<is_detected<is_machine_module_pass_t, PassT>::value>
226
  addRunOnModule(PassConceptT *Pass) {
227
    static_assert(is_detected<is_machine_function_pass_t, PassT>::value,
228
                  "machine module pass needs to define machine function pass "
229
                  "api. sorry.");
230
 
231
    using PassModelT =
232
        detail::PassModel<MachineFunction, PassT, PreservedAnalyses,
233
                          MachineFunctionAnalysisManager>;
234
    auto *P = static_cast<PassModelT *>(Pass);
235
    MachineModulePasses.emplace(
236
        Passes.size() - 1,
237
        [=](Module &M, MachineFunctionAnalysisManager &MFAM) {
238
          return P->Pass.run(M, MFAM);
239
        });
240
  }
241
 
242
  using FuncTy = Error(Module &, MachineFunctionAnalysisManager &);
243
  SmallVector<llvm::unique_function<FuncTy>, 4> InitializationFuncs;
244
  SmallVector<llvm::unique_function<FuncTy>, 4> FinalizationFuncs;
245
 
246
  using PassIndex = decltype(Passes)::size_type;
247
  std::map<PassIndex, llvm::unique_function<FuncTy>> MachineModulePasses;
248
 
249
  // Run codegen in the SCC order.
250
  bool RequireCodeGenSCCOrder;
251
 
252
  bool VerifyMachineFunction;
253
};
254
 
255
} // end namespace llvm
256
 
257
#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H