1 //===- ScopedNoAliasAA.cpp - Scoped No-Alias Alias Analysis ---------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ScopedNoAlias alias-analysis pass, which implements
11 // metadata-based scoped no-alias support.
13 // Alias-analysis scopes are defined similar to TBAA nodes:
15 // !scope0 = metadata !{ metadata !"scope of foo()" }
16 // !scope1 = metadata !{ metadata !"scope 1", metadata !scope0 }
17 // !scope2 = metadata !{ metadata !"scope 2", metadata !scope0 }
18 // !scope3 = metadata !{ metadata !"scope 2.1", metadata !scope2 }
19 // !scope4 = metadata !{ metadata !"scope 2.2", metadata !scope2 }
21 // Loads and stores can be tagged with an alias-analysis scope, and also, with
22 // a noalias tag for a specific scope:
24 // ... = load %ptr1, !alias.scope !{ !scope1 }
25 // ... = load %ptr2, !alias.scope !{ !scope1, !scope2 }, !noalias !{ !scope1 }
27 // When evaluating an aliasing query, if one of the instructions is associated
28 // with an alias.scope id that is identical to the noalias scope associated
29 // with the other instruction, or is a descendant (in the scope hierarchy) of
30 // the noalias scope associated with the other instruction, then the two memory
31 // accesses are assumed not to alias.
33 // Note that if the first element of the scope metadata is a string, then it
34 // can be combined accross functions and translation units. The string can be
35 // replaced by a self-reference to create globally unqiue scope identifiers.
37 //===----------------------------------------------------------------------===//
39 #include "llvm/Analysis/Passes.h"
40 #include "llvm/Analysis/AliasAnalysis.h"
41 #include "llvm/IR/Constants.h"
42 #include "llvm/IR/LLVMContext.h"
43 #include "llvm/IR/Metadata.h"
44 #include "llvm/IR/Module.h"
45 #include "llvm/Pass.h"
46 #include "llvm/Support/CommandLine.h"
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.
53 EnableScopedNoAlias("enable-scoped-noalias", cl::init(true));
56 /// AliasScopeNode - This is a simple wrapper around an MDNode which provides
57 /// a higher-level interface by hiding the details of how alias analysis
58 /// information is encoded in its operands.
59 class AliasScopeNode {
63 AliasScopeNode() : Node(0) {}
64 explicit AliasScopeNode(const MDNode *N) : Node(N) {}
66 /// getNode - Get the MDNode for this AliasScopeNode.
67 const MDNode *getNode() const { return Node; }
69 /// getParent - Get this AliasScopeNode's Alias tree parent.
70 AliasScopeNode getParent() const {
71 if (Node->getNumOperands() < 2)
72 return AliasScopeNode();
73 MDNode *P = dyn_cast_or_null<MDNode>(Node->getOperand(1));
75 return AliasScopeNode();
76 // Ok, this node has a valid parent. Return it.
77 return AliasScopeNode(P);
81 /// ScopedNoAliasAA - This is a simple alias analysis
82 /// implementation that uses scoped-noalias metadata to answer queries.
83 class ScopedNoAliasAA : public ImmutablePass, public AliasAnalysis {
85 static char ID; // Class identification, replacement for typeinfo
86 ScopedNoAliasAA() : ImmutablePass(ID) {
87 initializeScopedNoAliasAAPass(*PassRegistry::getPassRegistry());
90 virtual void initializePass() {
91 InitializeAliasAnalysis(this);
94 /// getAdjustedAnalysisPointer - This method is used when a pass implements
95 /// an analysis interface through multiple inheritance. If needed, it
96 /// should override this to adjust the this pointer as needed for the
97 /// specified pass info.
98 virtual void *getAdjustedAnalysisPointer(const void *PI) {
99 if (PI == &AliasAnalysis::ID)
100 return (AliasAnalysis*)this;
105 bool mayAlias(const MDNode *A, const MDNode *B) const;
106 bool mayAliasInScopes(const MDNode *Scopes, const MDNode *NoAlias) const;
109 virtual void getAnalysisUsage(AnalysisUsage &AU) const;
110 virtual AliasResult alias(const Location &LocA, const Location &LocB);
111 virtual bool pointsToConstantMemory(const Location &Loc, bool OrLocal);
112 virtual ModRefBehavior getModRefBehavior(ImmutableCallSite CS);
113 virtual ModRefBehavior getModRefBehavior(const Function *F);
114 virtual ModRefResult getModRefInfo(ImmutableCallSite CS,
115 const Location &Loc);
116 virtual ModRefResult getModRefInfo(ImmutableCallSite CS1,
117 ImmutableCallSite CS2);
119 } // End of anonymous namespace
121 // Register this pass...
122 char ScopedNoAliasAA::ID = 0;
123 INITIALIZE_AG_PASS(ScopedNoAliasAA, AliasAnalysis, "scoped-noalias",
124 "Scoped NoAlias Alias Analysis", false, true, false)
126 ImmutablePass *llvm::createScopedNoAliasAAPass() {
127 return new ScopedNoAliasAA();
131 ScopedNoAliasAA::getAnalysisUsage(AnalysisUsage &AU) const {
132 AU.setPreservesAll();
133 AliasAnalysis::getAnalysisUsage(AU);
136 /// mayAlias - Test whether the scope represented by A may alias the
137 /// scope represented by B. Specifically, A is the target scope, and B is the
140 ScopedNoAliasAA::mayAlias(const MDNode *A,
141 const MDNode *B) const {
142 // Climb the tree from A to see if we reach B.
143 for (AliasScopeNode T(A); ; ) {
144 if (T.getNode() == B)
145 // B is an ancestor of A.
157 ScopedNoAliasAA::mayAliasInScopes(const MDNode *Scopes,
158 const MDNode *NoAlias) const {
159 if (!Scopes || !NoAlias)
162 for (unsigned i = 0, ie = Scopes->getNumOperands(); i != ie; ++i)
163 if (const MDNode *SMD = dyn_cast<MDNode>(Scopes->getOperand(i)))
164 for (unsigned j = 0, je = NoAlias->getNumOperands(); j != je; ++j)
165 if (const MDNode *NAMD = dyn_cast<MDNode>(NoAlias->getOperand(j)))
166 if (!mayAlias(SMD, NAMD))
172 AliasAnalysis::AliasResult
173 ScopedNoAliasAA::alias(const Location &LocA, const Location &LocB) {
174 if (!EnableScopedNoAlias)
175 return AliasAnalysis::alias(LocA, LocB);
177 // Get the attached MDNodes.
178 const MDNode *AScopes = LocA.AATags.Scope,
179 *BScopes = LocB.AATags.Scope;
181 const MDNode *ANoAlias = LocA.AATags.NoAlias,
182 *BNoAlias = LocB.AATags.NoAlias;
184 if (!mayAliasInScopes(AScopes, BNoAlias))
187 if (!mayAliasInScopes(BScopes, ANoAlias))
190 // If they may alias, chain to the next AliasAnalysis.
191 return AliasAnalysis::alias(LocA, LocB);
194 bool ScopedNoAliasAA::pointsToConstantMemory(const Location &Loc,
196 return AliasAnalysis::pointsToConstantMemory(Loc, OrLocal);
199 AliasAnalysis::ModRefBehavior
200 ScopedNoAliasAA::getModRefBehavior(ImmutableCallSite CS) {
201 return AliasAnalysis::getModRefBehavior(CS);
204 AliasAnalysis::ModRefBehavior
205 ScopedNoAliasAA::getModRefBehavior(const Function *F) {
206 return AliasAnalysis::getModRefBehavior(F);
209 AliasAnalysis::ModRefResult
210 ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS, const Location &Loc) {
211 if (!EnableScopedNoAlias)
212 return AliasAnalysis::getModRefInfo(CS, Loc);
214 if (!mayAliasInScopes(Loc.AATags.Scope,
215 CS.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
218 if (!mayAliasInScopes(
219 CS.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
223 return AliasAnalysis::getModRefInfo(CS, Loc);
226 AliasAnalysis::ModRefResult
227 ScopedNoAliasAA::getModRefInfo(ImmutableCallSite CS1, ImmutableCallSite CS2) {
228 if (!EnableScopedNoAlias)
229 return AliasAnalysis::getModRefInfo(CS1, CS2);
231 if (!mayAliasInScopes(
232 CS1.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
233 CS2.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
236 if (!mayAliasInScopes(
237 CS2.getInstruction()->getMetadata(LLVMContext::MD_alias_scope),
238 CS1.getInstruction()->getMetadata(LLVMContext::MD_noalias)))
241 return AliasAnalysis::getModRefInfo(CS1, CS2);