LLVM: lib/Analysis/AssumptionCache.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
34#include
35
36using namespace llvm;
38
41 cl::desc("Enable verification of assumption cache"),
43
45AssumptionCache::getOrInsertAffectedValues(Value *V) {
46
47
48 auto AVI = AffectedValues.find_as(V);
49 if (AVI != AffectedValues.end())
50 return AVI->second;
51
52 return AffectedValues[AffectedValueCallbackVH(V, this)];
53}
54
57 auto AddAffectedVal = [&](Value *V) {
59 InsertAffected(V);
60 };
61
62 if (Bundle.getTagName() == "separate_storage") {
63 assert(Bundle.Inputs.size() == 2 && "separate_storage must have two args");
69}
70
71static void
74
75
76
77 auto InsertAffected = [&Affected](Value *V) {
79 };
80
81 auto AddAffectedVal = [&Affected](Value *V, unsigned Idx) {
84 }
85 };
86
90 [&](Value *V) { Affected.push_back({V, Idx}); });
91
92 Value *Cond = CI->getArgOperand(0);
94
95 if (TTI) {
97 unsigned AS;
98 std::tie(Ptr, AS) = TTI->getPredicatedAddrSpace(Cond);
99 if (Ptr)
102 }
103}
104
108
109 for (auto &AV : Affected) {
110 auto &AVV = getOrInsertAffectedValues(AV.Assume);
112 return Elem.Assume == CI && Elem.Index == AV.Index;
113 }))
114 AVV.push_back({CI, AV.Index});
115 }
116}
117
121
122 for (auto &AV : Affected) {
123 auto AVI = AffectedValues.find_as(AV.Assume);
124 if (AVI == AffectedValues.end())
125 continue;
126 bool Found = false;
127 bool HasNonnull = false;
128 for (ResultElem &Elem : AVI->second) {
129 if (Elem.Assume == CI) {
130 Found = true;
131 Elem.Assume = nullptr;
132 }
133 HasNonnull |= !!Elem.Assume;
134 if (HasNonnull && Found)
135 break;
136 }
137 assert(Found && "already unregistered or incorrect cache state");
138 if (!HasNonnull)
139 AffectedValues.erase(AVI);
140 }
141
143}
144
146 AC->AffectedValues.erase(getValPtr());
147
148}
149
150void AssumptionCache::transferAffectedValuesInCache(Value *OV, Value *NV) {
151 auto &NAVV = getOrInsertAffectedValues(NV);
152 auto AVI = AffectedValues.find(OV);
153 if (AVI == AffectedValues.end())
154 return;
155
156 for (auto &A : AVI->second)
158 NAVV.push_back(A);
159 AffectedValues.erase(OV);
160}
161
162void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(Value *NV) {
164 return;
165
166
167
168 AC->transferAffectedValuesInCache(getValPtr(), NV);
169
170
171
172}
173
174void AssumptionCache::scanFunction() {
175 assert(!Scanned && "Tried to scan the function twice!");
176 assert(AssumeHandles.empty() && "Already have assumes when scanning!");
177
178
179
180 for (BasicBlock &B : F)
183 AssumeHandles.push_back(&I);
184
185
186 Scanned = true;
187
188
189 for (auto &A : AssumeHandles)
191}
192
194
195
196 if (!Scanned)
197 return;
198
199 AssumeHandles.push_back(CI);
200
201#ifndef NDEBUG
203 "Cannot register @llvm.assume call not in a basic block");
205 "Cannot register @llvm.assume call not in this function");
206
207
208
209
211 for (auto &VH : AssumeHandles) {
212 if (!VH)
213 continue;
214
216 "Cached assumption not inside this function!");
218 "Cached something other than a call to @llvm.assume!");
220 "Cache contains multiple copies of a call!");
221 }
222#endif
223
225}
226
232
234
238
239 OS << "Cached assumptions for function: " << F.getName() << "\n";
241 if (VH)
242 OS << " " << *cast(VH)->getArgOperand(0) << "\n";
243
245}
246
248 auto I = ACT->AssumptionCaches.find_as(cast(getValPtr()));
249 if (I != ACT->AssumptionCaches.end())
250 ACT->AssumptionCaches.erase(I);
251
252}
253
255
256
257
258
259 auto I = AssumptionCaches.find_as(&F);
260 if (I != AssumptionCaches.end())
261 return *I->second;
262
264 auto *TTI = TTIWP ? &TTIWP->getTTI(F) : nullptr;
265
266
267
268 auto IP = AssumptionCaches.insert(std::make_pair(
269 FunctionCallbackVH(&F, this), std::make_unique(F, TTI)));
270 assert(IP.second && "Scanning function already in the map?");
271 return *IP.first->second;
272}
273
275 auto I = AssumptionCaches.find_as(&F);
276 if (I != AssumptionCaches.end())
277 return I->second.get();
278 return nullptr;
279}
280
282
283
284
285
287 return;
288
290 for (const auto &I : AssumptionCaches) {
291 for (auto &VH : I.second->assumptions())
292 if (VH)
294
300 }
301}
302
304
306
308
310 "Assumption Cache Tracker", false, true)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static void findAffectedValues(CallBase *CI, TargetTransformInfo *TTI, SmallVectorImpl< AssumptionCache::ResultElem > &Affected)
Definition AssumptionCache.cpp:72
static cl::opt< bool > VerifyAssumptionCache("verify-assumption-cache", cl::Hidden, cl::desc("Enable verification of assumption cache"), cl::init(false))
static const Function * getParent(const Value *V)
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This header defines various interfaces for pass management in LLVM.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This pass exposes codegen information to IR-level passes.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
LLVM_ABI AssumptionCache run(Function &F, FunctionAnalysisManager &)
Definition AssumptionCache.cpp:227
An immutable pass that tracks lazily created AssumptionCache objects.
~AssumptionCacheTracker() override
AssumptionCache * lookupAssumptionCache(Function &F)
Return the cached assumptions for a function if it has already been scanned.
Definition AssumptionCache.cpp:274
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
Definition AssumptionCache.cpp:281
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
Definition AssumptionCache.cpp:254
AssumptionCacheTracker()
Definition AssumptionCache.cpp:303
A cache of @llvm.assume calls within a function.
static void findValuesAffectedByOperandBundle(OperandBundleUse Bundle, function_ref< void(Value *)> InsertAffected)
Determine which values are affected by this assume operand bundle.
Definition AssumptionCache.cpp:55
LLVM_ABI void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
Definition AssumptionCache.cpp:193
LLVM_ABI void updateAffectedValues(AssumeInst *CI)
Update the cache of values being affected by this assumption (i.e.
Definition AssumptionCache.cpp:105
MutableArrayRef< WeakVH > 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...
Definition AssumptionCache.cpp:118
AssumptionCache(Function &F, TargetTransformInfo *TTI=nullptr)
Construct an AssumptionCache from a function by scanning all of its instructions.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition AssumptionCache.cpp:235
LLVM Basic Block Representation.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
OperandBundleUse getOperandBundleAt(unsigned Index) const
Return the operand bundle at a specific index.
unsigned getNumOperandBundles() const
Return the number of operand bundles associated with this User.
virtual void deleted()
Callback for Value destruction.
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable() - Subclasses use this function to get analysis information tha...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Value * getValPtr() const
LLVM Value Representation.
LLVM_ABI const Value * stripInBoundsOffsets(function_ref< void(const Value *)> Func=[](const Value *) {}) const
Strip off pointer casts and inbounds GEPs.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
bool match(Val *V, const Pattern &P)
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_IntrinsicIntrinsic::fabs(m_Value(X))
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
constexpr StringRef IgnoreBundleTag
Tag in operand bundle indicating that this bundle should be ignored.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
LLVM_ABI void findValuesAffectedByCondition(Value *Cond, bool IsAssume, function_ref< void(Value *)> InsertAffected)
Call InsertAffected on all Values whose known bits / value may be affected by the condition Cond.
A special type used by analysis passes to provide an address that identifies that particular analysis...
unsigned Index
contains either ExprResultIdx or the index of the operand bundle containing the knowledge.
A lightweight accessor for an operand bundle meant to be passed around by value.
StringRef getTagName() const
Return the tag of this operand bundle as a string.