LLVM 17.0.0git
ScopedNoAliasAA.cpp
Go to the documentation of this file.
1//===- ScopedNoAliasAA.cpp - Scoped No-Alias Alias Analysis ---------------===//
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 defines the ScopedNoAlias alias-analysis pass, which implements
10// metadata-based scoped no-alias support.
11//
12// Alias-analysis scopes are defined by an id (which can be a string or some
13// other metadata node), a domain node, and an optional descriptive string.
14// A domain is defined by an id (which can be a string or some other metadata
15// node), and an optional descriptive string.
16//
17// !dom0 = metadata !{ metadata !"domain of foo()" }
18// !scope1 = metadata !{ metadata !scope1, metadata !dom0, metadata !"scope 1" }
19// !scope2 = metadata !{ metadata !scope2, metadata !dom0, metadata !"scope 2" }
20//
21// Loads and stores can be tagged with an alias-analysis scope, and also, with
22// a noalias tag for a specific scope:
23//
24// ... = load %ptr1, !alias.scope !{ !scope1 }
25// ... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 }
26//
27// When evaluating an aliasing query, if one of the instructions is associated
28// has a set of noalias scopes in some domain that is a superset of the alias
29// scopes in that domain of some other instruction, then the two memory
30// accesses are assumed not to alias.
31//
32//===----------------------------------------------------------------------===//
33
38#include "llvm/IR/InstrTypes.h"
39#include "llvm/IR/LLVMContext.h"
40#include "llvm/IR/Metadata.h"
42#include "llvm/Pass.h"
45
46using namespace llvm;
47
48// A handy option for disabling scoped no-alias functionality. The same effect
49// can also be achieved by stripping the associated metadata tags from IR, but
50// this option is sometimes more convenient.
51static cl::opt<bool> EnableScopedNoAlias("enable-scoped-noalias",
52 cl::init(true), cl::Hidden);
53
55 const MemoryLocation &LocB,
56 AAQueryInfo &AAQI,
57 const Instruction *) {
59 return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
60
61 // Get the attached MDNodes.
62 const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
63
64 const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias;
65
66 if (!mayAliasInScopes(AScopes, BNoAlias))
68
69 if (!mayAliasInScopes(BScopes, ANoAlias))
71
72 // If they may alias, chain to the next AliasAnalysis.
73 return AAResultBase::alias(LocA, LocB, AAQI, nullptr);
74}
75
77 const MemoryLocation &Loc,
78 AAQueryInfo &AAQI) {
80 return AAResultBase::getModRefInfo(Call, Loc, AAQI);
81
82 if (!mayAliasInScopes(Loc.AATags.Scope,
83 Call->getMetadata(LLVMContext::MD_noalias)))
85
86 if (!mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope),
87 Loc.AATags.NoAlias))
89
90 return AAResultBase::getModRefInfo(Call, Loc, AAQI);
91}
92
94 const CallBase *Call2,
95 AAQueryInfo &AAQI) {
97 return AAResultBase::getModRefInfo(Call1, Call2, AAQI);
98
99 if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope),
100 Call2->getMetadata(LLVMContext::MD_noalias)))
102
103 if (!mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope),
104 Call1->getMetadata(LLVMContext::MD_noalias)))
106
107 return AAResultBase::getModRefInfo(Call1, Call2, AAQI);
108}
109
110static void collectMDInDomain(const MDNode *List, const MDNode *Domain,
112 for (const MDOperand &MDOp : List->operands())
113 if (const MDNode *MD = dyn_cast<MDNode>(MDOp))
114 if (AliasScopeNode(MD).getDomain() == Domain)
115 Nodes.insert(MD);
116}
117
118bool ScopedNoAliasAAResult::mayAliasInScopes(const MDNode *Scopes,
119 const MDNode *NoAlias) const {
120 if (!Scopes || !NoAlias)
121 return true;
122
123 // Collect the set of scope domains relevant to the noalias scopes.
125 for (const MDOperand &MDOp : NoAlias->operands())
126 if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
127 if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
128 Domains.insert(Domain);
129
130 // We alias unless, for some domain, the set of noalias scopes in that domain
131 // is a superset of the set of alias scopes in that domain.
132 for (const MDNode *Domain : Domains) {
134 collectMDInDomain(Scopes, Domain, ScopeNodes);
135 if (ScopeNodes.empty())
136 continue;
137
139 collectMDInDomain(NoAlias, Domain, NANodes);
140
141 // To not alias, all of the nodes in ScopeNodes must be in NANodes.
142 if (llvm::set_is_subset(ScopeNodes, NANodes))
143 return false;
144 }
145
146 return true;
147}
148
149AnalysisKey ScopedNoAliasAA::Key;
150
153 return ScopedNoAliasAAResult();
154}
155
157
159 "Scoped NoAlias Alias Analysis", false, true)
160
162 return new ScopedNoAliasAAWrapperPass();
163}
164
167}
168
170 Result.reset(new ScopedNoAliasAAResult());
171 return false;
172}
173
175 Result.reset();
176 return false;
177}
178
180 AU.setPreservesAll();
181}
static Domain getDomain(const ConstantRange &CR)
#define F(x, y, z)
Definition: MD5.cpp:55
This file provides utility analysis objects describing memory locations.
This file contains the declarations for metadata subclasses.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
static void collectMDInDomain(const MDNode *List, const MDNode *Domain, SmallPtrSetImpl< const MDNode * > &Nodes)
static cl::opt< bool > EnableScopedNoAlias("enable-scoped-noalias", cl::init(true), cl::Hidden)
This is the interface for a metadata-based scoped no-alias analysis.
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallPtrSet class.
This class stores info we want to provide to or retain within an alias query.
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI, const Instruction *I)
The possible results of an alias query.
Definition: AliasAnalysis.h:83
@ NoAlias
The two locations do not alias at all.
This is a simple wrapper around an MDNode which provides a higher-level interface by hiding the detai...
Definition: Metadata.h:1423
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1186
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition: Pass.h:279
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:275
Metadata node.
Definition: Metadata.h:943
ArrayRef< MDOperand > operands() const
Definition: Metadata.h:1289
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:772
Representation for a specific memory location.
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A simple AA result which uses scoped-noalias metadata to answer queries.
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB, AAQueryInfo &AAQI, const Instruction *CtxI)
Legacy wrapper pass to provide the ScopedNoAliasAAResult object.
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ScopedNoAliasAAResult run(Function &F, FunctionAnalysisManager &AM)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:344
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:365
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry &)
ImmutablePass * createScopedNoAliasAAWrapperPass()
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: ModRef.h:27
@ NoModRef
The access neither references nor modifies the value stored in memory.
MDNode * Scope
The tag for alias scope specification (used with noalias).
Definition: Metadata.h:674
MDNode * NoAlias
The tag specifying the noalias scope.
Definition: Metadata.h:677
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:69