LLVM 22.0.0git
AssumptionCache.h
Go to the documentation of this file.
1//===- llvm/Analysis/AssumptionCache.h - Track @llvm.assume -----*- 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//
9// This file contains a pass that keeps track of @llvm.assume intrinsics in
10// the functions of a module (allowing assumptions within any function to be
11// found cheaply by other parts of the optimizer).
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_ANALYSIS_ASSUMPTIONCACHE_H
16#define LLVM_ANALYSIS_ASSUMPTIONCACHE_H
17
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/DenseMap.h"
22#include "llvm/IR/PassManager.h"
23#include "llvm/IR/ValueHandle.h"
24#include "llvm/Pass.h"
26#include <memory>
27
28namespace llvm {
29
30class AssumeInst;
31class Function;
32class raw_ostream;
33class TargetTransformInfo;
34class Value;
35
36/// A cache of \@llvm.assume calls within a function.
37///
38/// This cache provides fast lookup of assumptions within a function by caching
39/// them and amortizing the cost of scanning for them across all queries. Passes
40/// that create new assumptions are required to call registerAssumption() to
41/// register any new \@llvm.assume calls that they create. Deletions of
42/// \@llvm.assume calls do not require special handling.
44public:
45 /// Value of ResultElem::Index indicating that the argument to the call of the
46 /// llvm.assume.
47 enum : unsigned { ExprResultIdx = std::numeric_limits<unsigned>::max() };
48
49 struct ResultElem {
51
52 /// contains either ExprResultIdx or the index of the operand bundle
53 /// containing the knowledge.
54 unsigned Index;
55 operator Value *() const { return Assume; }
56 };
57
58private:
59 /// The function for which this cache is handling assumptions.
60 ///
61 /// We track this to lazily populate our assumptions.
62 Function &F;
63
65
66 /// Vector of weak value handles to calls of the \@llvm.assume
67 /// intrinsic.
68 SmallVector<ResultElem, 4> AssumeHandles;
69
70 class LLVM_ABI AffectedValueCallbackVH final : public CallbackVH {
72
73 void deleted() override;
74 void allUsesReplacedWith(Value *) override;
75
76 public:
77 using DMI = DenseMapInfo<Value *>;
78
79 AffectedValueCallbackVH(Value *V, AssumptionCache *AC = nullptr)
80 : CallbackVH(V), AC(AC) {}
81 };
82
83 friend AffectedValueCallbackVH;
84
85 /// A map of values about which an assumption might be providing
86 /// information to the relevant set of assumptions.
87 using AffectedValuesMap =
88 DenseMap<AffectedValueCallbackVH, SmallVector<ResultElem, 1>,
89 AffectedValueCallbackVH::DMI>;
90 AffectedValuesMap AffectedValues;
91
92 /// Get the vector of assumptions which affect a value from the cache.
93 SmallVector<ResultElem, 1> &getOrInsertAffectedValues(Value *V);
94
95 /// Move affected values in the cache for OV to be affected values for NV.
96 void transferAffectedValuesInCache(Value *OV, Value *NV);
97
98 /// Flag tracking whether we have scanned the function yet.
99 ///
100 /// We want to be as lazy about this as possible, and so we scan the function
101 /// at the last moment.
102 bool Scanned = false;
103
104 /// Scan the function for assumptions and add them to the cache.
105 LLVM_ABI void scanFunction();
106
107public:
108 /// Construct an AssumptionCache from a function by scanning all of
109 /// its instructions.
111 : F(F), TTI(TTI) {}
112
113 /// This cache is designed to be self-updating and so it should never be
114 /// invalidated.
117 return false;
118 }
119
120 /// Add an \@llvm.assume intrinsic to this function's cache.
121 ///
122 /// The call passed in must be an instruction within this function and must
123 /// not already be in the cache.
125
126 /// Remove an \@llvm.assume intrinsic from this function's cache if it has
127 /// been added to the cache earlier.
129
130 /// Update the cache of values being affected by this assumption (i.e.
131 /// the values about which this assumption provides information).
133
134 /// Clear the cache of \@llvm.assume intrinsics for a function.
135 ///
136 /// It will be re-scanned the next time it is requested.
137 void clear() {
138 AssumeHandles.clear();
139 AffectedValues.clear();
140 Scanned = false;
141 }
142
143 /// Access the list of assumption handles currently tracked for this
144 /// function.
145 ///
146 /// Note that these produce weak handles that may be null. The caller must
147 /// handle that case.
148 /// FIXME: We should replace this with pointee_iterator<filter_iterator<...>>
149 /// when we can write that to filter out the null values. Then caller code
150 /// will become simpler.
152 if (!Scanned)
153 scanFunction();
154 return AssumeHandles;
155 }
156
157 /// Access the list of assumptions which affect this value.
159 if (!Scanned)
160 scanFunction();
161
162 auto AVI = AffectedValues.find_as(const_cast<Value *>(V));
163 if (AVI == AffectedValues.end())
165
166 return AVI->second;
167 }
168};
169
170/// A function analysis which provides an \c AssumptionCache.
171///
172/// This analysis is intended for use with the new pass manager and will vend
173/// assumption caches for a given function.
174class AssumptionAnalysis : public AnalysisInfoMixin<AssumptionAnalysis> {
176
177 LLVM_ABI static AnalysisKey Key;
178
179public:
181
183};
184
185/// Printer pass for the \c AssumptionAnalysis results.
186class AssumptionPrinterPass : public PassInfoMixin<AssumptionPrinterPass> {
187 raw_ostream &OS;
188
189public:
191
193
194 static bool isRequired() { return true; }
195};
196
197/// An immutable pass that tracks lazily created \c AssumptionCache
198/// objects.
199///
200/// This is essentially a workaround for the legacy pass manager's weaknesses
201/// which associates each assumption cache with Function and clears it if the
202/// function is deleted. The nature of the AssumptionCache is that it is not
203/// invalidated by any changes to the function body and so this is sufficient
204/// to be conservatively correct.
206 /// A callback value handle applied to function objects, which we use to
207 /// delete our cache of intrinsics for a function when it is deleted.
208 class LLVM_ABI FunctionCallbackVH final : public CallbackVH {
210
211 void deleted() override;
212
213 public:
214 using DMI = DenseMapInfo<Value *>;
215
216 FunctionCallbackVH(Value *V, AssumptionCacheTracker *ACT = nullptr)
217 : CallbackVH(V), ACT(ACT) {}
218 };
219
220 friend FunctionCallbackVH;
221
222 using FunctionCallsMap =
225
226 FunctionCallsMap AssumptionCaches;
227
228public:
229 /// Get the cached assumptions for a function.
230 ///
231 /// If no assumptions are cached, this will scan the function. Otherwise, the
232 /// existing cache will be returned.
233 AssumptionCache &getAssumptionCache(Function &F);
234
235 /// Return the cached assumptions for a function if it has already been
236 /// scanned. Otherwise return nullptr.
237 AssumptionCache *lookupAssumptionCache(Function &F);
238
241
242 void releaseMemory() override {
243 verifyAnalysis();
244 AssumptionCaches.shrink_and_clear();
245 }
246
247 void verifyAnalysis() const override;
248
249 bool doFinalization(Module &) override {
250 verifyAnalysis();
251 return false;
252 }
253
254 static char ID; // Pass identification, replacement for typeid
255};
256
257template<> struct simplify_type<AssumptionCache::ResultElem> {
258 using SimpleType = Value *;
259
261 return Val;
262 }
263};
264template<> struct simplify_type<const AssumptionCache::ResultElem> {
265 using SimpleType = /*const*/ Value *;
266
268 return Val;
269 }
270};
271
272} // end namespace llvm
273
274#endif // LLVM_ANALYSIS_ASSUMPTIONCACHE_H
aarch64 promote const
#define LLVM_ABI
Definition: Compiler.h:213
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
raw_pwrite_stream & OS
This file defines the SmallVector class.
API to communicate dependencies between analyses during invalidation.
Definition: PassManager.h:294
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
LLVM_ABI AssumptionCache run(Function &F, FunctionAnalysisManager &)
An immutable pass that tracks lazily created AssumptionCache objects.
bool doFinalization(Module &) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
void releaseMemory() override
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
A cache of @llvm.assume calls within a function.
LLVM_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
void clear()
Clear the cache of @llvm.assume intrinsics for a function.
bool invalidate(Function &, const PreservedAnalyses &, FunctionAnalysisManager::Invalidator &)
This cache is designed to be self-updating and so it should never be invalidated.
LLVM_ABI void updateAffectedValues(AssumeInst *CI)
Update the cache of values being affected by this assumption (i.e.
MutableArrayRef< ResultElem > assumptions()
Access the list of assumption handles currently tracked for this function.
LLVM_ABI void unregisterAssumption(AssumeInst *CI)
Remove an @llvm.assume intrinsic from this function's cache if it has been added to the cache earlier...
AssumptionCache(Function &F, TargetTransformInfo *TTI=nullptr)
Construct an AssumptionCache from a function by scanning all of its instructions.
MutableArrayRef< ResultElem > assumptionsFor(const Value *V)
Access the list of assumptions which affect this value.
Printer pass for the AssumptionAnalysis results.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
AssumptionPrinterPass(raw_ostream &OS)
Value handle with callbacks on RAUW and destruction.
Definition: ValueHandle.h:384
void shrink_and_clear()
Definition: DenseMap.h:828
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:285
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:303
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
LLVM Value Representation.
Definition: Value.h:75
A nullable Value handle that is nullable.
Definition: ValueHandle.h:145
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
A CRTP mix-in that provides informational APIs needed for analysis passes.
Definition: PassManager.h:93
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:29
unsigned Index
contains either ExprResultIdx or the index of the operand bundle containing the knowledge.
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:54
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:70
static SimpleType getSimplifiedValue(AssumptionCache::ResultElem &Val)
static SimpleType getSimplifiedValue(const AssumptionCache::ResultElem &Val)
Define a template that can be specialized by smart pointers to reflect the fact that they are automat...
Definition: Casting.h:34