1//===- Analysis.h --------------------------------------------*- C++ -*-===// 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 7//===----------------------------------------------------------------------===// 9/// Pass manager infrastructure for declaring and invalidating analyses. 10//===----------------------------------------------------------------------===// 12#ifndef LLVM_IR_ANALYSIS_H 13#define LLVM_IR_ANALYSIS_H 22/// A special type used by analysis passes to provide an address that 23/// identifies that particular analysis pass type. 25/// Analysis passes should have a static data member of this type and derive 26/// from the \c AnalysisInfoMixin to get a static ID method used to identify 27/// the analysis in the pass management infrastructure. 30/// A special type used to provide an address that identifies a set of related 31/// analyses. These sets are primarily used below to mark sets of analyses as 34/// For example, a transformation can indicate that it preserves the CFG of a 35/// function by preserving the appropriate AnalysisSetKey. An analysis that 36/// depends only on the CFG can then check if that AnalysisSetKey is preserved; 37/// if it is, the analysis knows that it itself is preserved. 40/// This templated class represents "all analyses that operate over <a 41/// particular IR unit>" (e.g. a Function or a Module) in instances of 44/// This lets a transformation say e.g. "I preserved all function analyses". 46/// Note that you must provide an explicit instantiation declaration and 47/// definition for this template in order to get the correct behavior on 48/// Windows. Otherwise, the address of SetKey will not be stable. 57template <
typename IRUnitT> AnalysisSetKey AllAnalysesOn<IRUnitT>::SetKey;
59externtemplateclassAllAnalysesOn<Module>;
60externtemplateclassAllAnalysesOn<Function>;
62/// Represents analyses that only rely on functions' control flow. 64/// This can be used with \c PreservedAnalyses to mark the CFG as preserved and 65/// to query whether it has been preserved. 67/// The CFG of a function is defined as the set of basic blocks and the edges 68/// between them. Changing the set of basic blocks in a function is enough to 69/// mutate the CFG. Mutating the condition of a branch or argument of an 70/// invoked function does not mutate the CFG, but changing the successor labels 71/// of those instructions does. 80/// A set of analyses that are preserved following a run of a transformation 83/// Transformation passes build and return these objects to communicate which 84/// analyses are still valid after the transformation. For most passes this is 85/// fairly simple: if they don't change anything all analyses are preserved, 86/// otherwise only a short list of analyses that have been explicitly updated 89/// This class also lets transformation passes mark abstract *sets* of analyses 90/// as preserved. A transformation that (say) does not alter the CFG can 91/// indicate such by marking a particular AnalysisSetKey as preserved, and 92/// then analyses can query whether that AnalysisSetKey is preserved. 94/// Finally, this class can represent an "abandoned" analysis, which is 95/// not preserved even if it would be covered by some abstract set of analyses. 97/// Given a `PreservedAnalyses` object, an analysis will typically want to 98/// figure out whether it is preserved. In the example below, MyAnalysisType is 99/// preserved if it's not abandoned, and (a) it's explicitly marked as 100/// preserved, (b), the set AllAnalysesOn<MyIRUnit> is preserved, or (c) both 101/// AnalysisSetA and AnalysisSetB are preserved. 104/// auto PAC = PA.getChecker<MyAnalysisType>(); 105/// if (PAC.preserved() || PAC.preservedSet<AllAnalysesOn<MyIRUnit>>() || 106/// (PAC.preservedSet<AnalysisSetA>() && 107/// PAC.preservedSet<AnalysisSetB>())) { 108/// // The analysis has been successfully preserved ... 113 /// Convenience factory function for the empty preserved set. 116 /// Construct a special preserved set that preserves all passes. 119 PA.PreservedIDs.
insert(&AllAnalysesKey);
123 /// Construct a preserved analyses object with a single preserved set. 130 /// Mark an analysis as preserved. 133 /// Given an analysis's ID, mark the analysis as preserved, adding it 136// Clear this ID from the explicit not-preserved set if present. 137 NotPreservedAnalysisIDs.erase(
ID);
139// If we're not already preserving all analyses (other than those in 140// NotPreservedAnalysisIDs). 141if (!areAllPreserved())
142 PreservedIDs.insert(
ID);
145 /// Mark an analysis set as preserved. 147 preserveSet(AnalysisSetT::ID());
150 /// Mark an analysis set as preserved using its ID. 152// If we're not already in the saturated 'all' state, add this set. 153if (!areAllPreserved())
154 PreservedIDs.insert(
ID);
157 /// Mark an analysis as abandoned. 159 /// An abandoned analysis is not preserved, even if it is nominally covered 160 /// by some other set or was previously explicitly marked as preserved. 162 /// Note that you can only abandon a specific analysis, not a *set* of 166 /// Mark an analysis as abandoned using its ID. 168 /// An abandoned analysis is not preserved, even if it is nominally covered 169 /// by some other set or was previously explicitly marked as preserved. 171 /// Note that you can only abandon a specific analysis, not a *set* of 174 PreservedIDs.erase(
ID);
175 NotPreservedAnalysisIDs.insert(
ID);
178 /// Intersect this set with another in place. 180 /// This is a mutating operation on this preserved set, removing all 181 /// preserved passes which are not also preserved in the argument. 185if (areAllPreserved()) {
189// The intersection requires the *union* of the explicitly not-preserved 190// IDs and the *intersection* of the preserved IDs. 191for (
auto *
ID : Arg.NotPreservedAnalysisIDs) {
192 PreservedIDs.erase(
ID);
193 NotPreservedAnalysisIDs.insert(
ID);
195 PreservedIDs.remove_if(
196 [&](
void *
ID) {
return !Arg.PreservedIDs.
contains(
ID); });
199 /// Intersect this set with a temporary other set in place. 201 /// This is a mutating operation on this preserved set, removing all 202 /// preserved passes which are not also preserved in the argument. 204if (Arg.areAllPreserved())
206if (areAllPreserved()) {
207 *
this = std::move(Arg);
210// The intersection requires the *union* of the explicitly not-preserved 211// IDs and the *intersection* of the preserved IDs. 212for (
auto *
ID : Arg.NotPreservedAnalysisIDs) {
213 PreservedIDs.erase(
ID);
214 NotPreservedAnalysisIDs.insert(
ID);
216 PreservedIDs.remove_if(
217 [&](
void *
ID) {
return !Arg.PreservedIDs.contains(
ID); });
220 /// A checker object that makes it easy to query for whether an analysis or 221 /// some set covering it is preserved. 227constbool IsAbandoned;
229 /// A PreservedAnalysisChecker is tied to a particular Analysis because 230 /// `preserved()` and `preservedSet()` both return false if the Analysis 233 : PA(PA),
ID(
ID), IsAbandoned(PA.NotPreservedAnalysisIDs.
count(
ID)) {}
236 /// Returns true if the checker's analysis was not abandoned and either 237 /// - the analysis is explicitly preserved or 238 /// - all analyses are preserved. 240return !IsAbandoned && (PA.PreservedIDs.
count(&AllAnalysesKey) ||
244 /// Return true if the checker's analysis was not abandoned, i.e. it was not 245 /// explicitly invalidated. Even if the analysis is not explicitly 246 /// preserved, if the analysis is known stateless, then it is preserved. 249 /// Returns true if the checker's analysis was not abandoned and either 250 /// - \p AnalysisSetT is explicitly preserved or 251 /// - all analyses are preserved. 254return !IsAbandoned && (PA.PreservedIDs.
count(&AllAnalysesKey) ||
255 PA.PreservedIDs.
count(SetID));
259 /// Build a checker for this `PreservedAnalyses` and the specified analysis 262 /// You can use the returned object to query whether an analysis was 263 /// preserved. See the example in the comment on `PreservedAnalysis`. 268 /// Build a checker for this `PreservedAnalyses` and the specified analysis 271 /// You can use the returned object to query whether an analysis was 272 /// preserved. See the example in the comment on `PreservedAnalysis`. 277 /// Test whether all analyses are preserved (and none are abandoned). 279 /// This is used primarily to optimize for the common case of a transformation 280 /// which makes no changes to the IR. 282return NotPreservedAnalysisIDs.empty() &&
283 PreservedIDs.count(&AllAnalysesKey);
286 /// Directly test whether a set of analyses is preserved. 288 /// This is only true when no analyses have been explicitly abandoned. 290return allAnalysesInSetPreserved(AnalysisSetT::ID());
293 /// Directly test whether a set of analyses is preserved. 295 /// This is only true when no analyses have been explicitly abandoned. 297return NotPreservedAnalysisIDs.empty() &&
298 (PreservedIDs.count(&AllAnalysesKey) || PreservedIDs.count(SetID));
302 /// A special key used to indicate all analyses. 305 /// The IDs of analyses and analysis sets that are preserved. 308 /// The IDs of explicitly not-preserved analyses. 310 /// If an analysis in this set is covered by a set in `PreservedIDs`, we 311 /// consider it not-preserved. That is, `NotPreservedAnalysisIDs` always 312 /// "wins" over analysis sets in `PreservedIDs`. 314 /// Also, a given ID should never occur both here and in `PreservedIDs`. Machine Check Debug Module
This file defines the SmallPtrSet class.
This templated class represents "all analyses that operate over <a particular IR unit>" (e....
static AnalysisSetKey * ID()
Represents analyses that only rely on functions' control flow.
static AnalysisSetKey * ID()
A checker object that makes it easy to query for whether an analysis or some set covering it is prese...
bool preserved()
Returns true if the checker's analysis was not abandoned and either.
bool preservedWhenStateless()
Return true if the checker's analysis was not abandoned, i.e.
bool preservedSet()
Returns true if the checker's analysis was not abandoned and either.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
void preserveSet(AnalysisSetKey *ID)
Mark an analysis set as preserved using its ID.
bool areAllPreserved() const
Test whether all analyses are preserved (and none are abandoned).
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
bool allAnalysesInSetPreserved() const
Directly test whether a set of analyses is preserved.
PreservedAnalysisChecker getChecker(AnalysisKey *ID) const
Build a checker for this PreservedAnalyses and the specified analysis ID.
void intersect(const PreservedAnalyses &Arg)
Intersect this set with another in place.
void intersect(PreservedAnalyses &&Arg)
Intersect this set with a temporary other set in place.
void abandon(AnalysisKey *ID)
Mark an analysis as abandoned using its ID.
bool allAnalysesInSetPreserved(AnalysisSetKey *SetID) const
Directly test whether a set of analyses is preserved.
void preserveSet()
Mark an analysis set as preserved.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
void preserve(AnalysisKey *ID)
Given an analysis's ID, mark the analysis as preserved, adding it to the set.
void abandon()
Mark an analysis as abandoned.
void preserve()
Mark an analysis as preserved.
static PreservedAnalyses allInSet()
Construct a preserved analyses object with a single preserved set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This is an optimization pass for GlobalISel generic memory operations.
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
A special type used by analysis passes to provide an address that identifies that particular analysis...
A special type used to provide an address that identifies a set of related analyses.