LLVM 20.0.0git
AliasSetTracker.cpp
Go to the documentation of this file.
1//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
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 implements the AliasSetTracker and AliasSet classes.
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/ADT/SetVector.h"
19#include "llvm/Config/llvm-config.h"
20#include "llvm/IR/Function.h"
24#include "llvm/IR/PassManager.h"
26#include "llvm/IR/Value.h"
27#include "llvm/Pass.h"
31#include "llvm/Support/Debug.h"
34
35using namespace llvm;
36
38 "alias-set-saturation-threshold", cl::Hidden, cl::init(250),
39 cl::desc("The maximum total number of memory locations alias "
40 "sets may contain before degradation"));
41
42/// mergeSetIn - Merge the specified alias set into this alias set.
44 BatchAAResults &BatchAA) {
45 assert(!AS.Forward && "Alias set is already forwarding!");
46 assert(!Forward && "This set is a forwarding set!!");
47
48 // Update the alias and access types of this set...
49 Access |= AS.Access;
50 Alias |= AS.Alias;
51
52 if (Alias == SetMustAlias) {
53 // Check that these two merged sets really are must aliases. If we cannot
54 // find a must-alias pair between them, this set becomes a may alias.
55 if (!any_of(MemoryLocs, [&](const MemoryLocation &MemLoc) {
56 return any_of(AS.MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
57 return BatchAA.isMustAlias(MemLoc, ASMemLoc);
58 });
59 }))
60 Alias = SetMayAlias;
61 }
62
63 // Merge the list of constituent memory locations...
64 if (MemoryLocs.empty()) {
65 std::swap(MemoryLocs, AS.MemoryLocs);
66 } else {
67 append_range(MemoryLocs, AS.MemoryLocs);
68 AS.MemoryLocs.clear();
69 }
70
71 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
72 if (UnknownInsts.empty()) { // Merge call sites...
73 if (ASHadUnknownInsts) {
74 std::swap(UnknownInsts, AS.UnknownInsts);
75 addRef();
76 }
77 } else if (ASHadUnknownInsts) {
78 llvm::append_range(UnknownInsts, AS.UnknownInsts);
79 AS.UnknownInsts.clear();
80 }
81
82 AS.Forward = this; // Forward across AS now...
83 addRef(); // AS is now pointing to us...
84
85 if (ASHadUnknownInsts)
86 AS.dropRef(AST);
87}
88
89void AliasSetTracker::removeAliasSet(AliasSet *AS) {
90 if (AliasSet *Fwd = AS->Forward) {
91 Fwd->dropRef(*this);
92 AS->Forward = nullptr;
93 } else // Update TotalAliasSetSize only if not forwarding.
94 TotalAliasSetSize -= AS->size();
95
96 AliasSets.erase(AS);
97 // If we've removed the saturated alias set, set saturated marker back to
98 // nullptr and ensure this tracker is empty.
99 if (AS == AliasAnyAS) {
100 AliasAnyAS = nullptr;
101 assert(AliasSets.empty() && "Tracker not empty");
102 }
103}
104
105void AliasSet::removeFromTracker(AliasSetTracker &AST) {
106 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
107 AST.removeAliasSet(this);
108}
109
110void AliasSet::addMemoryLocation(AliasSetTracker &AST,
111 const MemoryLocation &MemLoc,
112 bool KnownMustAlias) {
113 if (isMustAlias() && !KnownMustAlias) {
114 // If we cannot find a must-alias with any of the existing MemoryLocs, we
115 // must downgrade to may-alias.
116 if (!any_of(MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
117 return AST.getAliasAnalysis().isMustAlias(MemLoc, ASMemLoc);
118 }))
119 Alias = SetMayAlias;
120 }
121
122 // Add it to the end of the list...
123 MemoryLocs.push_back(MemLoc);
124
125 AST.TotalAliasSetSize++;
126}
127
128void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
129 if (UnknownInsts.empty())
130 addRef();
131 UnknownInsts.emplace_back(I);
132
133 // Guards are marked as modifying memory for control flow modelling purposes,
134 // but don't actually modify any specific memory location.
135 using namespace PatternMatch;
136 bool MayWriteMemory = I->mayWriteToMemory() && !isGuard(I) &&
137 !(I->use_empty() && match(I, m_Intrinsic<Intrinsic::invariant_start>()));
138 if (!MayWriteMemory) {
139 Alias = SetMayAlias;
140 Access |= RefAccess;
141 return;
142 }
143
144 // FIXME: This should use mod/ref information to make this not suck so bad
145 Alias = SetMayAlias;
146 Access = ModRefAccess;
147}
148
149/// aliasesMemoryLocation - If the specified memory location "may" (or must)
150/// alias one of the members in the set return the appropriate AliasResult.
151/// Otherwise return NoAlias.
152///
154 BatchAAResults &AA) const {
155 if (AliasAny)
157
158 // Check all of the memory locations in the set...
159 for (const auto &ASMemLoc : MemoryLocs) {
160 AliasResult AR = AA.alias(MemLoc, ASMemLoc);
161 if (AR != AliasResult::NoAlias)
162 return AR;
163 }
164
165 // Check the unknown instructions...
166 for (Instruction *Inst : UnknownInsts)
167 if (isModOrRefSet(AA.getModRefInfo(Inst, MemLoc)))
169
171}
172
174 BatchAAResults &AA) const {
175
176 if (AliasAny)
177 return ModRefInfo::ModRef;
178
179 if (!Inst->mayReadOrWriteMemory())
181
182 for (Instruction *UnknownInst : UnknownInsts) {
183 const auto *C1 = dyn_cast<CallBase>(UnknownInst);
184 const auto *C2 = dyn_cast<CallBase>(Inst);
185 if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
186 isModOrRefSet(AA.getModRefInfo(C2, C1))) {
187 // TODO: Could be more precise, but not really useful right now.
188 return ModRefInfo::ModRef;
189 }
190 }
191
193 for (const auto &ASMemLoc : MemoryLocs) {
194 MR |= AA.getModRefInfo(Inst, ASMemLoc);
195 if (isModAndRefSet(MR))
196 return MR;
197 }
198
199 return MR;
200}
201
204 for (const MemoryLocation &MemLoc : MemoryLocs)
205 Pointers.insert(MemLoc.Ptr);
206 return Pointers.takeVector();
207}
208
210 PointerMap.clear();
211 AliasSets.clear();
212}
213
214/// mergeAliasSetsForMemoryLocation - Given a memory location, merge all alias
215/// sets that may alias it. Return the unified set, or nullptr if no aliasing
216/// set was found. A known existing alias set for the pointer value of the
217/// memory location can be passed in (or nullptr if not available). MustAliasAll
218/// is updated to true/false if the memory location is found to MustAlias all
219/// the sets it merged.
220AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
221 const MemoryLocation &MemLoc, AliasSet *PtrAS, bool &MustAliasAll) {
222 AliasSet *FoundSet = nullptr;
223 MustAliasAll = true;
224 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
225 if (AS.Forward)
226 continue;
227
228 // An alias set that already contains a memory location with the same
229 // pointer value is directly assumed to MustAlias; we bypass the AA query in
230 // this case.
231 // Note: it is not guaranteed that AA would always provide the same result;
232 // a known exception are undef pointer values, where alias(undef, undef) is
233 // NoAlias, while we treat it as MustAlias.
234 if (&AS != PtrAS) {
235 AliasResult AR = AS.aliasesMemoryLocation(MemLoc, AA);
236 if (AR == AliasResult::NoAlias)
237 continue;
238
239 if (AR != AliasResult::MustAlias)
240 MustAliasAll = false;
241 }
242
243 if (!FoundSet) {
244 // If this is the first alias set ptr can go into, remember it.
245 FoundSet = &AS;
246 } else {
247 // Otherwise, we must merge the sets.
248 FoundSet->mergeSetIn(AS, *this, AA);
249 }
250 }
251
252 return FoundSet;
253}
254
255AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
256 AliasSet *FoundSet = nullptr;
257 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
258 if (AS.Forward || !isModOrRefSet(AS.aliasesUnknownInst(Inst, AA)))
259 continue;
260 if (!FoundSet) {
261 // If this is the first alias set ptr can go into, remember it.
262 FoundSet = &AS;
263 } else {
264 // Otherwise, we must merge the sets.
265 FoundSet->mergeSetIn(AS, *this, AA);
266 }
267 }
268 return FoundSet;
269}
270
272 // The alias sets are indexed with a map from the memory locations' pointer
273 // values. If the memory location is already registered, we can find it in the
274 // alias set associated with its pointer.
275 AliasSet *&MapEntry = PointerMap[MemLoc.Ptr];
276 if (MapEntry) {
277 collapseForwardingIn(MapEntry);
278 if (is_contained(MapEntry->MemoryLocs, MemLoc))
279 return *MapEntry;
280 }
281
282 AliasSet *AS;
283 bool MustAliasAll = false;
284 if (AliasAnyAS) {
285 // At this point, the AST is saturated, so we only have one active alias
286 // set. That means we already know which alias set we want to return, and
287 // just need to add the memory location to that set to keep the data
288 // structure consistent.
289 // This, of course, means that we will never need a merge here.
290 AS = AliasAnyAS;
291 } else if (AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
292 MemLoc, MapEntry, MustAliasAll)) {
293 // Add it to the alias set it aliases.
294 AS = AliasAS;
295 } else {
296 // Otherwise create a new alias set to hold the new memory location.
297 AliasSets.push_back(AS = new AliasSet());
298 MustAliasAll = true;
299 }
300
301 // Register memory location in selected alias set.
302 AS->addMemoryLocation(*this, MemLoc, MustAliasAll);
303 // Register selected alias set in pointer map (or ensure it is consistent with
304 // earlier map entry after taking into account new merging).
305 if (MapEntry) {
306 collapseForwardingIn(MapEntry);
307 assert(MapEntry == AS && "Memory locations with same pointer value cannot "
308 "be in different alias sets");
309 } else {
310 AS->addRef();
311 MapEntry = AS;
312 }
313 return *AS;
314}
315
317 addMemoryLocation(Loc, AliasSet::NoAccess);
318}
319
322 return addUnknown(LI);
323 addMemoryLocation(MemoryLocation::get(LI), AliasSet::RefAccess);
324}
325
327 if (isStrongerThanMonotonic(SI->getOrdering()))
328 return addUnknown(SI);
329 addMemoryLocation(MemoryLocation::get(SI), AliasSet::ModAccess);
330}
331
333 addMemoryLocation(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
334}
335
337 addMemoryLocation(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
338}
339
341 addMemoryLocation(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
342 addMemoryLocation(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
343}
344
346 if (isa<DbgInfoIntrinsic>(Inst))
347 return; // Ignore DbgInfo Intrinsics.
348
349 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
350 // These intrinsics will show up as affecting memory, but they are just
351 // markers.
352 switch (II->getIntrinsicID()) {
353 default:
354 break;
355 // FIXME: Add lifetime/invariant intrinsics (See: PR30807).
356 case Intrinsic::allow_runtime_check:
357 case Intrinsic::allow_ubsan_check:
358 case Intrinsic::assume:
359 case Intrinsic::experimental_noalias_scope_decl:
360 case Intrinsic::sideeffect:
361 case Intrinsic::pseudoprobe:
362 return;
363 }
364 }
365 if (!Inst->mayReadOrWriteMemory())
366 return; // doesn't alias anything
367
368 if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
369 AS->addUnknownInst(Inst, AA);
370 return;
371 }
372 AliasSets.push_back(new AliasSet());
373 AliasSets.back().addUnknownInst(Inst, AA);
374}
375
377 // Dispatch to one of the other add methods.
378 if (LoadInst *LI = dyn_cast<LoadInst>(I))
379 return add(LI);
380 if (StoreInst *SI = dyn_cast<StoreInst>(I))
381 return add(SI);
382 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
383 return add(VAAI);
384 if (AnyMemSetInst *MSI = dyn_cast<AnyMemSetInst>(I))
385 return add(MSI);
386 if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I))
387 return add(MTI);
388
389 // Handle all calls with known mod/ref sets genericall
390 if (auto *Call = dyn_cast<CallBase>(I))
391 if (Call->onlyAccessesArgMemory()) {
392 auto getAccessFromModRef = [](ModRefInfo MRI) {
393 if (isRefSet(MRI) && isModSet(MRI))
394 return AliasSet::ModRefAccess;
395 else if (isModSet(MRI))
396 return AliasSet::ModAccess;
397 else if (isRefSet(MRI))
398 return AliasSet::RefAccess;
399 else
400 return AliasSet::NoAccess;
401 };
402
403 ModRefInfo CallMask = AA.getMemoryEffects(Call).getModRef();
404
405 // Some intrinsics are marked as modifying memory for control flow
406 // modelling purposes, but don't actually modify any specific memory
407 // location.
408 using namespace PatternMatch;
409 if (Call->use_empty() &&
410 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
411 CallMask &= ModRefInfo::Ref;
412
413 for (auto IdxArgPair : enumerate(Call->args())) {
414 int ArgIdx = IdxArgPair.index();
415 const Value *Arg = IdxArgPair.value();
416 if (!Arg->getType()->isPointerTy())
417 continue;
418 MemoryLocation ArgLoc =
419 MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
420 ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
421 ArgMask &= CallMask;
422 if (!isNoModRef(ArgMask))
423 addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
424 }
425 return;
426 }
427
428 return addUnknown(I);
429}
430
432 for (auto &I : BB)
433 add(&I);
434}
435
437 assert(&AA == &AST.AA &&
438 "Merging AliasSetTracker objects with different Alias Analyses!");
439
440 // Loop over all of the alias sets in AST, adding the members contained
441 // therein into the current alias sets. This can cause alias sets to be
442 // merged together in the current AST.
443 for (const AliasSet &AS : AST) {
444 if (AS.Forward)
445 continue; // Ignore forwarding alias sets
446
447 // If there are any call sites in the alias set, add them to this AST.
448 for (Instruction *Inst : AS.UnknownInsts)
449 add(Inst);
450
451 // Loop over all of the memory locations in this alias set.
452 for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
453 addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
454 }
455}
456
457AliasSet &AliasSetTracker::mergeAllAliasSets() {
458 assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
459 "Full merge should happen once, when the saturation threshold is "
460 "reached");
461
462 // Collect all alias sets, so that we can drop references with impunity
463 // without worrying about iterator invalidation.
464 std::vector<AliasSet *> ASVector;
465 ASVector.reserve(SaturationThreshold);
466 for (AliasSet &AS : *this)
467 ASVector.push_back(&AS);
468
469 // Copy all instructions and memory locations into a new set, and forward all
470 // other sets to it.
471 AliasSets.push_back(new AliasSet());
472 AliasAnyAS = &AliasSets.back();
473 AliasAnyAS->Alias = AliasSet::SetMayAlias;
474 AliasAnyAS->Access = AliasSet::ModRefAccess;
475 AliasAnyAS->AliasAny = true;
476
477 for (auto *Cur : ASVector) {
478 // If Cur was already forwarding, just forward to the new AS instead.
479 AliasSet *FwdTo = Cur->Forward;
480 if (FwdTo) {
481 Cur->Forward = AliasAnyAS;
482 AliasAnyAS->addRef();
483 FwdTo->dropRef(*this);
484 continue;
485 }
486
487 // Otherwise, perform the actual merge.
488 AliasAnyAS->mergeSetIn(*Cur, *this, AA);
489 }
490
491 return *AliasAnyAS;
492}
493
494AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
495 AliasSet::AccessLattice E) {
496 AliasSet &AS = getAliasSetFor(Loc);
497 AS.Access |= E;
498
499 if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
500 // The AST is now saturated. From here on, we conservatively consider all
501 // elements to alias each-other.
502 return mergeAllAliasSets();
503 }
504
505 return AS;
506}
507
508//===----------------------------------------------------------------------===//
509// AliasSet/AliasSetTracker Printing Support
510//===----------------------------------------------------------------------===//
511
513 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";
514 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
515 switch (Access) {
516 case NoAccess: OS << "No access "; break;
517 case RefAccess: OS << "Ref "; break;
518 case ModAccess: OS << "Mod "; break;
519 case ModRefAccess: OS << "Mod/Ref "; break;
520 default: llvm_unreachable("Bad value for Access!");
521 }
522 if (Forward)
523 OS << " forwarding to " << (void*)Forward;
524
525 if (!MemoryLocs.empty()) {
526 ListSeparator LS;
527 OS << "Memory locations: ";
528 for (const MemoryLocation &MemLoc : MemoryLocs) {
529 OS << LS;
530 MemLoc.Ptr->printAsOperand(OS << "(");
531 if (MemLoc.Size == LocationSize::afterPointer())
532 OS << ", unknown after)";
533 else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
534 OS << ", unknown before-or-after)";
535 else
536 OS << ", " << MemLoc.Size << ")";
537 }
538 }
539 if (!UnknownInsts.empty()) {
540 ListSeparator LS;
541 OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
542 for (Instruction *I : UnknownInsts) {
543 OS << LS;
544 if (I->hasName())
545 I->printAsOperand(OS);
546 else
547 I->print(OS);
548 }
549 }
550 OS << "\n";
551}
552
554 OS << "Alias Set Tracker: " << AliasSets.size();
555 if (AliasAnyAS)
556 OS << " (Saturated)";
557 OS << " alias sets for " << PointerMap.size() << " pointer values.\n";
558 for (const AliasSet &AS : *this)
559 AS.print(OS);
560 OS << "\n";
561}
562
563#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
566#endif
567
568//===----------------------------------------------------------------------===//
569// AliasSetPrinter Pass
570//===----------------------------------------------------------------------===//
571
573
576 auto &AA = AM.getResult<AAManager>(F);
577 BatchAAResults BatchAA(AA);
578 AliasSetTracker Tracker(BatchAA);
579 OS << "Alias sets for function '" << F.getName() << "':\n";
580 for (Instruction &I : instructions(F))
581 Tracker.add(&I);
582 Tracker.print(OS);
583 return PreservedAnalyses::all();
584}
unsigned const MachineRegisterInfo * MRI
static cl::opt< unsigned > SaturationThreshold("alias-set-saturation-threshold", cl::Hidden, cl::init(250), cl::desc("The maximum total number of memory locations alias " "sets may contain before degradation"))
Expand Atomic instructions
Atomic ordering constants.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:622
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
This file contains some functions that are useful when dealing with strings.
A manager for alias analyses.
The possible results of an alias query.
Definition: AliasAnalysis.h:77
@ MayAlias
The two locations may or may not alias.
Definition: AliasAnalysis.h:98
@ NoAlias
The two locations do not alias at all.
Definition: AliasAnalysis.h:95
@ MustAlias
The two locations precisely alias each other.
BatchAAResults & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
AliasSet & getAliasSetFor(const MemoryLocation &MemLoc)
Return the alias set which contains the specified memory location.
void addUnknown(Instruction *I)
void print(raw_ostream &OS) const
void add(const MemoryLocation &Loc)
These methods are used to add different types of instructions to the alias sets.
unsigned size() const
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA)
Merge the specified alias set into this alias set.
void print(raw_ostream &OS) const
ModRefInfo aliasesUnknownInst(const Instruction *Inst, BatchAAResults &AA) const
bool isMustAlias() const
AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc, BatchAAResults &AA) const
If the specified memory location "may" (or must) alias one of the members in the set return the appro...
PointerVector getPointers() const
void dump() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
AliasSetsPrinterPass(raw_ostream &OS)
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
This class represents any memset intrinsic.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
ModRefInfo getArgModRefInfo(const CallBase *Call, unsigned ArgIdx)
MemoryEffects getMemoryEffects(const CallBase *Call)
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
unsigned size() const
Definition: DenseMap.h:99
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
Definition: Instruction.h:759
An instruction for reading from memory.
Definition: Instructions.h:176
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Definition: Instructions.h:220
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
static constexpr LocationSize afterPointer()
Any location after the base pointer (but still within the underlying object).
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition: ModRef.h:165
Representation for a specific memory location.
static MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static MemoryLocation getForSource(const MemTransferInst *MTI)
Return a location representing the source of a memory transfer.
LocationSize Size
The maximum size of the location, in address-units, or UnknownSize if the size is not known.
const Value * Ptr
The address of the start of the location.
static MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
Vector takeVector()
Clear the SetVector and return the underlying vector.
Definition: SetVector.h:87
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition: SetVector.h:162
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
An instruction for storing to memory.
Definition: Instructions.h:292
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:264
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Definition: Value.h:74
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:255
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:5144
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition: STLExtras.h:2448
bool isStrongerThanMonotonic(AtomicOrdering AO)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2115
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1746
bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
Definition: GuardUtils.cpp:18
bool isModSet(const ModRefInfo MRI)
Definition: ModRef.h:48
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
bool isModOrRefSet(const ModRefInfo MRI)
Definition: ModRef.h:42
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: ModRef.h:27
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
bool isModAndRefSet(const ModRefInfo MRI)
Definition: ModRef.h:45
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1903
bool isNoModRef(const ModRefInfo MRI)
Definition: ModRef.h:39
bool isRefSet(const ModRefInfo MRI)
Definition: ModRef.h:51
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:860