LLVM 23.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"
40#include "llvm/IR/LLVMContext.h"
41#include "llvm/IR/Metadata.h"
43#include "llvm/Pass.h"
46
47using namespace llvm;
48
49// A handy option for disabling scoped no-alias functionality. The same effect
50// can also be achieved by stripping the associated metadata tags from IR, but
51// this option is sometimes more convenient.
52static cl::opt<bool> EnableScopedNoAlias("enable-scoped-noalias",
53 cl::init(true), cl::Hidden);
54
56 const MemoryLocation &LocB) {
59
60 // Get the attached MDNodes.
61 const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
62
63 const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias;
64
65 if (!mayAliasInScopes(AScopes, BNoAlias))
67
68 if (!mayAliasInScopes(BScopes, ANoAlias))
70
72}
73
75 const MemoryLocation &LocB,
76 AAQueryInfo &, const Instruction *) {
77 return alias(LocA, LocB);
78}
79
81 const MemoryLocation &Loc,
82 AAQueryInfo &AAQI) {
84 return ModRefInfo::ModRef;
85
86 if (!mayAliasInScopes(Loc.AATags.Scope,
87 Call->getMetadata(LLVMContext::MD_noalias)))
89
90 if (!mayAliasInScopes(Call->getMetadata(LLVMContext::MD_alias_scope),
91 Loc.AATags.NoAlias))
93
94 return ModRefInfo::ModRef;
95}
96
98 const MemoryLocation &Loc,
99 AAQueryInfo &AAQI) {
101 return ModRefInfo::ModRef;
102
103 if (!mayAliasInScopes(Loc.AATags.Scope,
104 F->getMetadata(LLVMContext::MD_noalias)))
106
107 if (!mayAliasInScopes(F->getMetadata(LLVMContext::MD_alias_scope),
108 Loc.AATags.NoAlias))
110
111 return ModRefInfo::ModRef;
112}
113
115 const CallBase *Call2,
116 AAQueryInfo &AAQI) {
118 return ModRefInfo::ModRef;
119
120 if (!mayAliasInScopes(Call1->getMetadata(LLVMContext::MD_alias_scope),
121 Call2->getMetadata(LLVMContext::MD_noalias)))
123
124 if (!mayAliasInScopes(Call2->getMetadata(LLVMContext::MD_alias_scope),
125 Call1->getMetadata(LLVMContext::MD_noalias)))
127
128 return ModRefInfo::ModRef;
129}
130
131static void collectMDInDomain(const MDNode *List, const MDNode *Domain,
133 for (const MDOperand &MDOp : List->operands())
134 if (const MDNode *MD = dyn_cast<MDNode>(MDOp))
135 if (AliasScopeNode(MD).getDomain() == Domain)
136 Nodes.insert(MD);
137}
138
139/// Collect the set of scoped domains relevant to the noalias scopes.
141 const MDNode *NoAlias, SmallPtrSetImpl<const MDNode *> &Domains) {
142 if (!NoAlias)
143 return;
144 assert(Domains.empty() && "Domains should be empty");
145 for (const MDOperand &MDOp : NoAlias->operands())
146 if (const MDNode *NAMD = dyn_cast<MDNode>(MDOp))
147 if (const MDNode *Domain = AliasScopeNode(NAMD).getDomain())
148 Domains.insert(Domain);
149}
150
152 const MDNode *NoAlias) {
153 if (!Scopes || !NoAlias)
154 return true;
155
156 // Collect the set of scope domains relevant to the noalias scopes.
158 collectScopedDomains(NoAlias, Domains);
159
160 // We alias unless, for some domain, the set of noalias scopes in that domain
161 // is a superset of the set of alias scopes in that domain.
162 for (const MDNode *Domain : Domains) {
164 collectMDInDomain(Scopes, Domain, ScopeNodes);
165 if (ScopeNodes.empty())
166 continue;
167
169 collectMDInDomain(NoAlias, Domain, NANodes);
170
171 // To not alias, all of the nodes in ScopeNodes must be in NANodes.
172 if (llvm::set_is_subset(ScopeNodes, NANodes))
173 return false;
174 }
175
176 return true;
177}
178
179AnalysisKey ScopedNoAliasAA::Key;
180
185
187
189 "Scoped NoAlias Alias Analysis", false, true)
190
192 return new ScopedNoAliasAAWrapperPass();
193}
194
196
198 Result.reset(new ScopedNoAliasAAResult());
199 return false;
200}
201
203 Result.reset();
204 return false;
205}
206
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.
This is a simple wrapper around an MDNode which provides a higher-level interface by hiding the detai...
Definition Metadata.h:1596
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:1080
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1442
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:67
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)
static LLVM_ABI void collectScopedDomains(const MDNode *NoAlias, SmallPtrSetImpl< const MDNode * > &Domains)
Collect the set of scoped domains relevant to the noalias scopes.
LLVM_ABI ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc, AAQueryInfo &AAQI)
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
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:786
MDNode * NoAlias
The tag specifying the noalias scope.
Definition Metadata.h:789
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29