19#include "llvm/Config/llvm-config.h"
39 cl::desc(
"The maximum total number of memory locations alias "
40 "sets may contain before degradation"));
45 assert(!AS.Forward &&
"Alias set is already forwarding!");
46 assert(!Forward &&
"This set is a forwarding set!!");
52 if (Alias == SetMustAlias) {
57 return BatchAA.isMustAlias(MemLoc, ASMemLoc);
64 if (MemoryLocs.empty()) {
68 AS.MemoryLocs.clear();
71 bool ASHadUnknownInsts = !AS.UnknownInsts.empty();
72 if (UnknownInsts.empty()) {
73 if (ASHadUnknownInsts) {
77 }
else if (ASHadUnknownInsts) {
79 AS.UnknownInsts.clear();
85 if (ASHadUnknownInsts)
89void AliasSetTracker::removeAliasSet(
AliasSet *AS) {
92 AS->Forward =
nullptr;
94 TotalAliasSetSize -= AS->
size();
99 if (AS == AliasAnyAS) {
100 AliasAnyAS =
nullptr;
101 assert(AliasSets.empty() &&
"Tracker not empty");
106 assert(RefCount == 0 &&
"Cannot remove non-dead alias set from tracker!");
107 AST.removeAliasSet(
this);
112 bool KnownMustAlias) {
116 if (!
any_of(MemoryLocs, [&](
const MemoryLocation &ASMemLoc) {
123 MemoryLocs.push_back(MemLoc);
125 AST.TotalAliasSetSize++;
129 if (UnknownInsts.empty())
131 UnknownInsts.emplace_back(
I);
135 using namespace PatternMatch;
136 bool MayWriteMemory =
I->mayWriteToMemory() && !
isGuard(
I) &&
138 if (!MayWriteMemory) {
159 for (
const auto &ASMemLoc : MemoryLocs) {
193 for (
const auto &ASMemLoc : MemoryLocs) {
194 MR |=
AA.getModRefInfo(Inst, ASMemLoc);
220AliasSet *AliasSetTracker::mergeAliasSetsForMemoryLocation(
240 MustAliasAll =
false;
277 collapseForwardingIn(MapEntry);
283 bool MustAliasAll =
false;
291 }
else if (
AliasSet *AliasAS = mergeAliasSetsForMemoryLocation(
292 MemLoc, MapEntry, MustAliasAll)) {
297 AliasSets.push_back(AS =
new AliasSet());
302 AS->addMemoryLocation(*
this, MemLoc, MustAliasAll);
306 collapseForwardingIn(MapEntry);
307 assert(MapEntry == AS &&
"Memory locations with same pointer value cannot "
308 "be in different alias sets");
334 "Can't handle release stores here");
356 switch (
II->getIntrinsicID()) {
360 case Intrinsic::allow_runtime_check:
361 case Intrinsic::allow_ubsan_check:
362 case Intrinsic::assume:
363 case Intrinsic::experimental_noalias_scope_decl:
364 case Intrinsic::sideeffect:
365 case Intrinsic::pseudoprobe:
372 if (
AliasSet *AS = findAliasSetForUnknownInst(Inst)) {
373 AS->addUnknownInst(Inst, AA);
376 AliasSets.push_back(
new AliasSet());
377 AliasSets.back().addUnknownInst(Inst, AA);
395 if (
Call->onlyAccessesArgMemory()) {
402 if (
Call->use_empty() &&
407 int ArgIdx = IdxArgPair.index();
408 const Value *Arg = IdxArgPair.value();
416 addMemoryLocation(ArgLoc, ArgMask);
431 "Merging AliasSetTracker objects with different Alias Analyses!");
446 addMemoryLocation(ASMemLoc, AS.Access);
450AliasSet &AliasSetTracker::mergeAllAliasSets() {
452 "Full merge should happen once, when the saturation threshold is "
457 std::vector<AliasSet *> ASVector;
460 ASVector.push_back(&AS);
464 AliasSets.push_back(
new AliasSet());
465 AliasAnyAS = &AliasSets.back();
466 AliasAnyAS->Alias = AliasSet::SetMayAlias;
468 AliasAnyAS->AliasAny =
true;
470 for (
auto *Cur : ASVector) {
474 Cur->Forward = AliasAnyAS;
475 AliasAnyAS->addRef();
476 FwdTo->dropRef(*
this);
495 return mergeAllAliasSets();
506 OS <<
" AliasSet[" << (
const void*)
this <<
", " << RefCount <<
"] ";
507 OS << (Alias == SetMustAlias ?
"must" :
"may") <<
" alias, ";
523 OS <<
" forwarding to " << (
void*)Forward;
525 if (!MemoryLocs.empty()) {
527 OS <<
"Memory locations: ";
532 OS <<
", unknown after)";
534 OS <<
", unknown before-or-after)";
536 OS <<
", " << MemLoc.
Size <<
")";
539 if (!UnknownInsts.empty()) {
541 OS <<
"\n " << UnknownInsts.size() <<
" Unknown instructions: ";
545 I->printAsOperand(OS);
554 OS <<
"Alias Set Tracker: " << AliasSets.size();
556 OS <<
" (Saturated)";
557 OS <<
" alias sets for " << PointerMap.size() <<
" pointer values.\n";
563#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
579 OS <<
"Alias sets for function '" <<
F.getName() <<
"':\n";
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
This header defines various interfaces for pass management in LLVM.
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
This file implements a set that has insertion order iteration characteristics.
A manager for alias analyses.
The possible results of an alias query.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ MustAlias
The two locations precisely alias each other.
LLVM_ABI void dump() const
BatchAAResults & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
LLVM_ABI AliasSet & getAliasSetFor(const MemoryLocation &MemLoc)
Return the alias set which contains the specified memory location.
LLVM_ABI void addUnknown(Instruction *I)
AliasSetTracker(BatchAAResults &AA)
Create an empty collection of AliasSets, and use the specified alias analysis object to disambiguate ...
LLVM_ABI void addWithoutAATags(StoreInst *SI)
LLVM_ABI void print(raw_ostream &OS) const
LLVM_ABI void add(const MemoryLocation &Loc)
These methods are used to add different types of instructions to the alias sets.
LLVM_ABI void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA)
Merge the specified alias set into this alias set.
LLVM_ABI void print(raw_ostream &OS) const
AliasSet(const AliasSet &)=delete
LLVM_ABI ModRefInfo aliasesUnknownInst(const Instruction *Inst, BatchAAResults &AA) const
LLVM_ABI 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...
friend class AliasSetTracker
LLVM_ABI PointerVector getPointers() const
LLVM_ABI void dump() const
SmallVector< const Value *, 8 > PointerVector
Retrieve the pointer values for the memory locations in this alias set.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI AliasSetsPrinterPass(raw_ostream &OS)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents any memset intrinsic.
LLVM Basic Block Representation.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
bool mayReadOrWriteMemory() const
Return true if this instruction may read or write memory.
A helper class to return the specified delimiter string after the first invocation of operator String...
An instruction for reading from memory.
AtomicOrdering getOrdering() const
Returns the ordering constraint of this load instruction.
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).
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static LLVM_ABI 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 LLVM_ABI MemoryLocation getForDest(const MemIntrinsic *MI)
Return a location representing the destination of a memory set or transfer.
static LLVM_ABI 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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Vector takeVector()
Clear the SetVector and return the underlying vector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
An instruction for storing to memory.
bool isPointerTy() const
True if this is an instance of PointerType.
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI 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.
This class implements an extremely fast bulk output stream that can only output to a stream.
Abstract Attribute helper functions.
bool match(Val *V, const Pattern &P)
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool isStrongerThanMonotonic(AtomicOrdering AO)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isGuard(const User *U)
Returns true iff U has semantics of a guard expressed in a form of call of llvm.experimental....
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isModOrRefSet(const ModRefInfo MRI)
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ ModRef
The access may reference and may modify the value stored in memory.
@ Mod
The access may modify the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
bool isModAndRefSet(const ModRefInfo MRI)
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.
bool isNoModRef(const ModRefInfo MRI)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.