LLVM  4.0.0
ScopedNoAliasAA.cpp
Go to the documentation of this file.
1 //===- ScopedNoAliasAA.cpp - Scoped No-Alias Alias Analysis ---------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines the ScopedNoAlias alias-analysis pass, which implements
11 // metadata-based scoped no-alias support.
12 //
13 // Alias-analysis scopes are defined by an id (which can be a string or some
14 // other metadata node), a domain node, and an optional descriptive string.
15 // A domain is defined by an id (which can be a string or some other metadata
16 // node), and an optional descriptive string.
17 //
18 // !dom0 = metadata !{ metadata !"domain of foo()" }
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 is associated
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 //===----------------------------------------------------------------------===//
34 
36 #include "llvm/ADT/SmallPtrSet.h"
37 #include "llvm/IR/Constants.h"
38 #include "llvm/IR/LLVMContext.h"
39 #include "llvm/IR/Metadata.h"
40 #include "llvm/IR/Module.h"
41 #include "llvm/Pass.h"
43 
44 using namespace llvm;
45 
46 // A handy option for disabling scoped no-alias functionality. The same effect
47 // can also be achieved by stripping the associated metadata tags from IR, but
48 // this option is sometimes more convenient.
49 static cl::opt<bool> EnableScopedNoAlias("enable-scoped-noalias",
50  cl::init(true));
51 
52 namespace {
53 /// This is a simple wrapper around an MDNode which provides a higher-level
54 /// interface by hiding the details of how alias analysis information is encoded
55 /// in its operands.
56 class AliasScopeNode {
57  const MDNode *Node;
58 
59 public:
60  AliasScopeNode() : Node(nullptr) {}
61  explicit AliasScopeNode(const MDNode *N) : Node(N) {}
62 
63  /// Get the MDNode for this AliasScopeNode.
64  const MDNode *getNode() const { return Node; }
65 
66  /// Get the MDNode for this AliasScopeNode's domain.
67  const MDNode *getDomain() const {
68  if (Node->getNumOperands() < 2)
69  return nullptr;
70  return dyn_cast_or_null<MDNode>(Node->getOperand(1));
71  }
72 };
73 } // end of anonymous namespace
74 
76  const MemoryLocation &LocB) {
78  return AAResultBase::alias(LocA, LocB);
79 
80  // Get the attached MDNodes.
81  const MDNode *AScopes = LocA.AATags.Scope, *BScopes = LocB.AATags.Scope;
82 
83  const MDNode *ANoAlias = LocA.AATags.NoAlias, *BNoAlias = LocB.AATags.NoAlias;
84 
85  if (!mayAliasInScopes(AScopes, BNoAlias))
86  return NoAlias;
87 
88  if (!mayAliasInScopes(BScopes, ANoAlias))
89  return NoAlias;
90 
91  // If they may alias, chain to the next AliasAnalysis.
92  return AAResultBase::alias(LocA, LocB);
93 }
94 
96  const MemoryLocation &Loc) {
98  return AAResultBase::getModRefInfo(CS, Loc);
99 
100  if (!mayAliasInScopes(Loc.AATags.Scope, CS.getInstruction()->getMetadata(
102  return MRI_NoModRef;
103 
104  if (!mayAliasInScopes(
106  Loc.AATags.NoAlias))
107  return MRI_NoModRef;
108 
109  return AAResultBase::getModRefInfo(CS, Loc);
110 }
111 
113  ImmutableCallSite CS2) {
114  if (!EnableScopedNoAlias)
115  return AAResultBase::getModRefInfo(CS1, CS2);
116 
117  if (!mayAliasInScopes(
120  return MRI_NoModRef;
121 
122  if (!mayAliasInScopes(
125  return MRI_NoModRef;
126 
127  return AAResultBase::getModRefInfo(CS1, CS2);
128 }
129 
130 static void collectMDInDomain(const MDNode *List, const MDNode *Domain,
132  for (const MDOperand &MDOp : List->operands())
133  if (const MDNode *MD = dyn_cast<MDNode>(MDOp))
134  if (AliasScopeNode(MD).getDomain() == Domain)
135  Nodes.insert(MD);
136 }
137 
138 bool ScopedNoAliasAAResult::mayAliasInScopes(const MDNode *Scopes,
139  const MDNode *NoAlias) const {
140  if (!Scopes || !NoAlias)
141  return true;
142 
143  // Collect the set of scope domains relevant to the noalias scopes.
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  // We alias unless, for some domain, the set of noalias scopes in that domain
151  // is a superset of the set of alias scopes in that domain.
152  for (const MDNode *Domain : Domains) {
154  collectMDInDomain(Scopes, Domain, ScopeNodes);
155  if (ScopeNodes.empty())
156  continue;
157 
159  collectMDInDomain(NoAlias, Domain, NANodes);
160 
161  // To not alias, all of the nodes in ScopeNodes must be in NANodes.
162  bool FoundAll = true;
163  for (const MDNode *SMD : ScopeNodes)
164  if (!NANodes.count(SMD)) {
165  FoundAll = false;
166  break;
167  }
168 
169  if (FoundAll)
170  return false;
171  }
172 
173  return true;
174 }
175 
176 AnalysisKey ScopedNoAliasAA::Key;
177 
180  return ScopedNoAliasAAResult();
181 }
182 
185  "Scoped NoAlias Alias Analysis", false, true)
186 
188  return new ScopedNoAliasAAWrapperPass();
189 }
190 
193 }
194 
196  Result.reset(new ScopedNoAliasAAResult());
197  return false;
198 }
199 
201  Result.reset();
202  return false;
203 }
204 
206  AU.setPreservesAll();
207 }
Tracking metadata reference owned by Metadata.
Definition: Metadata.h:679
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
MDNode * Scope
The tag for alias scope specification (used with noalias).
Definition: Metadata.h:642
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:52
This file contains the declarations for metadata subclasses.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:380
This is the interface for a metadata-based scoped no-alias analysis.
Metadata node.
Definition: Metadata.h:830
The two locations do not alias at all.
Definition: AliasAnalysis.h:79
ImmutablePass * createScopedNoAliasAAWrapperPass()
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:345
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: AliasAnalysis.h:94
A simple AA result which uses scoped-noalias metadata to answer queries.
INITIALIZE_PASS(ScopedNoAliasAAWrapperPass,"scoped-noalias","Scoped NoAlias Alias Analysis", false, true) ImmutablePass *llvm
static cl::opt< bool > EnableScopedNoAlias("enable-scoped-noalias", cl::init(true))
#define F(x, y, z)
Definition: MD5.cpp:51
bool doFinalization(Module &M) override
doFinalization - Virtual method overriden by subclasses to do any necessary clean up after all passes...
void initializeScopedNoAliasAAWrapperPassPass(PassRegistry &)
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
The access neither references nor modifies the value stored in memory.
Definition: AliasAnalysis.h:96
Legacy wrapper pass to provide the ScopedNoAliasAAResult object.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:395
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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:368
AliasResult
The possible results of an alias query.
Definition: AliasAnalysis.h:73
Represent the analysis usage information of a pass.
LLVM_NODISCARD bool empty() const
Definition: SmallPtrSet.h:98
AliasResult alias(const MemoryLocation &LocA, const MemoryLocation &LocB)
Representation for a specific memory location.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:425
ImmutablePass class - This class is used to provide information that does not need to be run...
Definition: Pass.h:266
InstrTy * getInstruction() const
Definition: CallSite.h:93
Module.h This file contains the declarations for the Module class.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
Definition: Instruction.h:175
MDNode * NoAlias
The tag specifying the noalias scope.
Definition: Metadata.h:645
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool doInitialization(Module &M) override
doInitialization - Virtual method overridden by subclasses to do any necessary initialization before ...
AAMDNodes AATags
The metadata nodes which describes the aliasing of the location (each member is null if that kind of ...
ImmutableCallSite - establish a view to a call site for examination.
Definition: CallSite.h:665
const NodeList & List
Definition: RDFGraph.cpp:205
#define N
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
op_range operands() const
Definition: Metadata.h:1032
ModRefInfo getModRefInfo(ImmutableCallSite CS, const MemoryLocation &Loc)
A container for analyses that lazily runs them and caches their results.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:64
ScopedNoAliasAAResult run(Function &F, FunctionAnalysisManager &AM)
static void collectMDInDomain(const MDNode *List, const MDNode *Domain, SmallPtrSetImpl< const MDNode * > &Nodes)