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"
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::allow_runtime_check:
358 case Intrinsic::allow_ubsan_check:
359 case Intrinsic::assume:
360 case Intrinsic::experimental_noalias_scope_decl:
361 case Intrinsic::sideeffect:
362 case Intrinsic::pseudoprobe:
363 return;
364 }
365 }
366 if (!Inst->mayReadOrWriteMemory())
367 return; // doesn't alias anything
368
369 if (AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
370 AS->addUnknownInst(Inst, AA);
371 return;
372 }
373 AliasSets.push_back(new AliasSet());
374 AliasSets.back().addUnknownInst(Inst, AA);
375}
376
378 // Dispatch to one of the other add methods.
379 if (LoadInst *LI = dyn_cast<LoadInst>(I))
380 return add(LI);
381 if (StoreInst *SI = dyn_cast<StoreInst>(I))
382 return add(SI);
383 if (VAArgInst *VAAI = dyn_cast<VAArgInst>(I))
384 return add(VAAI);
385 if (AnyMemSetInst *MSI = dyn_cast<AnyMemSetInst>(I))
386 return add(MSI);
387 if (AnyMemTransferInst *MTI = dyn_cast<AnyMemTransferInst>(I))
388 return add(MTI);
389
390 // Handle all calls with known mod/ref sets genericall
391 if (auto *Call = dyn_cast<CallBase>(I))
392 if (Call->onlyAccessesArgMemory()) {
393 auto getAccessFromModRef = [](ModRefInfo MRI) {
394 if (isRefSet(MRI) && isModSet(MRI))
395 return AliasSet::ModRefAccess;
396 else if (isModSet(MRI))
397 return AliasSet::ModAccess;
398 else if (isRefSet(MRI))
399 return AliasSet::RefAccess;
400 else
401 return AliasSet::NoAccess;
402 };
403
404 ModRefInfo CallMask = AA.getMemoryEffects(Call).getModRef();
405
406 // Some intrinsics are marked as modifying memory for control flow
407 // modelling purposes, but don't actually modify any specific memory
408 // location.
409 using namespace PatternMatch;
410 if (Call->use_empty() &&
411 match(Call, m_Intrinsic<Intrinsic::invariant_start>()))
412 CallMask &= ModRefInfo::Ref;
413
414 for (auto IdxArgPair : enumerate(Call->args())) {
415 int ArgIdx = IdxArgPair.index();
416 const Value *Arg = IdxArgPair.value();
417 if (!Arg->getType()->isPointerTy())
418 continue;
419 MemoryLocation ArgLoc =
420 MemoryLocation::getForArgument(Call, ArgIdx, nullptr);
421 ModRefInfo ArgMask = AA.getArgModRefInfo(Call, ArgIdx);
422 ArgMask &= CallMask;
423 if (!isNoModRef(ArgMask))
424 addMemoryLocation(ArgLoc, getAccessFromModRef(ArgMask));
425 }
426 return;
427 }
428
429 return addUnknown(I);
430}
431
433 for (auto &I : BB)
434 add(&I);
435}
436
438 assert(&AA == &AST.AA &&
439 "Merging AliasSetTracker objects with different Alias Analyses!");
440
441 // Loop over all of the alias sets in AST, adding the members contained
442 // therein into the current alias sets. This can cause alias sets to be
443 // merged together in the current AST.
444 for (const AliasSet &AS : AST) {
445 if (AS.Forward)
446 continue; // Ignore forwarding alias sets
447
448 // If there are any call sites in the alias set, add them to this AST.
449 for (Instruction *Inst : AS.UnknownInsts)
450 add(Inst);
451
452 // Loop over all of the memory locations in this alias set.
453 for (const MemoryLocation &ASMemLoc : AS.MemoryLocs)
454 addMemoryLocation(ASMemLoc, (AliasSet::AccessLattice)AS.Access);
455 }
456}
457
458AliasSet &AliasSetTracker::mergeAllAliasSets() {
459 assert(!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold) &&
460 "Full merge should happen once, when the saturation threshold is "
461 "reached");
462
463 // Collect all alias sets, so that we can drop references with impunity
464 // without worrying about iterator invalidation.
465 std::vector<AliasSet *> ASVector;
466 ASVector.reserve(SaturationThreshold);
467 for (AliasSet &AS : *this)
468 ASVector.push_back(&AS);
469
470 // Copy all instructions and memory locations into a new set, and forward all
471 // other sets to it.
472 AliasSets.push_back(new AliasSet());
473 AliasAnyAS = &AliasSets.back();
474 AliasAnyAS->Alias = AliasSet::SetMayAlias;
475 AliasAnyAS->Access = AliasSet::ModRefAccess;
476 AliasAnyAS->AliasAny = true;
477
478 for (auto *Cur : ASVector) {
479 // If Cur was already forwarding, just forward to the new AS instead.
480 AliasSet *FwdTo = Cur->Forward;
481 if (FwdTo) {
482 Cur->Forward = AliasAnyAS;
483 AliasAnyAS->addRef();
484 FwdTo->dropRef(*this);
485 continue;
486 }
487
488 // Otherwise, perform the actual merge.
489 AliasAnyAS->mergeSetIn(*Cur, *this, AA);
490 }
491
492 return *AliasAnyAS;
493}
494
495AliasSet &AliasSetTracker::addMemoryLocation(MemoryLocation Loc,
496 AliasSet::AccessLattice E) {
497 AliasSet &AS = getAliasSetFor(Loc);
498 AS.Access |= E;
499
500 if (!AliasAnyAS && (TotalAliasSetSize > SaturationThreshold)) {
501 // The AST is now saturated. From here on, we conservatively consider all
502 // elements to alias each-other.
503 return mergeAllAliasSets();
504 }
505
506 return AS;
507}
508
509//===----------------------------------------------------------------------===//
510// AliasSet/AliasSetTracker Printing Support
511//===----------------------------------------------------------------------===//
512
514 OS << " AliasSet[" << (const void*)this << ", " << RefCount << "] ";
515 OS << (Alias == SetMustAlias ? "must" : "may") << " alias, ";
516 switch (Access) {
517 case NoAccess: OS << "No access "; break;
518 case RefAccess: OS << "Ref "; break;
519 case ModAccess: OS << "Mod "; break;
520 case ModRefAccess: OS << "Mod/Ref "; break;
521 default: llvm_unreachable("Bad value for Access!");
522 }
523 if (Forward)
524 OS << " forwarding to " << (void*)Forward;
525
526 if (!MemoryLocs.empty()) {
527 ListSeparator LS;
528 OS << "Memory locations: ";
529 for (const MemoryLocation &MemLoc : MemoryLocs) {
530 OS << LS;
531 MemLoc.Ptr->printAsOperand(OS << "(");
532 if (MemLoc.Size == LocationSize::afterPointer())
533 OS << ", unknown after)";
534 else if (MemLoc.Size == LocationSize::beforeOrAfterPointer())
535 OS << ", unknown before-or-after)";
536 else
537 OS << ", " << MemLoc.Size << ")";
538 }
539 }
540 if (!UnknownInsts.empty()) {
541 ListSeparator LS;
542 OS << "\n " << UnknownInsts.size() << " Unknown instructions: ";
543 for (Instruction *I : UnknownInsts) {
544 OS << LS;
545 if (I->hasName())
546 I->printAsOperand(OS);
547 else
548 I->print(OS);
549 }
550 }
551 OS << "\n";
552}
553
555 OS << "Alias Set Tracker: " << AliasSets.size();
556 if (AliasAnyAS)
557 OS << " (Saturated)";
558 OS << " alias sets for " << PointerMap.size() << " pointer values.\n";
559 for (const AliasSet &AS : *this)
560 AS.print(OS);
561 OS << "\n";
562}
563
564#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
567#endif
568
569//===----------------------------------------------------------------------===//
570// AliasSetPrinter Pass
571//===----------------------------------------------------------------------===//
572
574
577 auto &AA = AM.getResult<AAManager>(F);
578 BatchAAResults BatchAA(AA);
579 AliasSetTracker Tracker(BatchAA);
580 OS << "Alias sets for function '" << F.getName() << "':\n";
581 for (Instruction &I : instructions(F))
582 Tracker.add(&I);
583 Tracker.print(OS);
584 return PreservedAnalyses::all();
585}
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:533
#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
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: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:405
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:754
An instruction for reading from memory.
Definition: Instructions.h:174
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
Definition: Instructions.h:218
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:1209
An instruction for storing to memory.
Definition: Instructions.h:290
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:251
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:5106
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:2431
bool isStrongerThanMonotonic(AtomicOrdering AO)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2098
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:656
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:1729
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:1886
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