//===- Analysis.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 /// Pass manager infrastructure for declaring and invalidating analyses. //===----------------------------------------------------------------------===// #ifndef LLVM_IR_ANALYSIS_H #define LLVM_IR_ANALYSIS_H #include "llvm/ADT/SmallPtrSet.h" namespace llvm { class Function; class Module; /// A special type used by analysis passes to provide an address that /// identifies that particular analysis pass type. /// /// Analysis passes should have a static data member of this type and derive /// from the \c AnalysisInfoMixin to get a static ID method used to identify /// the analysis in the pass management infrastructure. struct alignas(8) AnalysisKey { … }; /// A special type used to provide an address that identifies a set of related /// analyses. These sets are primarily used below to mark sets of analyses as /// preserved. /// /// For example, a transformation can indicate that it preserves the CFG of a /// function by preserving the appropriate AnalysisSetKey. An analysis that /// depends only on the CFG can then check if that AnalysisSetKey is preserved; /// if it is, the analysis knows that it itself is preserved. struct alignas(8) AnalysisSetKey { … }; /// This templated class represents "all analyses that operate over \<a /// particular IR unit\>" (e.g. a Function or a Module) in instances of /// PreservedAnalysis. /// /// This lets a transformation say e.g. "I preserved all function analyses". /// /// Note that you must provide an explicit instantiation declaration and /// definition for this template in order to get the correct behavior on /// Windows. Otherwise, the address of SetKey will not be stable. template <typename IRUnitT> class AllAnalysesOn { … }; template <typename IRUnitT> AnalysisSetKey AllAnalysesOn<IRUnitT>::SetKey; extern template class AllAnalysesOn<Module>; extern template class AllAnalysesOn<Function>; /// Represents analyses that only rely on functions' control flow. /// /// This can be used with \c PreservedAnalyses to mark the CFG as preserved and /// to query whether it has been preserved. /// /// The CFG of a function is defined as the set of basic blocks and the edges /// between them. Changing the set of basic blocks in a function is enough to /// mutate the CFG. Mutating the condition of a branch or argument of an /// invoked function does not mutate the CFG, but changing the successor labels /// of those instructions does. class CFGAnalyses { … }; /// A set of analyses that are preserved following a run of a transformation /// pass. /// /// Transformation passes build and return these objects to communicate which /// analyses are still valid after the transformation. For most passes this is /// fairly simple: if they don't change anything all analyses are preserved, /// otherwise only a short list of analyses that have been explicitly updated /// are preserved. /// /// This class also lets transformation passes mark abstract *sets* of analyses /// as preserved. A transformation that (say) does not alter the CFG can /// indicate such by marking a particular AnalysisSetKey as preserved, and /// then analyses can query whether that AnalysisSetKey is preserved. /// /// Finally, this class can represent an "abandoned" analysis, which is /// not preserved even if it would be covered by some abstract set of analyses. /// /// Given a `PreservedAnalyses` object, an analysis will typically want to /// figure out whether it is preserved. In the example below, MyAnalysisType is /// preserved if it's not abandoned, and (a) it's explicitly marked as /// preserved, (b), the set AllAnalysesOn<MyIRUnit> is preserved, or (c) both /// AnalysisSetA and AnalysisSetB are preserved. /// /// ``` /// auto PAC = PA.getChecker<MyAnalysisType>(); /// if (PAC.preserved() || PAC.preservedSet<AllAnalysesOn<MyIRUnit>>() || /// (PAC.preservedSet<AnalysisSetA>() && /// PAC.preservedSet<AnalysisSetB>())) { /// // The analysis has been successfully preserved ... /// } /// ``` class PreservedAnalyses { … }; } // namespace llvm #endif