aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/include/llvm/Transforms/IPO/PassManagerBuilder.h
blob: e0c72dc9672239b9b4d84c9492be1683fb6d0e90 (plain) (blame)
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#pragma once

#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-parameter"
#endif

// llvm/Transforms/IPO/PassManagerBuilder.h - Build Standard Pass -*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines the PassManagerBuilder class, which is used to set up a
// "standard" optimization sequence suitable for languages like C and C++.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H
#define LLVM_TRANSFORMS_IPO_PASSMANAGERBUILDER_H

#include "llvm-c/Transforms/PassManagerBuilder.h"
#include <functional>
#include <memory>
#include <string>
#include <vector>

namespace llvm {
class ModuleSummaryIndex;
class Pass;
class TargetLibraryInfoImpl;

// The old pass manager infrastructure is hidden in a legacy namespace now.
namespace legacy {
class FunctionPassManager;
class PassManagerBase;
}

/// PassManagerBuilder - This class is used to set up a standard optimization
/// sequence for languages like C and C++, allowing some APIs to customize the
/// pass sequence in various ways. A simple example of using it would be:
///
///  PassManagerBuilder Builder;
///  Builder.OptLevel = 2;
///  Builder.populateFunctionPassManager(FPM);
///  Builder.populateModulePassManager(MPM);
///
/// In addition to setting up the basic passes, PassManagerBuilder allows
/// frontends to vend a plugin API, where plugins are allowed to add extensions
/// to the default pass manager.  They do this by specifying where in the pass
/// pipeline they want to be added, along with a callback function that adds
/// the pass(es).  For example, a plugin that wanted to add a loop optimization
/// could do something like this:
///
/// static void addMyLoopPass(const PMBuilder &Builder, PassManagerBase &PM) {
///   if (Builder.getOptLevel() > 2 && Builder.getOptSizeLevel() == 0)
///     PM.add(createMyAwesomePass());
/// }
///   ...
///   Builder.addExtension(PassManagerBuilder::EP_LoopOptimizerEnd,
///                        addMyLoopPass);
///   ...
class PassManagerBuilder {
public:
  /// Extensions are passed to the builder itself (so they can see how it is
  /// configured) as well as the pass manager to add stuff to.
  typedef std::function<void(const PassManagerBuilder &Builder,
                             legacy::PassManagerBase &PM)>
      ExtensionFn;
  typedef int GlobalExtensionID;

  enum ExtensionPointTy {
    /// EP_EarlyAsPossible - This extension point allows adding passes before
    /// any other transformations, allowing them to see the code as it is coming
    /// out of the frontend.
    EP_EarlyAsPossible,

    /// EP_ModuleOptimizerEarly - This extension point allows adding passes
    /// just before the main module-level optimization passes.
    EP_ModuleOptimizerEarly,

    /// EP_LoopOptimizerEnd - This extension point allows adding loop passes to
    /// the end of the loop optimizer.
    EP_LoopOptimizerEnd,

    /// EP_ScalarOptimizerLate - This extension point allows adding optimization
    /// passes after most of the main optimizations, but before the last
    /// cleanup-ish optimizations.
    EP_ScalarOptimizerLate,

    /// EP_OptimizerLast -- This extension point allows adding passes that
    /// run after everything else.
    EP_OptimizerLast,

    /// EP_VectorizerStart - This extension point allows adding optimization
    /// passes before the vectorizer and other highly target specific
    /// optimization passes are executed.
    EP_VectorizerStart,

    /// EP_EnabledOnOptLevel0 - This extension point allows adding passes that
    /// should not be disabled by O0 optimization level. The passes will be
    /// inserted after the inlining pass.
    EP_EnabledOnOptLevel0,

    /// EP_Peephole - This extension point allows adding passes that perform
    /// peephole optimizations similar to the instruction combiner. These passes
    /// will be inserted after each instance of the instruction combiner pass.
    EP_Peephole,

    /// EP_LateLoopOptimizations - This extension point allows adding late loop
    /// canonicalization and simplification passes. This is the last point in
    /// the loop optimization pipeline before loop deletion. Each pass added
    /// here must be an instance of LoopPass.
    /// This is the place to add passes that can remove loops, such as target-
    /// specific loop idiom recognition.
    EP_LateLoopOptimizations,

    /// EP_CGSCCOptimizerLate - This extension point allows adding CallGraphSCC
    /// passes at the end of the main CallGraphSCC passes and before any
    /// function simplification passes run by CGPassManager.
    EP_CGSCCOptimizerLate,

    /// EP_FullLinkTimeOptimizationEarly - This extensions point allow adding
    /// passes that
    /// run at Link Time, before Full Link Time Optimization.
    EP_FullLinkTimeOptimizationEarly,

    /// EP_FullLinkTimeOptimizationLast - This extensions point allow adding
    /// passes that
    /// run at Link Time, after Full Link Time Optimization.
    EP_FullLinkTimeOptimizationLast,
  };

  /// The Optimization Level - Specify the basic optimization level.
  ///    0 = -O0, 1 = -O1, 2 = -O2, 3 = -O3
  unsigned OptLevel;

  /// SizeLevel - How much we're optimizing for size.
  ///    0 = none, 1 = -Os, 2 = -Oz
  unsigned SizeLevel;

