LLVM 19.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"
28#include "llvm/Pass.h"
32#include "llvm/Support/Debug.h"
35
36using namespace llvm;
37
39 "alias-set-saturation-threshold", cl::Hidden, cl::init(250),
40 cl::desc("The maximum total number of memory locations alias "
41 "sets may contain before degradation"));
42
43/// mergeSetIn - Merge the specified alias set into this alias set.
45 BatchAAResults &BatchAA) {
46 assert(!AS.Forward && "Alias set is already forwarding!");
47 assert(!Forward && "This set is a forwarding set!!");
48
49 // Update the alias and access types of this set...
50 Access |= AS.Access;
51 Alias |= AS.Alias;
52
53 if (Alias == SetMustAlias) {
54 // Check that these two merged sets really are must aliases. If we cannot
55 // find a must-alias pair between them, this set becomes a may alias.
56 if (!any_of(MemoryLocs, [&](const MemoryLocation &MemLoc) {
57 return any_of(AS.MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
58 return BatchAA.isMustAlias(MemLoc, ASMemLoc);
59 });
60 }))
61 Alias = SetMayAlias;
62 }
63
64 // Merge the list of constituent memory locations...
65 if (MemoryLocs.empty()) {
66 std::swap(MemoryLocs, AS.MemoryLocs);
67 } else {
68 append_range(MemoryLocs, AS.MemoryLocs);
69 AS.MemoryLocs.clear();
70 }
71
72 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
73 if (UnknownInsts.empty()) { // Merge call sites...
74 if (ASHadUnknownInsts) {
75 std::swap(UnknownInsts, AS.UnknownInsts);
76 addRef();
77 }
78 } else if (ASHadUnknownInsts) {
79 llvm::append_range(UnknownInsts, AS.UnknownInsts);
80 AS.UnknownInsts.clear();
81 }
82
83 AS.Forward = this; // Forward across AS now...
84 addRef(); // AS is now pointing to us...
85
86 if (ASHadUnknownInsts)
87 AS.dropRef(AST);
88}
89
90void AliasSetTracker::removeAliasSet(AliasSet *AS) {
91 if (AliasSet *Fwd = AS->Forward) {
92 Fwd->dropRef(*this);
93 AS->Forward = nullptr;
94 } else // Update TotalAliasSetSize only if not forwarding.
95 TotalAliasSetSize -= AS->size();
96
97 AliasSets.erase(AS);
98 // If we've removed the saturated alias set, set saturated marker back to
99 // nullptr and ensure this tracker is empty.
100 if (AS == AliasAnyAS) {
101 AliasAnyAS = nullptr;
102 assert(AliasSets.empty() && "Tracker not empty");
103 }
104}
105
106void AliasSet::removeFromTracker(AliasSetTracker &AST) {
107 assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
108 AST.removeAliasSet(this);
109}
110
111void AliasSet::addMemoryLocation(AliasSetTracker &AST,
112 const MemoryLocation &MemLoc,
113 bool KnownMustAlias) {
114 if (isMustAlias() && !KnownMustAlias) {
115 // If we cannot find a must-alias with any of the existing MemoryLocs, we
116 // must downgrade to may-alias.
117 if (!any_of(MemoryLocs, [&](const MemoryLocation &ASMemLoc) {
118 return AST.getAliasAnalysis().isMustAlias(MemLoc, ASMemLoc);
119 }))
120 Alias = SetMayAlias;
121 }
122
123 // Add it to the end of the list...
124 MemoryLocs.push_back(MemLoc);
125
126 AST.TotalAliasSetSize++;
127}
128
129void AliasSet::addUnknownInst(Instruction *I, BatchAAResults &AA) {
130 if (UnknownInsts.empty())
131 addRef();
132 UnknownInsts.emplace_back(I);
133
134 // Guards are marked as modifying memory for control flow modelling purposes,
135 // but don't actually modify any specific memory location.
136 using namespace PatternMatch;
137 bool MayWriteMemory = I->mayWriteToMemory() && !isGuard(I) &&
138 !(I->use_empty() && match(I, m_Intrinsic<Intrinsic::invariant_start>()));
139 if (!MayWriteMemory) {
140 Alias = SetMayAlias;
141 Access |= RefAccess;
142 return;
143 }
144
145 // FIXME: This should use mod/ref information to make this not suck so bad
146 Alias = SetMayAlias;
147 Access = ModRefAccess;
148}
149
150/// aliasesMemoryLocation - If the specified memory location "may" (or must)
151/// alias one of the members in the set return the appropriate AliasResult.
152/// Otherwise return NoAlias.
153///
155 BatchAAResults &AA) const {
156 if (AliasAny)
158
159 // Check all of the memory locations in the set...
160 for (const auto &ASMemLoc : MemoryLocs) {
161 AliasResult AR = AA.alias(MemLoc, ASMemLoc);
162 if (AR != AliasResult::NoAlias)
163 return AR;
164 }
165
166 // Check the unknown instructions...
167 for (Instruction *Inst : UnknownInsts)
168 if (isModOrRefSet(AA.getModRefInfo(Inst, MemLoc)))
170
172}
173
175 BatchAAResults &AA) const {
176
177 if (AliasAny)
178 return ModRefInfo::ModRef;
179
180 if (!Inst->mayReadOrWriteMemory())
182
183 for (Instruction *UnknownInst : UnknownInsts) {
184 const auto *C1 = dyn_cast<CallBase>(UnknownInst);
185 const auto *C2 = dyn_cast<CallBase>(Inst);
186 if (!C1 || !C2 || isModOrRefSet(AA.getModRefInfo(C1, C2)) ||
187 isModOrRefSet(AA.getModRefInfo(C2, C1))) {
188 // TODO: Could be more precise, but not really useful right now.
189 return ModRefInfo::ModRef;
190 }
191 }
192
194 for (const auto &ASMemLoc : MemoryLocs) {
195 MR |= AA.getModRefInfo(Inst, ASMemLoc);
196 if (isModAndRefSet(MR))
197 return MR;
198 }
199
200 return MR;
201}
202
205 for (const MemoryLocation &MemLoc : MemoryLocs)
206 Pointers.insert(MemLoc.Ptr);
207 return Pointers.takeVector();
208}
209
211 PointerMap.clear();
212 AliasSets.clear();
213}
214
215/// mergeAliasSetsForMemoryLocation - Given a memory location, merge all alias
216/// sets that may alias it. Return the unified set, or nullptr if no aliasing
217/// set was found. A known existing alias set for the pointer value of the
218/// memory location can be passed in (or nullptr if not available). MustAliasAll
219/// is updated to true/false if the memory location is found to MustAlias all
220/// the sets it merged.
221AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
222 const MemoryLocation &MemLoc, AliasSet *PtrAS, bool &MustAliasAll) {
223 AliasSet *FoundSet = nullptr;
224 MustAliasAll = true;
225 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
226 if (AS.Forward)
227 continue;
228
229 // An alias set that already contains a memory location with the same
230 // pointer value is directly assumed to MustAlias; we bypass the AA query in
231 // this case.
232 // Note: it is not guaranteed that AA would always provide the same result;
233 // a known exception are undef pointer values, where alias(undef, undef) is
234 // NoAlias, while we treat it as MustAlias.
235 if (&AS != PtrAS) {
236 AliasResult AR = AS.aliasesMemoryLocation(MemLoc, AA);
237 if (AR == AliasResult::NoAlias)
238 continue;
239
240 if (AR != AliasResult::MustAlias)
241 MustAliasAll = false;
242 }
243
244 if (!FoundSet) {
245 // If this is the first alias set ptr can go into, remember it.
246 FoundSet = &AS;
247 } else {
248 // Otherwise, we must merge the sets.
249 FoundSet->mergeSetIn(AS, *this, AA);
250 }
251 }
252
253 return FoundSet;
254}
255
256AliasSet *AliasSetTracker::findAliasSetForUnknownInst(Instruction *Inst) {
257 AliasSet *FoundSet = nullptr;
258 for (AliasSet &AS : llvm::make_early_inc_range(*this)) {
259 if (AS.Forward || !isModOrRefSet(AS.aliasesUnknownInst(Inst, AA)))
260 continue;
261 if (!FoundSet) {
262 // If this is the first alias set ptr can go into, remember it.
263 FoundSet = &AS;
264 } else {
265 // Otherwise, we must merge the sets.
266 FoundSet->mergeSetIn(AS, *this, AA);
267 }
268 }
269 return FoundSet;
270}
271
273 // The alias sets are indexed with a map from the memory locations' pointer
274 // values. If the memory location is already registered, we can find it in the
275 // alias set associated with its pointer.
276 AliasSet *&MapEntry = PointerMap[MemLoc.Ptr];
277 if (MapEntry) {
278 collapseForwardingIn(MapEntry);
279 if (is_contained(MapEntry->MemoryLocs, MemLoc))
280 return *MapEntry;
281 }
282
283 AliasSet *AS;
284 bool MustAliasAll = false;
285 if (AliasAnyAS) {
286 // At this point, the AST is saturated, so we only have one active alias
287 // set. That means we already know which alias set we want to return, and
288 // just need to add the memory location to that set to keep the data
289 // structure consistent.
290 // This, of course, means that we will never need a merge here.
291 AS = AliasAnyAS;
292 } else if (AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
293 MemLoc, MapEntry, MustAliasAll)) {
294 // Add it to the alias set it aliases.
295 AS = AliasAS;
296 } else {
297 // Otherwise create a new alias set to hold the new memory location.
298 AliasSets.push_back(AS = new AliasSet());
299 MustAliasAll = true;
300 }
301
302 // Register memory location in selected alias set.
303 AS->addMemoryLocation(*this, MemLoc, MustAliasAll);
304 // Register selected alias set in pointer map (or ensure it is consistent with
305 // earlier map entry after taking into account new merging).
306 if (MapEntry) {
307 collapseForwardingIn(MapEntry);
308 assert(MapEntry == AS && "Memory locations with same pointer value cannot "
309 "be in different alias sets");
310 } else {
311 AS->addRef();
312 MapEntry = AS;
313 }
314 return *AS;
315}
316
318 addMemoryLocation(Loc, AliasSet::NoAccess);
319}
320
323 return addUnknown(LI);
324 addMemoryLocation(MemoryLocation::get(LI), AliasSet::RefAccess);
325}
326
328 if (isStrongerThanMonotonic(SI->getOrdering()))
329 return addUnknown(SI);
330 addMemoryLocation(MemoryLocation::get(SI), AliasSet::ModAccess);
331}
332
334 addMemoryLocation(MemoryLocation::get(VAAI), AliasSet::ModRefAccess);
335}
336
338 addMemoryLocation(MemoryLocation::getForDest(MSI), AliasSet::ModAccess);
339}
340
342 addMemoryLocation(MemoryLocation::getForDest(MTI), AliasSet::ModAccess);
343 addMemoryLocation(MemoryLocation::getForSource(MTI), AliasSet::RefAccess);
344}
345
347 if (isa<DbgInfoIntrinsic>(Inst))
348 return; // Ignore DbgInfo Intrinsics.
349
350 if (auto *II = dyn_cast<IntrinsicInst>(Inst)) {
351 // These intrinsics will show up as affecting memory, but they are just
352 // markers.
353 switch (II->getIntrinsicID()) {
354 default:
355 break;
356 // FIXME: Add lifetime/invariant intrinsics (See: PR30807).
357 case Intrinsic::assume:
358 case Intrinsic::experimental_noalias_scope_decl:
359 case Intrinsic::sideeffect:
360 case Intrinsic::pseudoprobe:
361 return;
362 }
363 }
364 if (!Inst->mayReadOrWriteMemory())
365 return; // doesn't alias anything
366
367 if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
368 AS->addUnknownInst(Inst, AA);
369 return;
370 }
371 AliasSets.push_back(new AliasSet());
372 AliasSets.back().addUnknownInst(Inst, AA);
373}
374
376 // Dispatch to one of the other add methods.
377 if (LoadInst *LI = dyn_cast<LoadInst>(I))
378 return add(LI);
379 if (StoreInst *SI = dyn_cast<StoreInst>(I))
380 return add(SI);
381 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
382 return add(VAAI);
383 if (AnyMemSetInst *MSI = dyn_cast<AnyMemSetInst>(I))
384 return add(MSI);
385 if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I))
386 return add(MTI);
387
388 // Handle all calls with known mod/ref sets genericall
389 if (auto *Call = dyn_cast<CallBase>(I))
390 if (Call->onlyAccessesArgMemory()) {
391 auto getAccessFromModRef = [](ModRefInfo MRI) {
392 if (isRefSet(MRI) && isModSet(MRI))
393 return AliasSet::ModRefAccess;
394 else if (isModSet(MRI))
395 return AliasSet::ModAccess;
396 else if (isRefSet(MRI))
397 return AliasSet::RefAccess;
398 else
399 return AliasSet::NoAccess;
400 };
401
402 ModRefInfo CallMask = AA.getMemoryEffects(Call).getModRef();
403
404 // Some intrinsics are marked as modifying memory for control flow
405 // modelling purposes, but don't actually modify any specific memory
406 // location.
407 using namespace PatternMatch;
408 if (Call->use_empty() &&
409 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
410 CallMask &= ModRefInfo::Ref;
411
412 for (auto IdxArgPair : enumerate(Call->args())) {
413 int ArgIdx = IdxArgPair.index();
414 const Value *Arg = IdxArgPair.value();
415 if (!Arg->getType()->isPointerTy())
416 continue;
417 MemoryLocation ArgLoc =
418 MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
419 ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
420 ArgMask &= CallMask;
421 if (!isNoModRef(ArgMask))
422 addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
423 }
424 return;
425 }
426
427 return addUnknown(I);
428}
429
431 for (auto &I : BB)
432 add(&I);
433}
434
436 assert(&AA == &AST.AA &&
437 "Merging AliasSetTracker objects with different Alias Analyses!");
438
439 // Loop over all of the alias sets in AST, adding the members contained
440 // therein into the current alias sets. This can cause alias sets to be
441 // merged together in the current AST.
442 for (const AliasSet &AS : AST) {
443 if (AS.Forward)
444 continue; // Ignore forwarding alias sets
445
446 // If there are any call sites in the alias set, add them to this AST.
447 for (Instruction *Inst : AS.UnknownInsts)
448 add(Inst);
449
450 // Loop over all of the memory locations in this alias set.
451 for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
452 addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
453 }
454}
455
456AliasSet &AliasSetTracker::mergeAllAliasSets() {
457 assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
458 "Full merge should happen once, when the saturation threshold is "
459 "reached");
460
461 // Collect all alias sets, so that we can drop references with impunity
462 // without worrying about iterator invalidation.
463 std::vector<AliasSet *> ASVector;
464 ASVector.reserve(SaturationThreshold);
465 for (AliasSet &AS : *this)
466 ASVector.push_back(&AS);
467
468 // Copy all instructions and memory locations into a new set, and forward all
469 // other sets to it.
470 AliasSets.push_back(new AliasSet());
471 AliasAnyAS = &AliasSets.back();
472 AliasAnyAS->Alias = AliasSet::SetMayAlias;
473 AliasAnyAS->Access = AliasSet::ModRefAccess;
474 AliasAnyAS->AliasAny = true;
475
476 for (auto *Cur : ASVector) {
477 // If Cur was already forwarding, just forward to the new AS instead.
478 AliasSet *FwdTo = Cur->Forward;
479 if (FwdTo) {
480 Cur->Forward = AliasAnyAS;
481 AliasAnyAS->addRef();
482 FwdTo->dropRef(*this);
483 continue;
484 }
485
486 // Otherwise, perform the actual merge.
487 AliasAnyAS->mergeSetIn(*Cur, *this, AA);
488 }
489
490 return *AliasAnyAS;
491}
492
493AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
494 AliasSet::AccessLattice E) {
495 AliasSet &AS = getAliasSetFor(Loc);
496 AS.Access |= E;
497
498 if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
499 // The AST is now saturated. From here on, we conservatively consider all
500 // elements to alias each-other.
501 return mergeAllAliasSets();
502 }
503
504 return AS;
505}
506
507//===----------------------------------------------------------------------===//
508// AliasSet/AliasSetTracker Printing Support
509//===----------------------------------------------------------------------===//
510
512 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";
513 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
514 switch (Access) {
515 case NoAccess: OS << "No access "; break;
516 case RefAccess: OS << "Ref "; break;
517 case ModAccess: OS << "Mod "; break;
518 case ModRefAccess: OS << "Mod/Ref "; break;
519 default: llvm_unreachable("Bad value for Access!");
520 }
521 if (Forward)
522 OS << " forwarding to " << (void*)Forward;
523
524 if (!MemoryLocs.empty()) {
525 ListSeparator LS;
526 OS << "Memory locations: ";
527 for (const MemoryLocation &MemLoc : MemoryLocs) {
528 OS << LS;
529 MemLoc.Ptr->printAsOperand(OS << "(");
530 if (MemLoc.Size == LocationSize::afterPointer())
531 OS << ", unknown after)";
532 else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
533 OS << ", unknown before-or-after)";
534 else
535 OS << ", " << MemLoc.Size << ")";
536 }
537 }
538 if (!UnknownInsts.empty()) {
539 ListSeparator LS;
540 OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
541 for (Instruction *I : UnknownInsts) {
542 OS << LS;
543 if (I->hasName())
544 I->printAsOperand(OS);
545 else
546 I->print(OS);
547 }
548 }
549 OS << "\n";
550}
551
553 OS << "Alias Set Tracker: " << AliasSets.size();
554 if (AliasAnyAS)
555 OS << " (Saturated)";
556 OS << " alias sets for " << PointerMap.size() << " pointer values.\n";
557 for (const AliasSet &AS : *this)
558 AS.print(OS);
559 OS << "\n";
560}
561
562#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
565#endif
566
567//===----------------------------------------------------------------------===//
568// AliasSetPrinter Pass
569//===----------------------------------------------------------------------===//
570
572
575 auto &AA = AM.getResult<AAManager>(F);
576 BatchAAResults BatchAA(AA);
577 AliasSetTracker Tracker(BatchAA);
578 OS << "Alias sets for function '" << F.getName() << "':\n";
579 for (Instruction &I : instructions(F))
580 Tracker.add(&I);
581 Tracker.print(OS);
582 return PreservedAnalyses::all();
583}
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition: Compiler.h:529
#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.
This header defines various interfaces for pass management in LLVM.
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:81
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
Definition: AliasAnalysis.h:99
@ 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.
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:348
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:500
This class represents any memset intrinsic.
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
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:731
An instruction for reading from memory.
Definition: Instructions.h:184
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Definition: Instructions.h:245
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:109
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:115
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:1209
An instruction for storing to memory.
Definition: Instructions.h:317
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:255
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:5043
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:450
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 are tuples (A,...
Definition: STLExtras.h:2415
bool isStrongerThanMonotonic(AtomicOrdering AO)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2082
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:665
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:1738
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:1888
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