xref: /freebsd/contrib/llvm-project/llvm/include/llvm/Passes/PassBuilder.h (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- Parsing, selection, and construction of pass pipelines --*- 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 /// \file
9 ///
10 /// Interfaces for registering analysis passes, producing common pass manager
11 /// configurations, and parsing of pass pipelines.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_PASSES_PASSBUILDER_H
16 #define LLVM_PASSES_PASSBUILDER_H
17 
18 #include "llvm/Analysis/CGSCCPassManager.h"
19 #include "llvm/CodeGen/MachinePassManager.h"
20 #include "llvm/CodeGen/RegAllocCommon.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/Passes/OptimizationLevel.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/Error.h"
25 #include "llvm/Support/PGOOptions.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/Transforms/IPO/Inliner.h"
28 #include "llvm/Transforms/IPO/ModuleInliner.h"
29 #include "llvm/Transforms/Scalar/LoopPassManager.h"
30 #include <optional>
31 #include <vector>
32 
33 namespace llvm {
34 class StringRef;
35 class AAManager;
36 class TargetMachine;
37 class ModuleSummaryIndex;
38 template <typename T> class IntrusiveRefCntPtr;
39 namespace vfs {
40 class FileSystem;
41 } // namespace vfs
42 
43 /// Tunable parameters for passes in the default pipelines.
44 class PipelineTuningOptions {
45 public:
46   /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
47   /// can be set in the PassBuilder when using a LLVM as a library.
48   LLVM_ABI PipelineTuningOptions();
49 
50   /// Tuning option to set loop interleaving on/off, set based on opt level.
51   bool LoopInterleaving;
52 
53   /// Tuning option to enable/disable loop vectorization, set based on opt
54   /// level.
55   bool LoopVectorization;
56 
57   /// Tuning option to enable/disable slp loop vectorization, set based on opt
58   /// level.
59   bool SLPVectorization;
60 
61   /// Tuning option to enable/disable loop unrolling. Its default value is true.
62   bool LoopUnrolling;
63 
64   /// Tuning option to enable/disable loop interchange. Its default value is
65   /// false.
66   bool LoopInterchange;
67 
68   /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
69   /// is that of the flag: `-forget-scev-loop-unroll`.
70   bool ForgetAllSCEVInLoopUnroll;
71 
72   /// Tuning option to cap the number of calls to retrive clobbering accesses in
73   /// MemorySSA, in LICM.
74   unsigned LicmMssaOptCap;
75 
76   /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
77   /// the number of access is too large.
78   unsigned LicmMssaNoAccForPromotionCap;
79 
80   /// Tuning option to enable/disable call graph profile. Its default value is
81   /// that of the flag: `-enable-npm-call-graph-profile`.
82   bool CallGraphProfile;
83 
84   // Add LTO pipeline tuning option to enable the unified LTO pipeline.
85   bool UnifiedLTO;
86 
87   /// Tuning option to enable/disable function merging. Its default value is
88   /// false.
89   bool MergeFunctions;
90 
91   /// Tuning option to override the default inliner threshold.
92   int InlinerThreshold;
93 
94   // Experimental option to eagerly invalidate more analyses. This has the
95   // potential to decrease max memory usage in exchange for more compile time.
96   // This may affect codegen due to either passes using analyses only when
97   // cached, or invalidating and recalculating an analysis that was
98   // stale/imprecise but still valid. Currently this invalidates all function
99   // analyses after various module->function or cgscc->function adaptors in the
100   // default pipelines.
101   bool EagerlyInvalidateAnalyses;
102 };
103 
104 /// This class provides access to building LLVM's passes.
105 ///
106 /// Its members provide the baseline state available to passes during their
107 /// construction. The \c PassRegistry.def file specifies how to construct all
108 /// of the built-in passes, and those may reference these members during
109 /// construction.
110 class PassBuilder {
111   TargetMachine *TM;
112   PipelineTuningOptions PTO;
113   std::optional<PGOOptions> PGOOpt;
114   PassInstrumentationCallbacks *PIC;
115 
116 public:
117   /// A struct to capture parsed pass pipeline names.
118   ///
119   /// A pipeline is defined as a series of names, each of which may in itself
120   /// recursively contain a nested pipeline. A name is either the name of a pass
121   /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
122   /// name is the name of a pass, the InnerPipeline is empty, since passes
123   /// cannot contain inner pipelines. See parsePassPipeline() for a more
124   /// detailed description of the textual pipeline format.
125   struct PipelineElement {
126     StringRef Name;
127     std::vector<PipelineElement> InnerPipeline;
128   };
129 
130   LLVM_ABI explicit PassBuilder(
131       TargetMachine *TM = nullptr,
132       PipelineTuningOptions PTO = PipelineTuningOptions(),
133       std::optional<PGOOptions> PGOOpt = std::nullopt,
134       PassInstrumentationCallbacks *PIC = nullptr);
135 
136   /// Cross register the analysis managers through their proxies.
137   ///
138   /// This is an interface that can be used to cross register each
139   /// AnalysisManager with all the others analysis managers.
140   LLVM_ABI void
141   crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM,
142                        CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM,
143                        MachineFunctionAnalysisManager *MFAM = nullptr);
144 
145   /// Registers all available module analysis passes.
146   ///
147   /// This is an interface that can be used to populate a \c
148   /// ModuleAnalysisManager with all registered module analyses. Callers can
149   /// still manually register any additional analyses. Callers can also
150   /// pre-register analyses and this will not override those.
151   LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM);
152 
153   /// Registers all available CGSCC analysis passes.
154   ///
155   /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
156   /// with all registered CGSCC analyses. Callers can still manually register any
157   /// additional analyses. Callers can also pre-register analyses and this will
158   /// not override those.
159   LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
160 
161   /// Registers all available function analysis passes.
162   ///
163   /// This is an interface that can be used to populate a \c
164   /// FunctionAnalysisManager with all registered function analyses. Callers can
165   /// still manually register any additional analyses. Callers can also
166   /// pre-register analyses and this will not override those.
167   LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
168 
169   /// Registers all available loop analysis passes.
170   ///
171   /// This is an interface that can be used to populate a \c LoopAnalysisManager
172   /// with all registered loop analyses. Callers can still manually register any
173   /// additional analyses.
174   LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM);
175 
176   /// Registers all available machine function analysis passes.
177   ///
178   /// This is an interface that can be used to populate a \c
179   /// MachineFunctionAnalysisManager with all registered function analyses.
180   /// Callers can still manually register any additional analyses. Callers can
181   /// also pre-register analyses and this will not override those.
182   LLVM_ABI void
183   registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM);
184 
185   /// Construct the core LLVM function canonicalization and simplification
186   /// pipeline.
187   ///
188   /// This is a long pipeline and uses most of the per-function optimization
189   /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
190   /// repeatedly over the IR and is not expected to destroy important
191   /// information about the semantics of the IR.
192   ///
193   /// Note that \p Level cannot be `O0` here. The pipelines produced are
194   /// only intended for use when attempting to optimize code. If frontends
195   /// require some transformations for semantic reasons, they should explicitly
196   /// build them.
197   ///
198   /// \p Phase indicates the current ThinLTO phase.
199   LLVM_ABI FunctionPassManager buildFunctionSimplificationPipeline(
200       OptimizationLevel Level, ThinOrFullLTOPhase Phase);
201 
202   /// Construct the core LLVM module canonicalization and simplification
203   /// pipeline.
204   ///
205   /// This pipeline focuses on canonicalizing and simplifying the entire module
206   /// of IR. Much like the function simplification pipeline above, it is
207   /// suitable to run repeatedly over the IR and is not expected to destroy
208   /// important information. It does, however, perform inlining and other
209   /// heuristic based simplifications that are not strictly reversible.
210   ///
211   /// Note that \p Level cannot be `O0` here. The pipelines produced are
212   /// only intended for use when attempting to optimize code. If frontends
213   /// require some transformations for semantic reasons, they should explicitly
214   /// build them.
215   ///
216   /// \p Phase indicates the current ThinLTO phase.
217   LLVM_ABI ModulePassManager buildModuleSimplificationPipeline(
218       OptimizationLevel Level, ThinOrFullLTOPhase Phase);
219 
220   /// Construct the module pipeline that performs inlining as well as
221   /// the inlining-driven cleanups.
222   LLVM_ABI ModuleInlinerWrapperPass
223   buildInlinerPipeline(OptimizationLevel Level, ThinOrFullLTOPhase Phase);
224 
225   /// Construct the module pipeline that performs inlining with
226   /// module inliner pass.
227   LLVM_ABI ModulePassManager
228   buildModuleInlinerPipeline(OptimizationLevel Level, ThinOrFullLTOPhase Phase);
229 
230   /// Construct the core LLVM module optimization pipeline.
231   ///
232   /// This pipeline focuses on optimizing the execution speed of the IR. It
233   /// uses cost modeling and thresholds to balance code growth against runtime
234   /// improvements. It includes vectorization and other information destroying
235   /// transformations. It also cannot generally be run repeatedly on a module
236   /// without potentially seriously regressing either runtime performance of
237   /// the code or serious code size growth.
238   ///
239   /// Note that \p Level cannot be `O0` here. The pipelines produced are
240   /// only intended for use when attempting to optimize code. If frontends
241   /// require some transformations for semantic reasons, they should explicitly
242   /// build them.
243   LLVM_ABI ModulePassManager buildModuleOptimizationPipeline(
244       OptimizationLevel Level, ThinOrFullLTOPhase LTOPhase);
245 
246   /// Build a per-module default optimization pipeline.
247   ///
248   /// This provides a good default optimization pipeline for per-module
249   /// optimization and code generation without any link-time optimization. It
250   /// typically correspond to frontend "-O[123]" options for optimization
251   /// levels \c O1, \c O2 and \c O3 resp.
252   LLVM_ABI ModulePassManager buildPerModuleDefaultPipeline(
253       OptimizationLevel Level,
254       ThinOrFullLTOPhase Phase = ThinOrFullLTOPhase::None);
255 
256   /// Build a fat object default optimization pipeline.
257   ///
258   /// This builds a pipeline that runs the LTO/ThinLTO  pre-link pipeline, and
259   /// emits a section containing the pre-link bitcode along side the object code
260   /// generated in non-LTO compilation.
261   LLVM_ABI ModulePassManager buildFatLTODefaultPipeline(OptimizationLevel Level,
262                                                         bool ThinLTO,
263                                                         bool EmitSummary);
264 
265   /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
266   /// a pass manager.
267   ///
268   /// This adds the pre-link optimizations tuned to prepare a module for
269   /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
270   /// without making irreversible decisions which could be made better during
271   /// the LTO run.
272   LLVM_ABI ModulePassManager
273   buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
274 
275   /// Build a ThinLTO default optimization pipeline to a pass manager.
276   ///
277   /// This provides a good default optimization pipeline for link-time
278   /// optimization and code generation. It is particularly tuned to fit well
279   /// when IR coming into the LTO phase was first run through \c
280   /// buildThinLTOPreLinkDefaultPipeline, and the two coordinate closely.
281   LLVM_ABI ModulePassManager buildThinLTODefaultPipeline(
282       OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary);
283 
284   /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
285   /// manager.
286   ///
287   /// This adds the pre-link optimizations tuned to work well with a later LTO
288   /// run. It works to minimize the IR which needs to be analyzed without
289   /// making irreversible decisions which could be made better during the LTO
290   /// run.
291   LLVM_ABI ModulePassManager
292   buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
293 
294   /// Build an LTO default optimization pipeline to a pass manager.
295   ///
296   /// This provides a good default optimization pipeline for link-time
297   /// optimization and code generation. It is particularly tuned to fit well
298   /// when IR coming into the LTO phase was first run through \c
299   /// buildLTOPreLinkDefaultPipeline, and the two coordinate closely.
300   LLVM_ABI ModulePassManager buildLTODefaultPipeline(
301       OptimizationLevel Level, ModuleSummaryIndex *ExportSummary);
302 
303   /// Build an O0 pipeline with the minimal semantically required passes.
304   ///
305   /// This should only be used for non-LTO and LTO pre-link pipelines.
306   LLVM_ABI ModulePassManager
307   buildO0DefaultPipeline(OptimizationLevel Level,
308                          ThinOrFullLTOPhase Phase = ThinOrFullLTOPhase::None);
309 
310   /// Build the default `AAManager` with the default alias analysis pipeline
311   /// registered.
312   ///
313   /// This also adds target-specific alias analyses registered via
314   /// TargetMachine::registerDefaultAliasAnalyses().
315   LLVM_ABI AAManager buildDefaultAAPipeline();
316 
317   /// Parse a textual pass pipeline description into a \c
318   /// ModulePassManager.
319   ///
320   /// The format of the textual pass pipeline description looks something like:
321   ///
322   ///   module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
323   ///
324   /// Pass managers have ()s describing the nest structure of passes. All passes
325   /// are comma separated. As a special shortcut, if the very first pass is not
326   /// a module pass (as a module pass manager is), this will automatically form
327   /// the shortest stack of pass managers that allow inserting that first pass.
328   /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
329   /// passes 'lpassN', all of these are valid:
330   ///
331   ///   fpass1,fpass2,fpass3
332   ///   cgpass1,cgpass2,cgpass3
333   ///   lpass1,lpass2,lpass3
334   ///
335   /// And they are equivalent to the following (resp.):
336   ///
337   ///   module(function(fpass1,fpass2,fpass3))
338   ///   module(cgscc(cgpass1,cgpass2,cgpass3))
339   ///   module(function(loop(lpass1,lpass2,lpass3)))
340   ///
341   /// This shortcut is especially useful for debugging and testing small pass
342   /// combinations.
343   ///
344   /// The sequence of passes aren't necessarily the exact same kind of pass.
345   /// You can mix different levels implicitly if adaptor passes are defined to
346   /// make them work. For example,
347   ///
348   ///   mpass1,fpass1,fpass2,mpass2,lpass1
349   ///
350   /// This pipeline uses only one pass manager: the top-level module manager.
351   /// fpass1,fpass2 and lpass1 are added into the top-level module manager
352   /// using only adaptor passes. No nested function/loop pass managers are
353   /// added. The purpose is to allow easy pass testing when the user
354   /// specifically want the pass to run under a adaptor directly. This is
355   /// preferred when a pipeline is largely of one type, but one or just a few
356   /// passes are of different types(See PassBuilder.cpp for examples).
357   LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM,
358                                    StringRef PipelineText);
359 
360   /// {{@ Parse a textual pass pipeline description into a specific PassManager
361   ///
362   /// Automatic deduction of an appropriate pass manager stack is not supported.
363   /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
364   /// this is the valid pipeline text:
365   ///
366   ///   function(lpass)
367   LLVM_ABI Error parsePassPipeline(CGSCCPassManager &CGPM,
368                                    StringRef PipelineText);
369   LLVM_ABI Error parsePassPipeline(FunctionPassManager &FPM,
370                                    StringRef PipelineText);
371   LLVM_ABI Error parsePassPipeline(LoopPassManager &LPM,
372                                    StringRef PipelineText);
373   /// @}}
374 
375   /// Parse a textual MIR pipeline into the provided \c MachineFunctionPass
376   /// manager.
377   /// The format of the textual machine pipeline is a comma separated list of
378   /// machine pass names:
379   ///
380   ///   machine-funciton-pass,machine-module-pass,...
381   ///
382   /// There is no need to specify the pass nesting, and this function
383   /// currently cannot handle the pass nesting.
384   LLVM_ABI Error parsePassPipeline(MachineFunctionPassManager &MFPM,
385                                    StringRef PipelineText);
386 
387   /// Parse a textual alias analysis pipeline into the provided AA manager.
388   ///
389   /// The format of the textual AA pipeline is a comma separated list of AA
390   /// pass names:
391   ///
392   ///   basic-aa,globals-aa,...
393   ///
394   /// The AA manager is set up such that the provided alias analyses are tried
395   /// in the order specified. See the \c AAManaager documentation for details
396   /// about the logic used. This routine just provides the textual mapping
397   /// between AA names and the analyses to register with the manager.
398   ///
399   /// Returns false if the text cannot be parsed cleanly. The specific state of
400   /// the \p AA manager is unspecified if such an error is encountered and this
401   /// returns false.
402   LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
403 
404   /// Parse RegAllocFilterName to get RegAllocFilterFunc.
405   LLVM_ABI std::optional<RegAllocFilterFunc>
406   parseRegAllocFilter(StringRef RegAllocFilterName);
407 
408   /// Print pass names.
409   LLVM_ABI void printPassNames(raw_ostream &OS);
410 
411   /// Register a callback for a default optimizer pipeline extension
412   /// point
413   ///
414   /// This extension point allows adding passes that perform peephole
415   /// optimizations similar to the instruction combiner. These passes will be
416   /// inserted after each instance of the instruction combiner pass.
registerPeepholeEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)417   void registerPeepholeEPCallback(
418       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
419     PeepholeEPCallbacks.push_back(C);
420   }
421 
422   /// Register a callback for a default optimizer pipeline extension
423   /// point
424   ///
425   /// This extension point allows adding late loop canonicalization and
426   /// simplification passes. This is the last point in the loop optimization
427   /// pipeline before loop deletion. Each pass added
428   /// here must be an instance of LoopPass.
429   /// This is the place to add passes that can remove loops, such as target-
430   /// specific loop idiom recognition.
registerLateLoopOptimizationsEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)431   void registerLateLoopOptimizationsEPCallback(
432       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
433     LateLoopOptimizationsEPCallbacks.push_back(C);
434   }
435 
436   /// Register a callback for a default optimizer pipeline extension
437   /// point
438   ///
439   /// This extension point allows adding loop passes to the end of the loop
440   /// optimizer.
registerLoopOptimizerEndEPCallback(const std::function<void (LoopPassManager &,OptimizationLevel)> & C)441   void registerLoopOptimizerEndEPCallback(
442       const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
443     LoopOptimizerEndEPCallbacks.push_back(C);
444   }
445 
446   /// Register a callback for a default optimizer pipeline extension
447   /// point
448   ///
449   /// This extension point allows adding optimization passes after most of the
450   /// main optimizations, but before the last cleanup-ish optimizations.
registerScalarOptimizerLateEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)451   void registerScalarOptimizerLateEPCallback(
452       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
453     ScalarOptimizerLateEPCallbacks.push_back(C);
454   }
455 
456   /// Register a callback for a default optimizer pipeline extension
457   /// point
458   ///
459   /// This extension point allows adding CallGraphSCC passes at the end of the
460   /// main CallGraphSCC passes and before any function simplification passes run
461   /// by CGPassManager.
registerCGSCCOptimizerLateEPCallback(const std::function<void (CGSCCPassManager &,OptimizationLevel)> & C)462   void registerCGSCCOptimizerLateEPCallback(
463       const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
464     CGSCCOptimizerLateEPCallbacks.push_back(C);
465   }
466 
467   /// Register a callback for a default optimizer pipeline extension
468   /// point
469   ///
470   /// This extension point allows adding optimization passes before the
471   /// vectorizer and other highly target specific optimization passes are
472   /// executed.
registerVectorizerStartEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)473   void registerVectorizerStartEPCallback(
474       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
475     VectorizerStartEPCallbacks.push_back(C);
476   }
477 
478   /// Register a callback for a default optimizer pipeline extension
479   /// point
480   ///
481   /// This extension point allows adding optimization passes after the
482   /// vectorizer and other highly target specific optimization passes are
483   /// executed.
registerVectorizerEndEPCallback(const std::function<void (FunctionPassManager &,OptimizationLevel)> & C)484   void registerVectorizerEndEPCallback(
485       const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
486     VectorizerEndEPCallbacks.push_back(C);
487   }
488 
489   /// Register a callback for a default optimizer pipeline extension point.
490   ///
491   /// This extension point allows adding optimization once at the start of the
492   /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
493   /// link-time pipelines).
registerPipelineStartEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)494   void registerPipelineStartEPCallback(
495       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
496     PipelineStartEPCallbacks.push_back(C);
497   }
498 
499   /// Register a callback for a default optimizer pipeline extension point.
500   ///
501   /// This extension point allows adding optimization right after passes that do
502   /// basic simplification of the input IR.
registerPipelineEarlySimplificationEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel,ThinOrFullLTOPhase)> & C)503   void registerPipelineEarlySimplificationEPCallback(
504       const std::function<void(ModulePassManager &, OptimizationLevel,
505                                ThinOrFullLTOPhase)> &C) {
506     PipelineEarlySimplificationEPCallbacks.push_back(C);
507   }
508 
509   /// Register a callback for a default optimizer pipeline extension point
510   ///
511   /// This extension point allows adding optimizations before the function
512   /// optimization pipeline.
registerOptimizerEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel,ThinOrFullLTOPhase Phase)> & C)513   void registerOptimizerEarlyEPCallback(
514       const std::function<void(ModulePassManager &, OptimizationLevel,
515                                ThinOrFullLTOPhase Phase)> &C) {
516     OptimizerEarlyEPCallbacks.push_back(C);
517   }
518 
519   /// Register a callback for a default optimizer pipeline extension point
520   ///
521   /// This extension point allows adding optimizations at the very end of the
522   /// function optimization pipeline.
registerOptimizerLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel,ThinOrFullLTOPhase)> & C)523   void registerOptimizerLastEPCallback(
524       const std::function<void(ModulePassManager &, OptimizationLevel,
525                                ThinOrFullLTOPhase)> &C) {
526     OptimizerLastEPCallbacks.push_back(C);
527   }
528 
529   /// Register a callback for a default optimizer pipeline extension point
530   ///
531   /// This extension point allows adding optimizations at the start of the full
532   /// LTO pipeline.
registerFullLinkTimeOptimizationEarlyEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)533   void registerFullLinkTimeOptimizationEarlyEPCallback(
534       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
535     FullLinkTimeOptimizationEarlyEPCallbacks.push_back(C);
536   }
537 
538   /// Register a callback for a default optimizer pipeline extension point
539   ///
540   /// This extension point allows adding optimizations at the end of the full
541   /// LTO pipeline.
registerFullLinkTimeOptimizationLastEPCallback(const std::function<void (ModulePassManager &,OptimizationLevel)> & C)542   void registerFullLinkTimeOptimizationLastEPCallback(
543       const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
544     FullLinkTimeOptimizationLastEPCallbacks.push_back(C);
545   }
546 
547   /// Register a callback for parsing an AliasAnalysis Name to populate
548   /// the given AAManager \p AA
registerParseAACallback(const std::function<bool (StringRef Name,AAManager & AA)> & C)549   void registerParseAACallback(
550       const std::function<bool(StringRef Name, AAManager &AA)> &C) {
551     AAParsingCallbacks.push_back(C);
552   }
553 
554   /// {{@ Register callbacks for analysis registration with this PassBuilder
555   /// instance.
556   /// Callees register their analyses with the given AnalysisManager objects.
registerAnalysisRegistrationCallback(const std::function<void (CGSCCAnalysisManager &)> & C)557   void registerAnalysisRegistrationCallback(
558       const std::function<void(CGSCCAnalysisManager &)> &C) {
559     CGSCCAnalysisRegistrationCallbacks.push_back(C);
560   }
registerAnalysisRegistrationCallback(const std::function<void (FunctionAnalysisManager &)> & C)561   void registerAnalysisRegistrationCallback(
562       const std::function<void(FunctionAnalysisManager &)> &C) {
563     FunctionAnalysisRegistrationCallbacks.push_back(C);
564   }
registerAnalysisRegistrationCallback(const std::function<void (LoopAnalysisManager &)> & C)565   void registerAnalysisRegistrationCallback(
566       const std::function<void(LoopAnalysisManager &)> &C) {
567     LoopAnalysisRegistrationCallbacks.push_back(C);
568   }
registerAnalysisRegistrationCallback(const std::function<void (ModuleAnalysisManager &)> & C)569   void registerAnalysisRegistrationCallback(
570       const std::function<void(ModuleAnalysisManager &)> &C) {
571     ModuleAnalysisRegistrationCallbacks.push_back(C);
572   }
registerAnalysisRegistrationCallback(const std::function<void (MachineFunctionAnalysisManager &)> & C)573   void registerAnalysisRegistrationCallback(
574       const std::function<void(MachineFunctionAnalysisManager &)> &C) {
575     MachineFunctionAnalysisRegistrationCallbacks.push_back(C);
576   }
577   /// @}}
578 
579   /// {{@ Register pipeline parsing callbacks with this pass builder instance.
580   /// Using these callbacks, callers can parse both a single pass name, as well
581   /// as entire sub-pipelines, and populate the PassManager instance
582   /// accordingly.
registerPipelineParsingCallback(const std::function<bool (StringRef Name,CGSCCPassManager &,ArrayRef<PipelineElement>)> & C)583   void registerPipelineParsingCallback(
584       const std::function<bool(StringRef Name, CGSCCPassManager &,
585                                ArrayRef<PipelineElement>)> &C) {
586     CGSCCPipelineParsingCallbacks.push_back(C);
587   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,FunctionPassManager &,ArrayRef<PipelineElement>)> & C)588   void registerPipelineParsingCallback(
589       const std::function<bool(StringRef Name, FunctionPassManager &,
590                                ArrayRef<PipelineElement>)> &C) {
591     FunctionPipelineParsingCallbacks.push_back(C);
592   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,LoopPassManager &,ArrayRef<PipelineElement>)> & C)593   void registerPipelineParsingCallback(
594       const std::function<bool(StringRef Name, LoopPassManager &,
595                                ArrayRef<PipelineElement>)> &C) {
596     LoopPipelineParsingCallbacks.push_back(C);
597   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,ModulePassManager &,ArrayRef<PipelineElement>)> & C)598   void registerPipelineParsingCallback(
599       const std::function<bool(StringRef Name, ModulePassManager &,
600                                ArrayRef<PipelineElement>)> &C) {
601     ModulePipelineParsingCallbacks.push_back(C);
602   }
registerPipelineParsingCallback(const std::function<bool (StringRef Name,MachineFunctionPassManager &,ArrayRef<PipelineElement>)> & C)603   void registerPipelineParsingCallback(
604       const std::function<bool(StringRef Name, MachineFunctionPassManager &,
605                                ArrayRef<PipelineElement>)> &C) {
606     MachineFunctionPipelineParsingCallbacks.push_back(C);
607   }
608   /// @}}
609 
610   /// Register callbacks to parse target specific filter field if regalloc pass
611   /// needs it. E.g. AMDGPU requires regalloc passes can handle sgpr and vgpr
612   /// separately.
registerRegClassFilterParsingCallback(const std::function<RegAllocFilterFunc (StringRef)> & C)613   void registerRegClassFilterParsingCallback(
614       const std::function<RegAllocFilterFunc(StringRef)> &C) {
615     RegClassFilterParsingCallbacks.push_back(C);
616   }
617 
618   /// Register a callback for a top-level pipeline entry.
619   ///
620   /// If the PassManager type is not given at the top level of the pipeline
621   /// text, this Callback should be used to determine the appropriate stack of
622   /// PassManagers and populate the passed ModulePassManager.
623   LLVM_ABI void registerParseTopLevelPipelineCallback(
624       const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
625           &C);
626 
627   /// Add PGOInstrumenation passes for O0 only.
628   LLVM_ABI void addPGOInstrPassesForO0(ModulePassManager &MPM,
629                                        bool RunProfileGen, bool IsCS,
630                                        bool AtomicCounterUpdate,
631                                        std::string ProfileFile,
632                                        std::string ProfileRemappingFile,
633                                        IntrusiveRefCntPtr<vfs::FileSystem> FS);
634 
635   /// Returns PIC. External libraries can use this to register pass
636   /// instrumentation callbacks.
getPassInstrumentationCallbacks()637   PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
638     return PIC;
639   }
640 
641   // Invoke the callbacks registered for the various extension points.
642   // Custom pipelines should use these to invoke the callbacks registered
643   // by TargetMachines and other clients.
644   LLVM_ABI void invokePeepholeEPCallbacks(FunctionPassManager &FPM,
645                                           OptimizationLevel Level);
646   LLVM_ABI void invokeLateLoopOptimizationsEPCallbacks(LoopPassManager &LPM,
647                                                        OptimizationLevel Level);
648   LLVM_ABI void invokeLoopOptimizerEndEPCallbacks(LoopPassManager &LPM,
649                                                   OptimizationLevel Level);
650   LLVM_ABI void invokeScalarOptimizerLateEPCallbacks(FunctionPassManager &FPM,
651                                                      OptimizationLevel Level);
652   LLVM_ABI void invokeCGSCCOptimizerLateEPCallbacks(CGSCCPassManager &CGPM,
653                                                     OptimizationLevel Level);
654   LLVM_ABI void invokeVectorizerStartEPCallbacks(FunctionPassManager &FPM,
655                                                  OptimizationLevel Level);
656   LLVM_ABI void invokeVectorizerEndEPCallbacks(FunctionPassManager &FPM,
657                                                OptimizationLevel Level);
658   LLVM_ABI void invokeOptimizerEarlyEPCallbacks(ModulePassManager &MPM,
659                                                 OptimizationLevel Level,
660                                                 ThinOrFullLTOPhase Phase);
661   LLVM_ABI void invokeOptimizerLastEPCallbacks(ModulePassManager &MPM,
662                                                OptimizationLevel Level,
663                                                ThinOrFullLTOPhase Phase);
664   LLVM_ABI void
665   invokeFullLinkTimeOptimizationEarlyEPCallbacks(ModulePassManager &MPM,
666                                                  OptimizationLevel Level);
667   LLVM_ABI void
668   invokeFullLinkTimeOptimizationLastEPCallbacks(ModulePassManager &MPM,
669                                                 OptimizationLevel Level);
670   LLVM_ABI void invokePipelineStartEPCallbacks(ModulePassManager &MPM,
671                                                OptimizationLevel Level);
672   LLVM_ABI void
673   invokePipelineEarlySimplificationEPCallbacks(ModulePassManager &MPM,
674                                                OptimizationLevel Level,
675                                                ThinOrFullLTOPhase Phase);
676 
checkParametrizedPassName(StringRef Name,StringRef PassName)677   static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
678     if (!Name.consume_front(PassName))
679       return false;
680     // normal pass name w/o parameters == default parameters
681     if (Name.empty())
682       return true;
683     return Name.starts_with("<") && Name.ends_with(">");
684   }
685 
686   /// This performs customized parsing of pass name with parameters.
687   ///
688   /// We do not need parametrization of passes in textual pipeline very often,
689   /// yet on a rare occasion ability to specify parameters right there can be
690   /// useful.
691   ///
692   /// \p Name - parameterized specification of a pass from a textual pipeline
693   /// is a string in a form of :
694   ///      PassName '<' parameter-list '>'
695   ///
696   /// Parameter list is being parsed by the parser callable argument, \p Parser,
697   /// It takes a string-ref of parameters and returns either StringError or a
698   /// parameter list in a form of a custom parameters type, all wrapped into
699   /// Expected<> template class.
700   ///
701   template <typename ParametersParseCallableT>
702   static auto parsePassParameters(ParametersParseCallableT &&Parser,
703                                   StringRef Name, StringRef PassName)
704       -> decltype(Parser(StringRef{})) {
705     using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
706 
707     StringRef Params = Name;
708     if (!Params.consume_front(PassName)) {
709       llvm_unreachable(
710           "unable to strip pass name from parametrized pass specification");
711     }
712     if (!Params.empty() &&
713         (!Params.consume_front("<") || !Params.consume_back(">"))) {
714       llvm_unreachable("invalid format for parametrized pass name");
715     }
716 
717     Expected<ParametersT> Result = Parser(Params);
718     assert((Result || Result.template errorIsA<StringError>()) &&
719            "Pass parameter parser can only return StringErrors.");
720     return Result;
721   }
722 
723   /// Handle passes only accept one bool-valued parameter.
724   ///
725   /// \return false when Params is empty.
726   LLVM_ABI static Expected<bool> parseSinglePassOption(StringRef Params,
727                                                        StringRef OptionName,
728                                                        StringRef PassName);
729 
730 private:
731   // O1 pass pipeline
732   FunctionPassManager
733   buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
734                                         ThinOrFullLTOPhase Phase);
735 
736   void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
737 
738   void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
739                        bool IsFullLTO);
740 
741   static std::optional<std::vector<PipelineElement>>
742   parsePipelineText(StringRef Text);
743 
744   Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
745   Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
746   Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
747   Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
748   Error parseMachinePass(MachineFunctionPassManager &MFPM,
749                          const PipelineElement &E);
750   bool parseAAPassName(AAManager &AA, StringRef Name);
751 
752   Error parseMachinePassPipeline(MachineFunctionPassManager &MFPM,
753                                  ArrayRef<PipelineElement> Pipeline);
754   Error parseLoopPassPipeline(LoopPassManager &LPM,
755                               ArrayRef<PipelineElement> Pipeline);
756   Error parseFunctionPassPipeline(FunctionPassManager &FPM,
757                                   ArrayRef<PipelineElement> Pipeline);
758   Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
759                                ArrayRef<PipelineElement> Pipeline);
760   Error parseModulePassPipeline(ModulePassManager &MPM,
761                                 ArrayRef<PipelineElement> Pipeline);
762 
763   // Adds passes to do pre-inlining and related cleanup passes before
764   // profile instrumentation/matching (to enable better context sensitivity),
765   // and for memprof to enable better matching with missing debug frames.
766   void addPreInlinerPasses(ModulePassManager &MPM, OptimizationLevel Level,
767                            ThinOrFullLTOPhase LTOPhase);
768 
769   void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
770                          bool RunProfileGen, bool IsCS,
771                          bool AtomicCounterUpdate, std::string ProfileFile,
772                          std::string ProfileRemappingFile,
773                          IntrusiveRefCntPtr<vfs::FileSystem> FS);
774   void addPostPGOLoopRotation(ModulePassManager &MPM, OptimizationLevel Level);
775 
776   bool isInstrumentedPGOUse() const;
777 
778   // Extension Point callbacks
779   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
780       PeepholeEPCallbacks;
781   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
782       LateLoopOptimizationsEPCallbacks;
783   SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
784       LoopOptimizerEndEPCallbacks;
785   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
786       ScalarOptimizerLateEPCallbacks;
787   SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
788       CGSCCOptimizerLateEPCallbacks;
789   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
790       VectorizerStartEPCallbacks;
791   SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
792       VectorizerEndEPCallbacks;
793   // Module callbacks
794   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
795                                  ThinOrFullLTOPhase)>,
796               2>
797       OptimizerEarlyEPCallbacks;
798   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
799                                  ThinOrFullLTOPhase)>,
800               2>
801       OptimizerLastEPCallbacks;
802   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
803       FullLinkTimeOptimizationEarlyEPCallbacks;
804   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
805       FullLinkTimeOptimizationLastEPCallbacks;
806   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
807       PipelineStartEPCallbacks;
808   SmallVector<std::function<void(ModulePassManager &, OptimizationLevel,
809                                  ThinOrFullLTOPhase)>,
810               2>
811       PipelineEarlySimplificationEPCallbacks;
812 
813   SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
814       ModuleAnalysisRegistrationCallbacks;
815   SmallVector<std::function<bool(StringRef, ModulePassManager &,
816                                  ArrayRef<PipelineElement>)>,
817               2>
818       ModulePipelineParsingCallbacks;
819   SmallVector<
820       std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
821       TopLevelPipelineParsingCallbacks;
822   // CGSCC callbacks
823   SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
824       CGSCCAnalysisRegistrationCallbacks;
825   SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
826                                  ArrayRef<PipelineElement>)>,
827               2>
828       CGSCCPipelineParsingCallbacks;
829   // Function callbacks
830   SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
831       FunctionAnalysisRegistrationCallbacks;
832   SmallVector<std::function<bool(StringRef, FunctionPassManager &,
833                                  ArrayRef<PipelineElement>)>,
834               2>
835       FunctionPipelineParsingCallbacks;
836   // Loop callbacks
837   SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
838       LoopAnalysisRegistrationCallbacks;
839   SmallVector<std::function<bool(StringRef, LoopPassManager &,
840                                  ArrayRef<PipelineElement>)>,
841               2>
842       LoopPipelineParsingCallbacks;
843   // AA callbacks
844   SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
845       AAParsingCallbacks;
846   // Machine pass callbackcs
847   SmallVector<std::function<void(MachineFunctionAnalysisManager &)>, 2>
848       MachineFunctionAnalysisRegistrationCallbacks;
849   SmallVector<std::function<bool(StringRef, MachineFunctionPassManager &,
850                                  ArrayRef<PipelineElement>)>,
851               2>
852       MachineFunctionPipelineParsingCallbacks;
853   // Callbacks to parse `filter` parameter in register allocation passes
854   SmallVector<std::function<RegAllocFilterFunc(StringRef)>, 2>
855       RegClassFilterParsingCallbacks;
856 };
857 
858 /// This utility template takes care of adding require<> and invalidate<>
859 /// passes for an analysis to a given \c PassManager. It is intended to be used
860 /// during parsing of a pass pipeline when parsing a single PipelineName.
861 /// When registering a new function analysis FancyAnalysis with the pass
862 /// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
863 /// like this:
864 ///
865 /// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
866 ///                                   ArrayRef<PipelineElement> P) {
867 ///   if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
868 ///                                                 FPM))
869 ///     return true;
870 ///   return false;
871 /// }
872 template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
873           typename... ExtraArgTs>
parseAnalysisUtilityPasses(StringRef AnalysisName,StringRef PipelineName,PassManager<IRUnitT,AnalysisManagerT,ExtraArgTs...> & PM)874 bool parseAnalysisUtilityPasses(
875     StringRef AnalysisName, StringRef PipelineName,
876     PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
877   if (!PipelineName.ends_with(">"))
878     return false;
879   // See if this is an invalidate<> pass name
880   if (PipelineName.starts_with("invalidate<")) {
881     PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
882     if (PipelineName != AnalysisName)
883       return false;
884     PM.addPass(InvalidateAnalysisPass<AnalysisT>());
885     return true;
886   }
887 
888   // See if this is a require<> pass name
889   if (PipelineName.starts_with("require<")) {
890     PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
891     if (PipelineName != AnalysisName)
892       return false;
893     PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
894                                    ExtraArgTs...>());
895     return true;
896   }
897 
898   return false;
899 }
900 
901 // These are special since they are only for testing purposes.
902 
903 /// No-op module pass which does nothing.
904 struct NoOpModulePass : PassInfoMixin<NoOpModulePass> {
runNoOpModulePass905   PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
906     return PreservedAnalyses::all();
907   }
908 };
909 
910 /// No-op module analysis.
911 class NoOpModuleAnalysis : public AnalysisInfoMixin<NoOpModuleAnalysis> {
912   friend AnalysisInfoMixin<NoOpModuleAnalysis>;
913   LLVM_ABI static AnalysisKey Key;
914 
915 public:
916   struct Result {};
run(Module &,ModuleAnalysisManager &)917   Result run(Module &, ModuleAnalysisManager &) { return Result(); }
918 };
919 
920 /// No-op CGSCC pass which does nothing.
921 struct NoOpCGSCCPass : PassInfoMixin<NoOpCGSCCPass> {
runNoOpCGSCCPass922   PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &,
923                         LazyCallGraph &, CGSCCUpdateResult &UR) {
924     return PreservedAnalyses::all();
925   }
926 };
927 
928 /// No-op CGSCC analysis.
929 class NoOpCGSCCAnalysis : public AnalysisInfoMixin<NoOpCGSCCAnalysis> {
930   friend AnalysisInfoMixin<NoOpCGSCCAnalysis>;
931   LLVM_ABI static AnalysisKey Key;
932 
933 public:
934   struct Result {};
run(LazyCallGraph::SCC &,CGSCCAnalysisManager &,LazyCallGraph & G)935   Result run(LazyCallGraph::SCC &, CGSCCAnalysisManager &, LazyCallGraph &G) {
936     return Result();
937   }
938 };
939 
940 /// No-op function pass which does nothing.
941 struct NoOpFunctionPass : PassInfoMixin<NoOpFunctionPass> {
runNoOpFunctionPass942   PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
943     return PreservedAnalyses::all();
944   }
945 };
946 
947 /// No-op function analysis.
948 class NoOpFunctionAnalysis : public AnalysisInfoMixin<NoOpFunctionAnalysis> {
949   friend AnalysisInfoMixin<NoOpFunctionAnalysis>;
950   LLVM_ABI static AnalysisKey Key;
951 
952 public:
953   struct Result {};
run(Function &,FunctionAnalysisManager &)954   Result run(Function &, FunctionAnalysisManager &) { return Result(); }
955 };
956 
957 /// No-op loop nest pass which does nothing.
958 struct NoOpLoopNestPass : PassInfoMixin<NoOpLoopNestPass> {
runNoOpLoopNestPass959   PreservedAnalyses run(LoopNest &L, LoopAnalysisManager &,
960                         LoopStandardAnalysisResults &, LPMUpdater &) {
961     return PreservedAnalyses::all();
962   }
963 };
964 
965 /// No-op loop pass which does nothing.
966 struct NoOpLoopPass : PassInfoMixin<NoOpLoopPass> {
runNoOpLoopPass967   PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
968                         LoopStandardAnalysisResults &, LPMUpdater &) {
969     return PreservedAnalyses::all();
970   }
971 };
972 
973 /// No-op machine function pass which does nothing.
974 struct NoOpMachineFunctionPass : public PassInfoMixin<NoOpMachineFunctionPass> {
runNoOpMachineFunctionPass975   PreservedAnalyses run(MachineFunction &, MachineFunctionAnalysisManager &) {
976     return PreservedAnalyses::all();
977   }
978 };
979 
980 /// No-op loop analysis.
981 class NoOpLoopAnalysis : public AnalysisInfoMixin<NoOpLoopAnalysis> {
982   friend AnalysisInfoMixin<NoOpLoopAnalysis>;
983   LLVM_ABI static AnalysisKey Key;
984 
985 public:
986   struct Result {};
run(Loop &,LoopAnalysisManager &,LoopStandardAnalysisResults &)987   Result run(Loop &, LoopAnalysisManager &, LoopStandardAnalysisResults &) {
988     return Result();
989   }
990 };
991 
992 /// Common option used by multiple tools to print pipeline passes
993 LLVM_ABI extern cl::opt<bool> PrintPipelinePasses;
994 }
995 
996 #endif
997