  /// LibraryInfo - Specifies information about the runtime library for the
  /// optimizer.  If this is non-null, it is added to both the function and
  /// per-module pass pipeline.
  TargetLibraryInfoImpl *LibraryInfo;

  /// Inliner - Specifies the inliner to use.  If this is non-null, it is
  /// added to the per-module passes.
  Pass *Inliner;

  /// The module summary index to use for exporting information from the
  /// regular LTO phase, for example for the CFI and devirtualization type
  /// tests.
  ModuleSummaryIndex *ExportSummary = nullptr;

  /// The module summary index to use for importing information to the
  /// thin LTO backends, for example for the CFI and devirtualization type
  /// tests.
  const ModuleSummaryIndex *ImportSummary = nullptr;

  bool DisableUnrollLoops;
  bool CallGraphProfile;
  bool SLPVectorize;
  bool LoopVectorize;
  bool LoopsInterleaved;
  bool RerollLoops;
  bool NewGVN;
  bool DisableGVNLoadPRE;
  bool ForgetAllSCEVInLoopUnroll;
  bool VerifyInput;
  bool VerifyOutput;
  bool MergeFunctions;
  bool PrepareForLTO;
  bool PrepareForThinLTO;
  bool PerformThinLTO;
  bool DivergentTarget;
  unsigned LicmMssaOptCap;
  unsigned LicmMssaNoAccForPromotionCap;

  /// Enable profile instrumentation pass.
  bool EnablePGOInstrGen;
  /// Enable profile context sensitive instrumentation pass.
  bool EnablePGOCSInstrGen;
  /// Enable profile context sensitive profile use pass.
  bool EnablePGOCSInstrUse;
  /// Profile data file name that the instrumentation will be written to.
  std::string PGOInstrGen;
  /// Path of the profile data file.
  std::string PGOInstrUse;
  /// Path of the sample Profile data file.
  std::string PGOSampleUse;

private:
  /// ExtensionList - This is list of all of the extensions that are registered.
  std::vector<std::pair<ExtensionPointTy, ExtensionFn>> Extensions;

public:
  PassManagerBuilder();
  ~PassManagerBuilder();
  /// Adds an extension that will be used by all PassManagerBuilder instances.
  /// This is intended to be used by plugins, to register a set of
  /// optimisations to run automatically.
  ///
  /// \returns A global extension identifier that can be used to remove the
  /// extension.
  static GlobalExtensionID addGlobalExtension(ExtensionPointTy Ty,
                                              ExtensionFn Fn);
  /// Removes an extension that was previously added using addGlobalExtension.
  /// This is also intended to be used by plugins, to remove any extension that
  /// was previously registered before being unloaded.
  ///
  /// \param ExtensionID Identifier of the extension to be removed.
  static void removeGlobalExtension(GlobalExtensionID ExtensionID);
  void addExtension(ExtensionPointTy Ty, ExtensionFn Fn);

private:
  void addExtensionsToPM(ExtensionPointTy ETy,
                         legacy::PassManagerBase &PM) const;
  void addInitialAliasAnalysisPasses(legacy::PassManagerBase &PM) const;
  void addLTOOptimizationPasses(legacy::PassManagerBase &PM);
  void addLateLTOOptimizationPasses(legacy::PassManagerBase &PM);
  void addPGOInstrPasses(legacy::PassManagerBase &MPM, bool IsCS);
  void addFunctionSimplificationPasses(legacy::PassManagerBase &MPM);
  void addVectorPasses(legacy::PassManagerBase &PM, bool IsFullLTO);

public:
  /// populateFunctionPassManager - This fills in the function pass manager,
  /// which is expected to be run on each function immediately as it is
  /// generated.  The idea is to reduce the size of the IR in memory.
  void populateFunctionPassManager(legacy::FunctionPassManager &FPM);

  /// populateModulePassManager - This sets up the primary pass manager.
  void populateModulePassManager(legacy::PassManagerBase &MPM);
  void populateLTOPassManager(legacy::PassManagerBase &PM);
  void populateThinLTOPassManager(legacy::PassManagerBase &PM);
};

/// Registers a function for adding a standard set of passes.  This should be
/// used by optimizer plugins to allow all front ends to transparently use
/// them.  Create a static instance of this class in your plugin, providing a
/// private function that the PassManagerBuilder can use to add your passes.
class RegisterStandardPasses {
  PassManagerBuilder::GlobalExtensionID ExtensionID;

public:
  RegisterStandardPasses(PassManagerBuilder::ExtensionPointTy Ty,
                         PassManagerBuilder::ExtensionFn Fn) {
    ExtensionID = PassManagerBuilder::addGlobalExtension(Ty, std::move(Fn));
  }

  ~RegisterStandardPasses() {
    // If the collection holding the global extensions is destroyed after the
    // plugin is unloaded, the extension has to be removed here. Indeed, the
    // destructor of the ExtensionFn may reference code in the plugin.
    PassManagerBuilder::removeGlobalExtension(ExtensionID);
  }
};

inline PassManagerBuilder *unwrap(LLVMPassManagerBuilderRef P) {
    return reinterpret_cast<PassManagerBuilder*>(P);
}

inline LLVMPassManagerBuilderRef wrap(PassManagerBuilder *P) {
  return reinterpret_cast<LLVMPassManagerBuilderRef>(P);
}

} // end namespace llvm
#endif

#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif