aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/llvm14/include/llvm/Passes
diff options
context:
space:
mode:
authorvitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
committervitalyisaev <vitalyisaev@yandex-team.com>2023-06-29 10:00:50 +0300
commit6ffe9e53658409f212834330e13564e4952558f6 (patch)
tree85b1e00183517648b228aafa7c8fb07f5276f419 /contrib/libs/llvm14/include/llvm/Passes
parent726057070f9c5a91fc10fde0d5024913d10f1ab9 (diff)
downloadydb-6ffe9e53658409f212834330e13564e4952558f6.tar.gz
YQ Connector: support managed ClickHouse
Со стороны dqrun можно обратиться к инстансу коннектора, который работает на streaming стенде, и извлечь данные из облачного CH.
Diffstat (limited to 'contrib/libs/llvm14/include/llvm/Passes')
-rw-r--r--contrib/libs/llvm14/include/llvm/Passes/OptimizationLevel.h138
-rw-r--r--contrib/libs/llvm14/include/llvm/Passes/PassBuilder.h699
-rw-r--r--contrib/libs/llvm14/include/llvm/Passes/PassPlugin.h124
-rw-r--r--contrib/libs/llvm14/include/llvm/Passes/StandardInstrumentations.h546
4 files changed, 1507 insertions, 0 deletions
diff --git a/contrib/libs/llvm14/include/llvm/Passes/OptimizationLevel.h b/contrib/libs/llvm14/include/llvm/Passes/OptimizationLevel.h
new file mode 100644
index 0000000000..0986b0f6de
--- /dev/null
+++ b/contrib/libs/llvm14/include/llvm/Passes/OptimizationLevel.h
@@ -0,0 +1,138 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===-------- LLVM-provided High-Level Optimization levels -*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header enumerates the LLVM-provided high-level optimization levels.
+/// Each level has a specific goal and rationale.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_OPTIMIZATIONLEVEL_H
+#define LLVM_PASSES_OPTIMIZATIONLEVEL_H
+
+#include <assert.h>
+
+namespace llvm {
+
+class OptimizationLevel final {
+ unsigned SpeedLevel = 2;
+ unsigned SizeLevel = 0;
+ OptimizationLevel(unsigned SpeedLevel, unsigned SizeLevel)
+ : SpeedLevel(SpeedLevel), SizeLevel(SizeLevel) {
+ // Check that only valid combinations are passed.
+ assert(SpeedLevel <= 3 &&
+ "Optimization level for speed should be 0, 1, 2, or 3");
+ assert(SizeLevel <= 2 &&
+ "Optimization level for size should be 0, 1, or 2");
+ assert((SizeLevel == 0 || SpeedLevel == 2) &&
+ "Optimize for size should be encoded with speedup level == 2");
+ }
+
+public:
+ OptimizationLevel() = default;
+ /// Disable as many optimizations as possible. This doesn't completely
+ /// disable the optimizer in all cases, for example always_inline functions
+ /// can be required to be inlined for correctness.
+ static const OptimizationLevel O0;
+
+ /// Optimize quickly without destroying debuggability.
+ ///
+ /// This level is tuned to produce a result from the optimizer as quickly
+ /// as possible and to avoid destroying debuggability. This tends to result
+ /// in a very good development mode where the compiled code will be
+ /// immediately executed as part of testing. As a consequence, where
+ /// possible, we would like to produce efficient-to-execute code, but not
+ /// if it significantly slows down compilation or would prevent even basic
+ /// debugging of the resulting binary.
+ ///
+ /// As an example, complex loop transformations such as versioning,
+ /// vectorization, or fusion don't make sense here due to the degree to
+ /// which the executed code differs from the source code, and the compile
+ /// time cost.
+ static const OptimizationLevel O1;
+ /// Optimize for fast execution as much as possible without triggering
+ /// significant incremental compile time or code size growth.
+ ///
+ /// The key idea is that optimizations at this level should "pay for
+ /// themselves". So if an optimization increases compile time by 5% or
+ /// increases code size by 5% for a particular benchmark, that benchmark
+ /// should also be one which sees a 5% runtime improvement. If the compile
+ /// time or code size penalties happen on average across a diverse range of
+ /// LLVM users' benchmarks, then the improvements should as well.
+ ///
+ /// And no matter what, the compile time needs to not grow superlinearly
+ /// with the size of input to LLVM so that users can control the runtime of
+ /// the optimizer in this mode.
+ ///
+ /// This is expected to be a good default optimization level for the vast
+ /// majority of users.
+ static const OptimizationLevel O2;
+ /// Optimize for fast execution as much as possible.
+ ///
+ /// This mode is significantly more aggressive in trading off compile time
+ /// and code size to get execution time improvements. The core idea is that
+ /// this mode should include any optimization that helps execution time on
+ /// balance across a diverse collection of benchmarks, even if it increases
+ /// code size or compile time for some benchmarks without corresponding
+ /// improvements to execution time.
+ ///
+ /// Despite being willing to trade more compile time off to get improved
+ /// execution time, this mode still tries to avoid superlinear growth in
+ /// order to make even significantly slower compile times at least scale
+ /// reasonably. This does not preclude very substantial constant factor
+ /// costs though.
+ static const OptimizationLevel O3;
+ /// Similar to \c O2 but tries to optimize for small code size instead of
+ /// fast execution without triggering significant incremental execution
+ /// time slowdowns.
+ ///
+ /// The logic here is exactly the same as \c O2, but with code size and
+ /// execution time metrics swapped.
+ ///
+ /// A consequence of the different core goal is that this should in general
+ /// produce substantially smaller executables that still run in
+ /// a reasonable amount of time.
+ static const OptimizationLevel Os;
+ /// A very specialized mode that will optimize for code size at any and all
+ /// costs.
+ ///
+ /// This is useful primarily when there are absolute size limitations and
+ /// any effort taken to reduce the size is worth it regardless of the
+ /// execution time impact. You should expect this level to produce rather
+ /// slow, but very small, code.
+ static const OptimizationLevel Oz;
+
+ bool isOptimizingForSpeed() const { return SizeLevel == 0 && SpeedLevel > 0; }
+
+ bool isOptimizingForSize() const { return SizeLevel > 0; }
+
+ bool operator==(const OptimizationLevel &Other) const {
+ return SizeLevel == Other.SizeLevel && SpeedLevel == Other.SpeedLevel;
+ }
+ bool operator!=(const OptimizationLevel &Other) const {
+ return SizeLevel != Other.SizeLevel || SpeedLevel != Other.SpeedLevel;
+ }
+
+ unsigned getSpeedupLevel() const { return SpeedLevel; }
+
+ unsigned getSizeLevel() const { return SizeLevel; }
+};
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm14/include/llvm/Passes/PassBuilder.h b/contrib/libs/llvm14/include/llvm/Passes/PassBuilder.h
new file mode 100644
index 0000000000..2535e2d523
--- /dev/null
+++ b/contrib/libs/llvm14/include/llvm/Passes/PassBuilder.h
@@ -0,0 +1,699 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- Parsing, selection, and construction of pass pipelines --*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// Interfaces for registering analysis passes, producing common pass manager
+/// configurations, and parsing of pass pipelines.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_PASSBUILDER_H
+#define LLVM_PASSES_PASSBUILDER_H
+
+#include "llvm/ADT/Optional.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
+#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/OptimizationLevel.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/PGOOptions.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/IPO/Inliner.h"
+#include "llvm/Transforms/IPO/ModuleInliner.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Scalar/LoopPassManager.h"
+#include <vector>
+
+namespace llvm {
+class StringRef;
+class AAManager;
+class TargetMachine;
+class ModuleSummaryIndex;
+
+/// Tunable parameters for passes in the default pipelines.
+class PipelineTuningOptions {
+public:
+ /// Constructor sets pipeline tuning defaults based on cl::opts. Each option
+ /// can be set in the PassBuilder when using a LLVM as a library.
+ PipelineTuningOptions();
+
+ /// Tuning option to set loop interleaving on/off, set based on opt level.
+ bool LoopInterleaving;
+
+ /// Tuning option to enable/disable loop vectorization, set based on opt
+ /// level.
+ bool LoopVectorization;
+
+ /// Tuning option to enable/disable slp loop vectorization, set based on opt
+ /// level.
+ bool SLPVectorization;
+
+ /// Tuning option to enable/disable loop unrolling. Its default value is true.
+ bool LoopUnrolling;
+
+ /// Tuning option to forget all SCEV loops in LoopUnroll. Its default value
+ /// is that of the flag: `-forget-scev-loop-unroll`.
+ bool ForgetAllSCEVInLoopUnroll;
+
+ /// Tuning option to cap the number of calls to retrive clobbering accesses in
+ /// MemorySSA, in LICM.
+ unsigned LicmMssaOptCap;
+
+ /// Tuning option to disable promotion to scalars in LICM with MemorySSA, if
+ /// the number of access is too large.
+ unsigned LicmMssaNoAccForPromotionCap;
+
+ /// Tuning option to enable/disable call graph profile. Its default value is
+ /// that of the flag: `-enable-npm-call-graph-profile`.
+ bool CallGraphProfile;
+
+ /// Tuning option to enable/disable function merging. Its default value is
+ /// false.
+ bool MergeFunctions;
+
+ // Experimental option to eagerly invalidate more analyses. This has the
+ // potential to decrease max memory usage in exchange for more compile time.
+ // This may affect codegen due to either passes using analyses only when
+ // cached, or invalidating and recalculating an analysis that was
+ // stale/imprecise but still valid. Currently this invalidates all function
+ // analyses after various module->function or cgscc->function adaptors in the
+ // default pipelines.
+ bool EagerlyInvalidateAnalyses;
+};
+
+/// This class provides access to building LLVM's passes.
+///
+/// Its members provide the baseline state available to passes during their
+/// construction. The \c PassRegistry.def file specifies how to construct all
+/// of the built-in passes, and those may reference these members during
+/// construction.
+class PassBuilder {
+ TargetMachine *TM;
+ PipelineTuningOptions PTO;
+ Optional<PGOOptions> PGOOpt;
+ PassInstrumentationCallbacks *PIC;
+
+public:
+ /// A struct to capture parsed pass pipeline names.
+ ///
+ /// A pipeline is defined as a series of names, each of which may in itself
+ /// recursively contain a nested pipeline. A name is either the name of a pass
+ /// (e.g. "instcombine") or the name of a pipeline type (e.g. "cgscc"). If the
+ /// name is the name of a pass, the InnerPipeline is empty, since passes
+ /// cannot contain inner pipelines. See parsePassPipeline() for a more
+ /// detailed description of the textual pipeline format.
+ struct PipelineElement {
+ StringRef Name;
+ std::vector<PipelineElement> InnerPipeline;
+ };
+
+ explicit PassBuilder(TargetMachine *TM = nullptr,
+ PipelineTuningOptions PTO = PipelineTuningOptions(),
+ Optional<PGOOptions> PGOOpt = None,
+ PassInstrumentationCallbacks *PIC = nullptr);
+
+ /// Cross register the analysis managers through their proxies.
+ ///
+ /// This is an interface that can be used to cross register each
+ /// AnalysisManager with all the others analysis managers.
+ void crossRegisterProxies(LoopAnalysisManager &LAM,
+ FunctionAnalysisManager &FAM,
+ CGSCCAnalysisManager &CGAM,
+ ModuleAnalysisManager &MAM);
+
+ /// Registers all available module analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c
+ /// ModuleAnalysisManager with all registered module analyses. Callers can
+ /// still manually register any additional analyses. Callers can also
+ /// pre-register analyses and this will not override those.
+ void registerModuleAnalyses(ModuleAnalysisManager &MAM);
+
+ /// Registers all available CGSCC analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c CGSCCAnalysisManager
+ /// with all registered CGSCC analyses. Callers can still manually register any
+ /// additional analyses. Callers can also pre-register analyses and this will
+ /// not override those.
+ void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM);
+
+ /// Registers all available function analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c
+ /// FunctionAnalysisManager with all registered function analyses. Callers can
+ /// still manually register any additional analyses. Callers can also
+ /// pre-register analyses and this will not override those.
+ void registerFunctionAnalyses(FunctionAnalysisManager &FAM);
+
+ /// Registers all available loop analysis passes.
+ ///
+ /// This is an interface that can be used to populate a \c LoopAnalysisManager
+ /// with all registered loop analyses. Callers can still manually register any
+ /// additional analyses.
+ void registerLoopAnalyses(LoopAnalysisManager &LAM);
+
+ /// Construct the core LLVM function canonicalization and simplification
+ /// pipeline.
+ ///
+ /// This is a long pipeline and uses most of the per-function optimization
+ /// passes in LLVM to canonicalize and simplify the IR. It is suitable to run
+ /// repeatedly over the IR and is not expected to destroy important
+ /// information about the semantics of the IR.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ///
+ /// \p Phase indicates the current ThinLTO phase.
+ FunctionPassManager
+ buildFunctionSimplificationPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ /// Construct the core LLVM module canonicalization and simplification
+ /// pipeline.
+ ///
+ /// This pipeline focuses on canonicalizing and simplifying the entire module
+ /// of IR. Much like the function simplification pipeline above, it is
+ /// suitable to run repeatedly over the IR and is not expected to destroy
+ /// important information. It does, however, perform inlining and other
+ /// heuristic based simplifications that are not strictly reversible.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ///
+ /// \p Phase indicates the current ThinLTO phase.
+ ModulePassManager buildModuleSimplificationPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ /// Construct the module pipeline that performs inlining as well as
+ /// the inlining-driven cleanups.
+ ModuleInlinerWrapperPass buildInlinerPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ /// Construct the module pipeline that performs inlining with
+ /// module inliner pass.
+ ModulePassManager buildModuleInlinerPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ /// Construct the core LLVM module optimization pipeline.
+ ///
+ /// This pipeline focuses on optimizing the execution speed of the IR. It
+ /// uses cost modeling and thresholds to balance code growth against runtime
+ /// improvements. It includes vectorization and other information destroying
+ /// transformations. It also cannot generally be run repeatedly on a module
+ /// without potentially seriously regressing either runtime performance of
+ /// the code or serious code size growth.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildModuleOptimizationPipeline(OptimizationLevel Level,
+ bool LTOPreLink = false);
+
+ /// Build a per-module default optimization pipeline.
+ ///
+ /// This provides a good default optimization pipeline for per-module
+ /// optimization and code generation without any link-time optimization. It
+ /// typically correspond to frontend "-O[123]" options for optimization
+ /// levels \c O1, \c O2 and \c O3 resp.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level,
+ bool LTOPreLink = false);
+
+ /// Build a pre-link, ThinLTO-targeting default optimization pipeline to
+ /// a pass manager.
+ ///
+ /// This adds the pre-link optimizations tuned to prepare a module for
+ /// a ThinLTO run. It works to minimize the IR which needs to be analyzed
+ /// without making irreversible decisions which could be made better during
+ /// the LTO run.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level);
+
+ /// Build an ThinLTO default optimization pipeline to a pass manager.
+ ///
+ /// This provides a good default optimization pipeline for link-time
+ /// optimization and code generation. It is particularly tuned to fit well
+ /// when IR coming into the LTO phase was first run through \c
+ /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager
+ buildThinLTODefaultPipeline(OptimizationLevel Level,
+ const ModuleSummaryIndex *ImportSummary);
+
+ /// Build a pre-link, LTO-targeting default optimization pipeline to a pass
+ /// manager.
+ ///
+ /// This adds the pre-link optimizations tuned to work well with a later LTO
+ /// run. It works to minimize the IR which needs to be analyzed without
+ /// making irreversible decisions which could be made better during the LTO
+ /// run.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level);
+
+ /// Build an LTO default optimization pipeline to a pass manager.
+ ///
+ /// This provides a good default optimization pipeline for link-time
+ /// optimization and code generation. It is particularly tuned to fit well
+ /// when IR coming into the LTO phase was first run through \c
+ /// addPreLinkLTODefaultPipeline, and the two coordinate closely.
+ ///
+ /// Note that \p Level cannot be `O0` here. The pipelines produced are
+ /// only intended for use when attempting to optimize code. If frontends
+ /// require some transformations for semantic reasons, they should explicitly
+ /// build them.
+ ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level,
+ ModuleSummaryIndex *ExportSummary);
+
+ /// Build an O0 pipeline with the minimal semantically required passes.
+ ///
+ /// This should only be used for non-LTO and LTO pre-link pipelines.
+ ModulePassManager buildO0DefaultPipeline(OptimizationLevel Level,
+ bool LTOPreLink = false);
+
+ /// Build the default `AAManager` with the default alias analysis pipeline
+ /// registered.
+ ///
+ /// This also adds target-specific alias analyses registered via
+ /// TargetMachine::registerDefaultAliasAnalyses().
+ AAManager buildDefaultAAPipeline();
+
+ /// Parse a textual pass pipeline description into a \c
+ /// ModulePassManager.
+ ///
+ /// The format of the textual pass pipeline description looks something like:
+ ///
+ /// module(function(instcombine,sroa),dce,cgscc(inliner,function(...)),...)
+ ///
+ /// Pass managers have ()s describing the nest structure of passes. All passes
+ /// are comma separated. As a special shortcut, if the very first pass is not
+ /// a module pass (as a module pass manager is), this will automatically form
+ /// the shortest stack of pass managers that allow inserting that first pass.
+ /// So, assuming function passes 'fpassN', CGSCC passes 'cgpassN', and loop
+ /// passes 'lpassN', all of these are valid:
+ ///
+ /// fpass1,fpass2,fpass3
+ /// cgpass1,cgpass2,cgpass3
+ /// lpass1,lpass2,lpass3
+ ///
+ /// And they are equivalent to the following (resp.):
+ ///
+ /// module(function(fpass1,fpass2,fpass3))
+ /// module(cgscc(cgpass1,cgpass2,cgpass3))
+ /// module(function(loop(lpass1,lpass2,lpass3)))
+ ///
+ /// This shortcut is especially useful for debugging and testing small pass
+ /// combinations.
+ ///
+ /// The sequence of passes aren't necessarily the exact same kind of pass.
+ /// You can mix different levels implicitly if adaptor passes are defined to
+ /// make them work. For example,
+ ///
+ /// mpass1,fpass1,fpass2,mpass2,lpass1
+ ///
+ /// This pipeline uses only one pass manager: the top-level module manager.
+ /// fpass1,fpass2 and lpass1 are added into the the top-level module manager
+ /// using only adaptor passes. No nested function/loop pass managers are
+ /// added. The purpose is to allow easy pass testing when the user
+ /// specifically want the pass to run under a adaptor directly. This is
+ /// preferred when a pipeline is largely of one type, but one or just a few
+ /// passes are of different types(See PassBuilder.cpp for examples).
+ Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText);
+
+ /// {{@ Parse a textual pass pipeline description into a specific PassManager
+ ///
+ /// Automatic deduction of an appropriate pass manager stack is not supported.
+ /// For example, to insert a loop pass 'lpass' into a FunctionPassManager,
+ /// this is the valid pipeline text:
+ ///
+ /// function(lpass)
+ Error parsePassPipeline(CGSCCPassManager &CGPM, StringRef PipelineText);
+ Error parsePassPipeline(FunctionPassManager &FPM, StringRef PipelineText);
+ Error parsePassPipeline(LoopPassManager &LPM, StringRef PipelineText);
+ /// @}}
+
+ /// Parse a textual alias analysis pipeline into the provided AA manager.
+ ///
+ /// The format of the textual AA pipeline is a comma separated list of AA
+ /// pass names:
+ ///
+ /// basic-aa,globals-aa,...
+ ///
+ /// The AA manager is set up such that the provided alias analyses are tried
+ /// in the order specified. See the \c AAManaager documentation for details
+ /// about the logic used. This routine just provides the textual mapping
+ /// between AA names and the analyses to register with the manager.
+ ///
+ /// Returns false if the text cannot be parsed cleanly. The specific state of
+ /// the \p AA manager is unspecified if such an error is encountered and this
+ /// returns false.
+ Error parseAAPipeline(AAManager &AA, StringRef PipelineText);
+
+ /// Returns true if the pass name is the name of an alias analysis pass.
+ bool isAAPassName(StringRef PassName);
+
+ /// Returns true if the pass name is the name of a (non-alias) analysis pass.
+ bool isAnalysisPassName(StringRef PassName);
+
+ /// Print pass names.
+ void printPassNames(raw_ostream &OS);
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// 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.
+ void registerPeepholeEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ PeepholeEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// 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.
+ void registerLateLoopOptimizationsEPCallback(
+ const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
+ LateLoopOptimizationsEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding loop passes to the end of the loop
+ /// optimizer.
+ void registerLoopOptimizerEndEPCallback(
+ const std::function<void(LoopPassManager &, OptimizationLevel)> &C) {
+ LoopOptimizerEndEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding optimization passes after most of the
+ /// main optimizations, but before the last cleanup-ish optimizations.
+ void registerScalarOptimizerLateEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ ScalarOptimizerLateEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding CallGraphSCC passes at the end of the
+ /// main CallGraphSCC passes and before any function simplification passes run
+ /// by CGPassManager.
+ void registerCGSCCOptimizerLateEPCallback(
+ const std::function<void(CGSCCPassManager &, OptimizationLevel)> &C) {
+ CGSCCOptimizerLateEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension
+ /// point
+ ///
+ /// This extension point allows adding optimization passes before the
+ /// vectorizer and other highly target specific optimization passes are
+ /// executed.
+ void registerVectorizerStartEPCallback(
+ const std::function<void(FunctionPassManager &, OptimizationLevel)> &C) {
+ VectorizerStartEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension point.
+ ///
+ /// This extension point allows adding optimization once at the start of the
+ /// pipeline. This does not apply to 'backend' compiles (LTO and ThinLTO
+ /// link-time pipelines).
+ void registerPipelineStartEPCallback(
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
+ PipelineStartEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension point.
+ ///
+ /// This extension point allows adding optimization right after passes that do
+ /// basic simplification of the input IR.
+ void registerPipelineEarlySimplificationEPCallback(
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
+ PipelineEarlySimplificationEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for a default optimizer pipeline extension point
+ ///
+ /// This extension point allows adding optimizations at the very end of the
+ /// function optimization pipeline.
+ void registerOptimizerLastEPCallback(
+ const std::function<void(ModulePassManager &, OptimizationLevel)> &C) {
+ OptimizerLastEPCallbacks.push_back(C);
+ }
+
+ /// Register a callback for parsing an AliasAnalysis Name to populate
+ /// the given AAManager \p AA
+ void registerParseAACallback(
+ const std::function<bool(StringRef Name, AAManager &AA)> &C) {
+ AAParsingCallbacks.push_back(C);
+ }
+
+ /// {{@ Register callbacks for analysis registration with this PassBuilder
+ /// instance.
+ /// Callees register their analyses with the given AnalysisManager objects.
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(CGSCCAnalysisManager &)> &C) {
+ CGSCCAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(FunctionAnalysisManager &)> &C) {
+ FunctionAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(LoopAnalysisManager &)> &C) {
+ LoopAnalysisRegistrationCallbacks.push_back(C);
+ }
+ void registerAnalysisRegistrationCallback(
+ const std::function<void(ModuleAnalysisManager &)> &C) {
+ ModuleAnalysisRegistrationCallbacks.push_back(C);
+ }
+ /// @}}
+
+ /// {{@ Register pipeline parsing callbacks with this pass builder instance.
+ /// Using these callbacks, callers can parse both a single pass name, as well
+ /// as entire sub-pipelines, and populate the PassManager instance
+ /// accordingly.
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, CGSCCPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ CGSCCPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, FunctionPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ FunctionPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, LoopPassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ LoopPipelineParsingCallbacks.push_back(C);
+ }
+ void registerPipelineParsingCallback(
+ const std::function<bool(StringRef Name, ModulePassManager &,
+ ArrayRef<PipelineElement>)> &C) {
+ ModulePipelineParsingCallbacks.push_back(C);
+ }
+ /// @}}
+
+ /// Register a callback for a top-level pipeline entry.
+ ///
+ /// If the PassManager type is not given at the top level of the pipeline
+ /// text, this Callback should be used to determine the appropriate stack of
+ /// PassManagers and populate the passed ModulePassManager.
+ void registerParseTopLevelPipelineCallback(
+ const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
+ &C);
+
+ /// Add PGOInstrumenation passes for O0 only.
+ void addPGOInstrPassesForO0(ModulePassManager &MPM, bool RunProfileGen,
+ bool IsCS, std::string ProfileFile,
+ std::string ProfileRemappingFile);
+
+ /// Returns PIC. External libraries can use this to register pass
+ /// instrumentation callbacks.
+ PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {
+ return PIC;
+ }
+
+private:
+ // O1 pass pipeline
+ FunctionPassManager
+ buildO1FunctionSimplificationPipeline(OptimizationLevel Level,
+ ThinOrFullLTOPhase Phase);
+
+ void addRequiredLTOPreLinkPasses(ModulePassManager &MPM);
+
+ void addVectorPasses(OptimizationLevel Level, FunctionPassManager &FPM,
+ bool IsFullLTO);
+
+ static Optional<std::vector<PipelineElement>>
+ parsePipelineText(StringRef Text);
+
+ Error parseModulePass(ModulePassManager &MPM, const PipelineElement &E);
+ Error parseCGSCCPass(CGSCCPassManager &CGPM, const PipelineElement &E);
+ Error parseFunctionPass(FunctionPassManager &FPM, const PipelineElement &E);
+ Error parseLoopPass(LoopPassManager &LPM, const PipelineElement &E);
+ bool parseAAPassName(AAManager &AA, StringRef Name);
+
+ Error parseLoopPassPipeline(LoopPassManager &LPM,
+ ArrayRef<PipelineElement> Pipeline);
+ Error parseFunctionPassPipeline(FunctionPassManager &FPM,
+ ArrayRef<PipelineElement> Pipeline);
+ Error parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
+ ArrayRef<PipelineElement> Pipeline);
+ Error parseModulePassPipeline(ModulePassManager &MPM,
+ ArrayRef<PipelineElement> Pipeline);
+
+ void addPGOInstrPasses(ModulePassManager &MPM, OptimizationLevel Level,
+ bool RunProfileGen, bool IsCS, std::string ProfileFile,
+ std::string ProfileRemappingFile);
+ void invokePeepholeEPCallbacks(FunctionPassManager &, OptimizationLevel);
+
+ // Extension Point callbacks
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ PeepholeEPCallbacks;
+ SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
+ LateLoopOptimizationsEPCallbacks;
+ SmallVector<std::function<void(LoopPassManager &, OptimizationLevel)>, 2>
+ LoopOptimizerEndEPCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ ScalarOptimizerLateEPCallbacks;
+ SmallVector<std::function<void(CGSCCPassManager &, OptimizationLevel)>, 2>
+ CGSCCOptimizerLateEPCallbacks;
+ SmallVector<std::function<void(FunctionPassManager &, OptimizationLevel)>, 2>
+ VectorizerStartEPCallbacks;
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
+ OptimizerLastEPCallbacks;
+ // Module callbacks
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
+ PipelineStartEPCallbacks;
+ SmallVector<std::function<void(ModulePassManager &, OptimizationLevel)>, 2>
+ PipelineEarlySimplificationEPCallbacks;
+
+ SmallVector<std::function<void(ModuleAnalysisManager &)>, 2>
+ ModuleAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, ModulePassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ ModulePipelineParsingCallbacks;
+ SmallVector<
+ std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>, 2>
+ TopLevelPipelineParsingCallbacks;
+ // CGSCC callbacks
+ SmallVector<std::function<void(CGSCCAnalysisManager &)>, 2>
+ CGSCCAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, CGSCCPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ CGSCCPipelineParsingCallbacks;
+ // Function callbacks
+ SmallVector<std::function<void(FunctionAnalysisManager &)>, 2>
+ FunctionAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, FunctionPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ FunctionPipelineParsingCallbacks;
+ // Loop callbacks
+ SmallVector<std::function<void(LoopAnalysisManager &)>, 2>
+ LoopAnalysisRegistrationCallbacks;
+ SmallVector<std::function<bool(StringRef, LoopPassManager &,
+ ArrayRef<PipelineElement>)>,
+ 2>
+ LoopPipelineParsingCallbacks;
+ // AA callbacks
+ SmallVector<std::function<bool(StringRef Name, AAManager &AA)>, 2>
+ AAParsingCallbacks;
+};
+
+/// This utility template takes care of adding require<> and invalidate<>
+/// passes for an analysis to a given \c PassManager. It is intended to be used
+/// during parsing of a pass pipeline when parsing a single PipelineName.
+/// When registering a new function analysis FancyAnalysis with the pass
+/// pipeline name "fancy-analysis", a matching ParsePipelineCallback could look
+/// like this:
+///
+/// static bool parseFunctionPipeline(StringRef Name, FunctionPassManager &FPM,
+/// ArrayRef<PipelineElement> P) {
+/// if (parseAnalysisUtilityPasses<FancyAnalysis>("fancy-analysis", Name,
+/// FPM))
+/// return true;
+/// return false;
+/// }
+template <typename AnalysisT, typename IRUnitT, typename AnalysisManagerT,
+ typename... ExtraArgTs>
+bool parseAnalysisUtilityPasses(
+ StringRef AnalysisName, StringRef PipelineName,
+ PassManager<IRUnitT, AnalysisManagerT, ExtraArgTs...> &PM) {
+ if (!PipelineName.endswith(">"))
+ return false;
+ // See if this is an invalidate<> pass name
+ if (PipelineName.startswith("invalidate<")) {
+ PipelineName = PipelineName.substr(11, PipelineName.size() - 12);
+ if (PipelineName != AnalysisName)
+ return false;
+ PM.addPass(InvalidateAnalysisPass<AnalysisT>());
+ return true;
+ }
+
+ // See if this is a require<> pass name
+ if (PipelineName.startswith("require<")) {
+ PipelineName = PipelineName.substr(8, PipelineName.size() - 9);
+ if (PipelineName != AnalysisName)
+ return false;
+ PM.addPass(RequireAnalysisPass<AnalysisT, IRUnitT, AnalysisManagerT,
+ ExtraArgTs...>());
+ return true;
+ }
+
+ return false;
+}
+}
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm14/include/llvm/Passes/PassPlugin.h b/contrib/libs/llvm14/include/llvm/Passes/PassPlugin.h
new file mode 100644
index 0000000000..29b4691d37
--- /dev/null
+++ b/contrib/libs/llvm14/include/llvm/Passes/PassPlugin.h
@@ -0,0 +1,124 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- llvm/Passes/PassPlugin.h - Public Plugin API -----------------------===//
+//
+// 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 defines the public entry point for new-PM pass plugins.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_PASSPLUGIN_H
+#define LLVM_PASSES_PASSPLUGIN_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Support/Error.h"
+#include <cstdint>
+#include <string>
+
+namespace llvm {
+class PassBuilder;
+
+/// \macro LLVM_PLUGIN_API_VERSION
+/// Identifies the API version understood by this plugin.
+///
+/// When a plugin is loaded, the driver will check it's supported plugin version
+/// against that of the plugin. A mismatch is an error. The supported version
+/// will be incremented for ABI-breaking changes to the \c PassPluginLibraryInfo
+/// struct, i.e. when callbacks are added, removed, or reordered.
+#define LLVM_PLUGIN_API_VERSION 1
+
+extern "C" {
+/// Information about the plugin required to load its passes
+///
+/// This struct defines the core interface for pass plugins and is supposed to
+/// be filled out by plugin implementors. LLVM-side users of a plugin are
+/// expected to use the \c PassPlugin class below to interface with it.
+struct PassPluginLibraryInfo {
+ /// The API version understood by this plugin, usually \c
+ /// LLVM_PLUGIN_API_VERSION
+ uint32_t APIVersion;
+ /// A meaningful name of the plugin.
+ const char *PluginName;
+ /// The version of the plugin.
+ const char *PluginVersion;
+
+ /// The callback for registering plugin passes with a \c PassBuilder
+ /// instance
+ void (*RegisterPassBuilderCallbacks)(PassBuilder &);
+};
+}
+
+/// A loaded pass plugin.
+///
+/// An instance of this class wraps a loaded pass plugin and gives access to
+/// its interface defined by the \c PassPluginLibraryInfo it exposes.
+class PassPlugin {
+public:
+ /// Attempts to load a pass plugin from a given file.
+ ///
+ /// \returns Returns an error if either the library cannot be found or loaded,
+ /// there is no public entry point, or the plugin implements the wrong API
+ /// version.
+ static Expected<PassPlugin> Load(const std::string &Filename);
+
+ /// Get the filename of the loaded plugin.
+ StringRef getFilename() const { return Filename; }
+
+ /// Get the plugin name
+ StringRef getPluginName() const { return Info.PluginName; }
+
+ /// Get the plugin version
+ StringRef getPluginVersion() const { return Info.PluginVersion; }
+
+ /// Get the plugin API version
+ uint32_t getAPIVersion() const { return Info.APIVersion; }
+
+ /// Invoke the PassBuilder callback registration
+ void registerPassBuilderCallbacks(PassBuilder &PB) const {
+ Info.RegisterPassBuilderCallbacks(PB);
+ }
+
+private:
+ PassPlugin(const std::string &Filename, const sys::DynamicLibrary &Library)
+ : Filename(Filename), Library(Library), Info() {}
+
+ std::string Filename;
+ sys::DynamicLibrary Library;
+ PassPluginLibraryInfo Info;
+};
+}
+
+/// The public entry point for a pass plugin.
+///
+/// When a plugin is loaded by the driver, it will call this entry point to
+/// obtain information about this plugin and about how to register its passes.
+/// This function needs to be implemented by the plugin, see the example below:
+///
+/// ```
+/// extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+/// llvmGetPassPluginInfo() {
+/// return {
+/// LLVM_PLUGIN_API_VERSION, "MyPlugin", "v0.1", [](PassBuilder &PB) { ... }
+/// };
+/// }
+/// ```
+extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
+llvmGetPassPluginInfo();
+
+#endif /* LLVM_PASSES_PASSPLUGIN_H */
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
diff --git a/contrib/libs/llvm14/include/llvm/Passes/StandardInstrumentations.h b/contrib/libs/llvm14/include/llvm/Passes/StandardInstrumentations.h
new file mode 100644
index 0000000000..dd56fe8764
--- /dev/null
+++ b/contrib/libs/llvm14/include/llvm/Passes/StandardInstrumentations.h
@@ -0,0 +1,546 @@
+#pragma once
+
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+//===- StandardInstrumentations.h ------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This header defines a class that provides bookkeeping for all standard
+/// (i.e in-tree) pass instrumentations.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
+#define LLVM_PASSES_STANDARDINSTRUMENTATIONS_H
+
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/OptBisect.h"
+#include "llvm/IR/PassTimingInfo.h"
+#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Transforms/IPO/SampleProfileProbe.h"
+
+#include <string>
+#include <utility>
+
+namespace llvm {
+
+class Module;
+class Function;
+class PassInstrumentationCallbacks;
+
+/// Instrumentation to print IR before/after passes.
+///
+/// Needs state to be able to print module after pass that invalidates IR unit
+/// (typically Loop or SCC).
+class PrintIRInstrumentation {
+public:
+ ~PrintIRInstrumentation();
+
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ void printBeforePass(StringRef PassID, Any IR);
+ void printAfterPass(StringRef PassID, Any IR);
+ void printAfterPassInvalidated(StringRef PassID);
+
+ bool shouldPrintBeforePass(StringRef PassID);
+ bool shouldPrintAfterPass(StringRef PassID);
+
+ using PrintModuleDesc = std::tuple<const Module *, std::string, StringRef>;
+
+ void pushModuleDesc(StringRef PassID, Any IR);
+ PrintModuleDesc popModuleDesc(StringRef PassID);
+
+ PassInstrumentationCallbacks *PIC;
+ /// Stack of Module description, enough to print the module after a given
+ /// pass.
+ SmallVector<PrintModuleDesc, 2> ModuleDescStack;
+};
+
+class OptNoneInstrumentation {
+public:
+ OptNoneInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ bool DebugLogging;
+ bool shouldRun(StringRef PassID, Any IR);
+};
+
+class OptBisectInstrumentation {
+public:
+ OptBisectInstrumentation() = default;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
+struct PrintPassOptions {
+ /// Print adaptors and pass managers.
+ bool Verbose = false;
+ /// Don't print information for analyses.
+ bool SkipAnalyses = false;
+ /// Indent based on hierarchy.
+ bool Indent = false;
+};
+
+// Debug logging for transformation and analysis passes.
+class PrintPassInstrumentation {
+ raw_ostream &print();
+
+public:
+ PrintPassInstrumentation(bool Enabled, PrintPassOptions Opts)
+ : Enabled(Enabled), Opts(Opts) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+private:
+ bool Enabled;
+ PrintPassOptions Opts;
+ int Indent = 0;
+};
+
+class PreservedCFGCheckerInstrumentation {
+public:
+ // Keeps sticky poisoned flag for the given basic block once it has been
+ // deleted or RAUWed.
+ struct BBGuard final : public CallbackVH {
+ BBGuard(const BasicBlock *BB) : CallbackVH(BB) {}
+ void deleted() override { CallbackVH::deleted(); }
+ void allUsesReplacedWith(Value *) override { CallbackVH::deleted(); }
+ bool isPoisoned() const { return !getValPtr(); }
+ };
+
+ // CFG is a map BB -> {(Succ, Multiplicity)}, where BB is a non-leaf basic
+ // block, {(Succ, Multiplicity)} set of all pairs of the block's successors
+ // and the multiplicity of the edge (BB->Succ). As the mapped sets are
+ // unordered the order of successors is not tracked by the CFG. In other words
+ // this allows basic block successors to be swapped by a pass without
+ // reporting a CFG change. CFG can be guarded by basic block tracking pointers
+ // in the Graph (BBGuard). That is if any of the block is deleted or RAUWed
+ // then the CFG is treated poisoned and no block pointer of the Graph is used.
+ struct CFG {
+ Optional<DenseMap<intptr_t, BBGuard>> BBGuards;
+ DenseMap<const BasicBlock *, DenseMap<const BasicBlock *, unsigned>> Graph;
+
+ CFG(const Function *F, bool TrackBBLifetime);
+
+ bool operator==(const CFG &G) const {
+ return !isPoisoned() && !G.isPoisoned() && Graph == G.Graph;
+ }
+
+ bool isPoisoned() const {
+ return BBGuards &&
+ std::any_of(BBGuards->begin(), BBGuards->end(),
+ [](const auto &BB) { return BB.second.isPoisoned(); });
+ }
+
+ static void printDiff(raw_ostream &out, const CFG &Before,
+ const CFG &After);
+ bool invalidate(Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &);
+ };
+
+#ifdef LLVM_ENABLE_ABI_BREAKING_CHECKS
+ SmallVector<StringRef, 8> PassStack;
+#endif
+
+ static cl::opt<bool> VerifyPreservedCFG;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC,
+ FunctionAnalysisManager &FAM);
+};
+
+// Base class for classes that report changes to the IR.
+// It presents an interface for such classes and provides calls
+// on various events as the new pass manager transforms the IR.
+// It also provides filtering of information based on hidden options
+// specifying which functions are interesting.
+// Calls are made for the following events/queries:
+// 1. The initial IR processed.
+// 2. To get the representation of the IR (of type \p T).
+// 3. When a pass does not change the IR.
+// 4. When a pass changes the IR (given both before and after representations
+// of type \p T).
+// 5. When an IR is invalidated.
+// 6. When a pass is run on an IR that is not interesting (based on options).
+// 7. When a pass is ignored (pass manager or adapter pass).
+// 8. To compare two IR representations (of type \p T).
+template <typename IRUnitT> class ChangeReporter {
+protected:
+ ChangeReporter(bool RunInVerboseMode) : VerboseMode(RunInVerboseMode) {}
+
+public:
+ virtual ~ChangeReporter();
+
+ // Determine if this pass/IR is interesting and if so, save the IR
+ // otherwise it is left on the stack without data.
+ void saveIRBeforePass(Any IR, StringRef PassID);
+ // Compare the IR from before the pass after the pass.
+ void handleIRAfterPass(Any IR, StringRef PassID);
+ // Handle the situation where a pass is invalidated.
+ void handleInvalidatedPass(StringRef PassID);
+
+protected:
+ // Register required callbacks.
+ void registerRequiredCallbacks(PassInstrumentationCallbacks &PIC);
+
+ // Return true when this is a defined function for which printing
+ // of changes is desired.
+ bool isInterestingFunction(const Function &F);
+
+ // Return true when this is a pass for which printing of changes is desired.
+ bool isInterestingPass(StringRef PassID);
+
+ // Return true when this is a pass on IR for which printing
+ // of changes is desired.
+ bool isInteresting(Any IR, StringRef PassID);
+
+ // Called on the first IR processed.
+ virtual void handleInitialIR(Any IR) = 0;
+ // Called before and after a pass to get the representation of the IR.
+ virtual void generateIRRepresentation(Any IR, StringRef PassID,
+ IRUnitT &Output) = 0;
+ // Called when the pass is not iteresting.
+ virtual void omitAfter(StringRef PassID, std::string &Name) = 0;
+ // Called when an interesting IR has changed.
+ virtual void handleAfter(StringRef PassID, std::string &Name,
+ const IRUnitT &Before, const IRUnitT &After,
+ Any) = 0;
+ // Called when an interesting pass is invalidated.
+ virtual void handleInvalidated(StringRef PassID) = 0;
+ // Called when the IR or pass is not interesting.
+ virtual void handleFiltered(StringRef PassID, std::string &Name) = 0;
+ // Called when an ignored pass is encountered.
+ virtual void handleIgnored(StringRef PassID, std::string &Name) = 0;
+
+ // Stack of IRs before passes.
+ std::vector<IRUnitT> BeforeStack;
+ // Is this the first IR seen?
+ bool InitialIR = true;
+
+ // Run in verbose mode, printing everything?
+ const bool VerboseMode;
+};
+
+// An abstract template base class that handles printing banners and
+// reporting when things have not changed or are filtered out.
+template <typename IRUnitT>
+class TextChangeReporter : public ChangeReporter<IRUnitT> {
+protected:
+ TextChangeReporter(bool Verbose);
+
+ // Print a module dump of the first IR that is changed.
+ void handleInitialIR(Any IR) override;
+ // Report that the IR was omitted because it did not change.
+ void omitAfter(StringRef PassID, std::string &Name) override;
+ // Report that the pass was invalidated.
+ void handleInvalidated(StringRef PassID) override;
+ // Report that the IR was filtered out.
+ void handleFiltered(StringRef PassID, std::string &Name) override;
+ // Report that the pass was ignored.
+ void handleIgnored(StringRef PassID, std::string &Name) override;
+ // Make substitutions in \p S suitable for reporting changes
+ // after the pass and then print it.
+
+ raw_ostream &Out;
+};
+
+// A change printer based on the string representation of the IR as created
+// by unwrapAndPrint. The string representation is stored in a std::string
+// to preserve it as the IR changes in each pass. Note that the banner is
+// included in this representation but it is massaged before reporting.
+class IRChangedPrinter : public TextChangeReporter<std::string> {
+public:
+ IRChangedPrinter(bool VerboseMode)
+ : TextChangeReporter<std::string>(VerboseMode) {}
+ ~IRChangedPrinter() override;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+protected:
+ // Called before and after a pass to get the representation of the IR.
+ void generateIRRepresentation(Any IR, StringRef PassID,
+ std::string &Output) override;
+ // Called when an interesting IR has changed.
+ void handleAfter(StringRef PassID, std::string &Name,
+ const std::string &Before, const std::string &After,
+ Any) override;
+};
+
+// Information that needs to be saved for a basic block in order to compare
+// before and after the pass to determine if it was changed by a pass.
+template <typename T> class BlockDataT {
+public:
+ BlockDataT(const BasicBlock &B) : Label(B.getName().str()), Data(B) {
+ raw_string_ostream SS(Body);
+ B.print(SS, nullptr, true, true);
+ }
+
+ bool operator==(const BlockDataT &That) const { return Body == That.Body; }
+ bool operator!=(const BlockDataT &That) const { return Body != That.Body; }
+
+ // Return the label of the represented basic block.
+ StringRef getLabel() const { return Label; }
+ // Return the string representation of the basic block.
+ StringRef getBody() const { return Body; }
+
+ // Return the associated data
+ const T &getData() const { return Data; }
+
+protected:
+ std::string Label;
+ std::string Body;
+
+ // Extra data associated with a basic block
+ T Data;
+};
+
+template <typename T> class OrderedChangedData {
+public:
+ // Return the names in the order they were saved
+ std::vector<std::string> &getOrder() { return Order; }
+ const std::vector<std::string> &getOrder() const { return Order; }
+
+ // Return a map of names to saved representations
+ StringMap<T> &getData() { return Data; }
+ const StringMap<T> &getData() const { return Data; }
+
+ bool operator==(const OrderedChangedData<T> &That) const {
+ return Data == That.getData();
+ }
+
+ // Call the lambda \p HandlePair on each corresponding pair of data from
+ // \p Before and \p After. The order is based on the order in \p After
+ // with ones that are only in \p Before interspersed based on where they
+ // occur in \p Before. This is used to present the output in an order
+ // based on how the data is ordered in LLVM.
+ static void report(const OrderedChangedData &Before,
+ const OrderedChangedData &After,
+ function_ref<void(const T *, const T *)> HandlePair);
+
+protected:
+ std::vector<std::string> Order;
+ StringMap<T> Data;
+};
+
+// Do not need extra information for patch-style change reporter.
+class EmptyData {
+public:
+ EmptyData(const BasicBlock &) {}
+};
+
+// The data saved for comparing functions.
+template <typename T>
+class FuncDataT : public OrderedChangedData<BlockDataT<T>> {
+public:
+ FuncDataT(std::string S) : EntryBlockName(S) {}
+
+ // Return the name of the entry block
+ std::string getEntryBlockName() const { return EntryBlockName; }
+
+protected:
+ std::string EntryBlockName;
+};
+
+// The data saved for comparing IRs.
+template <typename T>
+class IRDataT : public OrderedChangedData<FuncDataT<T>> {};
+
+// Abstract template base class for a class that compares two IRs. The
+// class is created with the 2 IRs to compare and then compare is called.
+// The static function analyzeIR is used to build up the IR representation.
+template <typename T> class IRComparer {
+public:
+ IRComparer(const IRDataT<T> &Before, const IRDataT<T> &After)
+ : Before(Before), After(After) {}
+
+ // Compare the 2 IRs. \p handleFunctionCompare is called to handle the
+ // compare of a function. When \p InModule is set,
+ // this function is being handled as part of comparing a module.
+ void compare(
+ bool CompareModule,
+ std::function<void(bool InModule, unsigned Minor,
+ const FuncDataT<T> &Before, const FuncDataT<T> &After)>
+ CompareFunc);
+
+ // Analyze \p IR and build the IR representation in \p Data.
+ static void analyzeIR(Any IR, IRDataT<T> &Data);
+
+protected:
+ // Generate the data for \p F into \p Data.
+ static bool generateFunctionData(IRDataT<T> &Data, const Function &F);
+
+ const IRDataT<T> &Before;
+ const IRDataT<T> &After;
+};
+
+// A change printer that prints out in-line differences in the basic
+// blocks. It uses an InlineComparer to do the comparison so it shows
+// the differences prefixed with '-' and '+' for code that is removed
+// and added, respectively. Changes to the IR that do not affect basic
+// blocks are not reported as having changed the IR. The option
+// -print-module-scope does not affect this change reporter.
+class InLineChangePrinter : public TextChangeReporter<IRDataT<EmptyData>> {
+public:
+ InLineChangePrinter(bool VerboseMode, bool ColourMode)
+ : TextChangeReporter<IRDataT<EmptyData>>(VerboseMode),
+ UseColour(ColourMode) {}
+ ~InLineChangePrinter() override;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+protected:
+ // Create a representation of the IR.
+ virtual void generateIRRepresentation(Any IR, StringRef PassID,
+ IRDataT<EmptyData> &Output) override;
+
+ // Called when an interesting IR has changed.
+ virtual void handleAfter(StringRef PassID, std::string &Name,
+ const IRDataT<EmptyData> &Before,
+ const IRDataT<EmptyData> &After, Any) override;
+
+ void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
+ StringRef Divider, bool InModule, unsigned Minor,
+ const FuncDataT<EmptyData> &Before,
+ const FuncDataT<EmptyData> &After);
+
+ bool UseColour;
+};
+
+class VerifyInstrumentation {
+ bool DebugLogging;
+
+public:
+ VerifyInstrumentation(bool DebugLogging) : DebugLogging(DebugLogging) {}
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+};
+
+// Class that holds transitions between basic blocks. The transitions
+// are contained in a map of values to names of basic blocks.
+class DCData {
+public:
+ // Fill the map with the transitions from basic block \p B.
+ DCData(const BasicBlock &B);
+
+ // Return an iterator to the names of the successor blocks.
+ StringMap<std::string>::const_iterator begin() const {
+ return Successors.begin();
+ }
+ StringMap<std::string>::const_iterator end() const {
+ return Successors.end();
+ }
+
+ // Return the label of the basic block reached on a transition on \p S.
+ StringRef getSuccessorLabel(StringRef S) const {
+ assert(Successors.count(S) == 1 && "Expected to find successor.");
+ return Successors.find(S)->getValue();
+ }
+
+protected:
+ // Add a transition to \p Succ on \p Label
+ void addSuccessorLabel(StringRef Succ, StringRef Label) {
+ std::pair<std::string, std::string> SS{Succ.str(), Label.str()};
+ Successors.insert(SS);
+ }
+
+ StringMap<std::string> Successors;
+};
+
+// A change reporter that builds a website with links to pdf files showing
+// dot control flow graphs with changed instructions shown in colour.
+class DotCfgChangeReporter : public ChangeReporter<IRDataT<DCData>> {
+public:
+ DotCfgChangeReporter(bool Verbose);
+ ~DotCfgChangeReporter() override;
+ void registerCallbacks(PassInstrumentationCallbacks &PIC);
+
+protected:
+ // Initialize the HTML file and output the header.
+ bool initializeHTML();
+
+ // Called on the first IR processed.
+ void handleInitialIR(Any IR) override;
+ // Called before and after a pass to get the representation of the IR.
+ void generateIRRepresentation(Any IR, StringRef PassID,
+ IRDataT<DCData> &Output) override;
+ // Called when the pass is not iteresting.
+ void omitAfter(StringRef PassID, std::string &Name) override;
+ // Called when an interesting IR has changed.
+ void handleAfter(StringRef PassID, std::string &Name,
+ const IRDataT<DCData> &Before, const IRDataT<DCData> &After,
+ Any) override;
+ // Called when an interesting pass is invalidated.
+ void handleInvalidated(StringRef PassID) override;
+ // Called when the IR or pass is not interesting.
+ void handleFiltered(StringRef PassID, std::string &Name) override;
+ // Called when an ignored pass is encountered.
+ void handleIgnored(StringRef PassID, std::string &Name) override;
+
+ // Generate the pdf file into \p Dir / \p PDFFileName using \p DotFile as
+ // input and return the html <a> tag with \Text as the content.
+ static std::string genHTML(StringRef Text, StringRef DotFile,
+ StringRef PDFFileName);
+
+ void handleFunctionCompare(StringRef Name, StringRef Prefix, StringRef PassID,
+ StringRef Divider, bool InModule, unsigned Minor,
+ const FuncDataT<DCData> &Before,
+ const FuncDataT<DCData> &After);
+
+ unsigned N = 0;
+ std::unique_ptr<raw_fd_ostream> HTML;
+};
+
+/// This class provides an interface to register all the standard pass
+/// instrumentations and manages their state (if any).
+class StandardInstrumentations {
+ PrintIRInstrumentation PrintIR;
+ PrintPassInstrumentation PrintPass;
+ TimePassesHandler TimePasses;
+ OptNoneInstrumentation OptNone;
+ OptBisectInstrumentation OptBisect;
+ PreservedCFGCheckerInstrumentation PreservedCFGChecker;
+ IRChangedPrinter PrintChangedIR;
+ PseudoProbeVerifier PseudoProbeVerification;
+ InLineChangePrinter PrintChangedDiff;
+ DotCfgChangeReporter WebsiteChangeReporter;
+ VerifyInstrumentation Verify;
+
+ bool VerifyEach;
+
+public:
+ StandardInstrumentations(bool DebugLogging, bool VerifyEach = false,
+ PrintPassOptions PrintPassOpts = PrintPassOptions());
+
+ // Register all the standard instrumentation callbacks. If \p FAM is nullptr
+ // then PreservedCFGChecker is not enabled.
+ void registerCallbacks(PassInstrumentationCallbacks &PIC,
+ FunctionAnalysisManager *FAM = nullptr);
+
+ TimePassesHandler &getTimePasses() { return TimePasses; }
+};
+
+extern template class ChangeReporter<std::string>;
+extern template class TextChangeReporter<std::string>;
+
+extern template class BlockDataT<EmptyData>;
+extern template class FuncDataT<EmptyData>;
+extern template class IRDataT<EmptyData>;
+extern template class ChangeReporter<IRDataT<EmptyData>>;
+extern template class TextChangeReporter<IRDataT<EmptyData>>;
+extern template class IRComparer<EmptyData>;
+
+} // namespace llvm
+
+#endif
+
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif