LLVM 24.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), a flag saying whether its scopes are disjoint, and an optional
16// descriptive string.
17//
18// !dom0 = metadata !{ metadata !"domain of foo()", i1 false }
19// !scope1 = metadata !{ metadata !scope1, metadata !dom0, metadata !"scope 1" }
20// !scope2 = metadata !{ metadata !scope2, metadata !dom0, metadata !"scope 2" }
21//
22// Loads and stores can be tagged with an alias-analysis scope, and also, with
23// a noalias tag for a specific scope:
24//
25// ... = load %ptr1, !alias.scope !{ !scope1 }
26// ... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 }
27//
28// When evaluating an aliasing query, if one of the instructions
29// has a set of noalias scopes in some domain that is a superset of the alias
30// scopes in that domain of some other instruction, then the two memory
31// accesses are assumed not to alias.
32//
33// If a domain is declared as having disjoint scopes, two memory accesses are
34// assumed not to alias if the they both have entries for that domain in their
35// `alias.scope` list and their `alias.scope` lists have no scopes in common for
36// that domain. Equivalently, an instruction with a set of scopes from a
37// disjoint-scope domain in its `alias.scope` list implicitly has all other
38// scopes in that domain in its `noalias` set. For example,
39//
40// !dom1 = metadata !{ metadata !dom1, i1 true, metadata !"disjoint domain" }
41// !scope3 = metadata !{ metadata !scope3, metadata !dom1 }
42// !scope4 = metadata !{ metadata !scope4, metadata !dom1 }
43//
44// ... = load %ptr3, !alias.scope !{ !scope3 } ; doesn't alias the load below
45// ... = load %ptr4, !alias.scope !{ !scope4 }
46//
47//===----------------------------------------------------------------------===//
48
53#include "llvm/IR/InstrTypes.h"
55#include "llvm/IR/LLVMContext.h"
56#include "llvm/IR/Metadata.h"
58#include "llvm/Pass.h"
61
62using namespace llvm;
63
64// A handy option for disabling scoped no-alias functionality. The same effect
65// can also be achieved by stripping the associated metadata tags from IR, but
66// this option is sometimes more convenient.
67static cl::opt<bool> EnableScopedNoAlias("enable-scoped-noalias",
68 cl::init(true), cl::Hidden);
69
71 const MemoryLocation &LocB) {
74
75 // Get the attached MDNodes.
76 const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
77
78 const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias;
79
80 if (!mayAliasInScopes(AScopes, BNoAlias))
82
83 if (!mayAliasInScopes(BScopes, ANoAlias))
85
86 if (!mayAliasInDisjointDomains(AScopes, BScopes))
88
90}
91
93 const MemoryLocation &LocB,
94 AAQueryInfo &, const Instruction *) {
95 return alias(LocA, LocB);
96}
97
99 const MemoryLocation &Loc,
100 AAQueryInfo &AAQI) {
102 return ModRefInfo::ModRef;
103
104 if (!mayAliasInScopes(Loc.AATags.Scope,
105 Call->getMetadata(LLVMContext::MD_noalias)))
107
108 if (!mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope),
109 Loc.AATags.NoAlias))
111
113 Loc.AATags.Scope, Call->getMetadata(LLVMContext::MD_alias_scope)))
115
116 return ModRefInfo::ModRef;
117}
118
120 const MemoryLocation &Loc,
121 AAQueryInfo &AAQI) {
123 return ModRefInfo::ModRef;
124
125 if (!mayAliasInScopes(Loc.AATags.Scope,
126 F->getMetadata(LLVMContext::MD_noalias)))
128
129 if (!mayAliasInScopes(F->getMetadata(LLVMContext::MD_alias_scope),
130 Loc.AATags.NoAlias))
132
133 if (!mayAliasInDisjointDomains(Loc.AATags.Scope,
134 F->getMetadata(LLVMContext::MD_alias_scope)))
136
137 return ModRefInfo::ModRef;
138}
139
141 const CallBase *Call2,
142 AAQueryInfo &AAQI) {
144 return ModRefInfo::ModRef;
145
146 if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope),
147 Call2->getMetadata(LLVMContext::MD_noalias)))
149
150 if (!mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope),
151 Call1->getMetadata(LLVMContext::MD_noalias)))
153
155 Call1->getMetadata(LLVMContext::MD_alias_scope),
156 Call2->getMetadata(LLVMContext::MD_alias_scope)))
158
159 return ModRefInfo::ModRef;
160}
161
162static void collectMDInDomain(const MDNode *List, const MDNode *Domain,
164 for (const MDOperand &MDOp : List->operands())
165 if (const MDNode *MD = dyn_cast<MDNode>(MDOp))
166 if (AliasScopeNode(MD).getDomain() == Domain)
167 Nodes.insert(MD);
168}
169
170/// Collect the set of scoped domains relevant to the noalias scopes.
172 const MDNode *NoAlias, SmallPtrSetImpl<const MDNode *> &Domains,
173 bool DisjointOnly) {
174 if (!NoAlias)
175 return;
176 assert(Domains.empty() && "Domains should be empty");
177 for (const MDOperand &MDOp : NoAlias->operands())
178 if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
179 if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
180 if (!DisjointOnly || AliasScopeDomainNode(Domain).hasDisjointScopes())
181 Domains.insert(Domain);
182}
183
185 const MDNode *NoAlias) {
186 if (!Scopes || !NoAlias)
187 return true;
188
189 // Collect the set of scope domains relevant to the noalias scopes.
191 collectScopedDomains(NoAlias, Domains);
192
193 // We alias unless, for some domain, the set of noalias scopes in that domain
194 // is a superset of the set of alias scopes in that domain.
195 for (const MDNode *Domain : Domains) {
197 collectMDInDomain(Scopes, Domain, ScopeNodes);
198 if (ScopeNodes.empty())
199 continue;
200
202 collectMDInDomain(NoAlias, Domain, NANodes);
203
204 // To not alias, all of the nodes in ScopeNodes must be in NANodes.
205 if (llvm::set_is_subset(ScopeNodes, NANodes))
206 return false;
207 }
208
209 return true;
210}
211
213 const MDNode *Scopes2) {
214 if (!Scopes1 || !Scopes2)
215 return true;
216
217 // Collect the domains with disjoint scopes that the first access is in.
219 collectScopedDomains(Scopes1, Domains, /*DisjointOnly=*/true);
220
221 // The accesses don't alias if, for some domain, both accesses use at least
222 // one of its scopes and have no scopes in that domain in common.
223 for (const MDNode *Domain : Domains) {
225 collectMDInDomain(Scopes2, Domain, Nodes2);
226 if (Nodes2.empty())
227 continue;
228
230 collectMDInDomain(Scopes1, Domain, Nodes1);
231 if (!llvm::set_intersects(Nodes1, Nodes2))
232 return false;
233 }
234
235 return true;
236}
237
238AnalysisKey ScopedNoAliasAA::Key;
239
244
246
248 "Scoped NoAlias Alias Analysis", false, true)
249
251 return new ScopedNoAliasAAWrapperPass();
252}
253
255
257 Result.reset(new ScopedNoAliasAAResult());
258 return false;
259}
260
262 Result.reset();
263 return false;
264}
265
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static Domain getDomain(const ConstantRange &CR)
#define F(x, y, z)
Definition MD5.cpp:54
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:56
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.
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.
Wrapper around alias scope domain metedata to allow accessing their fields, including surfacing the o...
Definition Metadata.h:1603
This is a simple wrapper around an MDNode which provides a higher-level interface by hiding the detai...
Definition Metadata.h:1633
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...
An instruction for ordering other memory operations.
ImmutablePass class - This class is used to provide information that does not need to be run.
Definition Pass.h:285
ImmutablePass(char &pid)
Definition Pass.h:287
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Metadata node.
Definition Metadata.h:1081
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1435
Tracking metadata reference owned by Metadata.
Definition Metadata.h:902
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:68
A simple AA result which uses scoped-noalias metadata to answer queries.
static LLVM_ABI bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias)
static LLVM_ABI AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
static LLVM_ABI void collectScopedDomains(const MDNode *NoAlias, SmallPtrSetImpl< const MDNode * > &Domains, bool DisjointOnly=false)
Collect the set of scoped domains relevant to the noalias scopes.
static LLVM_ABI bool mayAliasInDisjointDomains(const MDNode *Scopes1, const MDNode *Scopes2)
Return false if two accesses with scope lists Scopes1 and Scopes2 are kept apart because they use dif...
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...
LLVM_ABI ScopedNoAliasAAResult run(Function &F, FunctionAnalysisManager &AM)
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
CallInst * Call
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
bool set_intersects(const S1Ty &S1, const S2Ty &S2)
set_intersects(A, B) - Return true iff A ^ B is non empty
LLVM_ABI ImmutablePass * createScopedNoAliasAAWrapperPass()
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition ModRef.h:28
@ ModRef
The access may reference and may modify the value stored in memory.
Definition ModRef.h:36
@ NoModRef
The access neither references nor modifies the value stored in memory.
Definition ModRef.h:30
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
MDNode * Scope
The tag for alias scope specification (used with noalias).
Definition Metadata.h:797
MDNode * NoAlias
The tag specifying the noalias scope.
Definition Metadata.h:800
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29