LLVM 20.0.0git
AliasSetTracker.h
Go to the documentation of this file.
1//===- llvm/Analysis/AliasSetTracker.h - Build Alias Sets -------*- C++ -*-===//
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 two classes: AliasSetTracker and AliasSet. These interfaces
10// are used to classify a collection of memory locations into a maximal number
11// of disjoint sets. Each AliasSet object constructed by the AliasSetTracker
12// object refers to memory disjoint from the other sets.
13//
14// An AliasSetTracker can only be used on immutable IR.
15//
16//===----------------------------------------------------------------------===//
17
18#ifndef LLVM_ANALYSIS_ALIASSETTRACKER_H
19#define LLVM_ANALYSIS_ALIASSETTRACKER_H
20
21#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/ilist.h"
24#include "llvm/ADT/ilist_node.h"
26#include "llvm/IR/PassManager.h"
27#include "llvm/IR/ValueHandle.h"
28#include <cassert>
29#include <vector>
30
31namespace llvm {
32
33class AliasResult;
34class AliasSetTracker;
35class AnyMemSetInst;
36class AnyMemTransferInst;
37class BasicBlock;
38class BatchAAResults;
39class Function;
40class Instruction;
41class StoreInst;
42class LoadInst;
43enum class ModRefInfo : uint8_t;
44class raw_ostream;
45class VAArgInst;
46class Value;
47
48class AliasSet : public ilist_node<AliasSet> {
49 friend class AliasSetTracker;
50
51 // Forwarding pointer.
52 AliasSet *Forward = nullptr;
53
54 /// Memory locations in this alias set.
56
57 /// All instructions without a specific address in this alias set.
58 std::vector<AssertingVH<Instruction>> UnknownInsts;
59
60 /// Number of nodes pointing to this AliasSet plus the number of AliasSets
61 /// forwarding to it.
62 unsigned RefCount : 27;
63
64 // Signifies that this set should be considered to alias any pointer.
65 // Use when the tracker holding this set is saturated.
66 unsigned AliasAny : 1;
67
68 /// The kinds of access this alias set models.
69 ///
70 /// We keep track of whether this alias set merely refers to the locations of
71 /// memory (and not any particular access), whether it modifies or references
72 /// the memory, or whether it does both. The lattice goes from "NoAccess" to
73 /// either RefAccess or ModAccess, then to ModRefAccess as necessary.
74 enum AccessLattice {
75 NoAccess = 0,
76 RefAccess = 1,
77 ModAccess = 2,
78 ModRefAccess = RefAccess | ModAccess
79 };
80 unsigned Access : 2;
81
82 /// The kind of alias relationship between pointers of the set.
83 ///
84 /// These represent conservatively correct alias results between any members
85 /// of the set. We represent these independently of the values of alias
86 /// results in order to pack it into a single bit. Lattice goes from
87 /// MustAlias to MayAlias.
88 enum AliasLattice {
89 SetMustAlias = 0, SetMayAlias = 1
90 };
91 unsigned Alias : 1;
92
93 void addRef() { ++RefCount; }
94
95 void dropRef(AliasSetTracker &AST) {
96 assert(RefCount >= 1 && "Invalid reference count detected!");
97 if (--RefCount == 0)
98 removeFromTracker(AST);
99 }
100
101public:
102 AliasSet(const AliasSet &) = delete;
103 AliasSet &operator=(const AliasSet &) = delete;
104
105 /// Accessors...
106 bool isRef() const { return Access & RefAccess; }
107 bool isMod() const { return Access & ModAccess; }
108 bool isMustAlias() const { return Alias == SetMustAlias; }
109 bool isMayAlias() const { return Alias == SetMayAlias; }
110
111 /// Return true if this alias set should be ignored as part of the
112 /// AliasSetTracker object.
113 bool isForwardingAliasSet() const { return Forward; }
114
115 /// Merge the specified alias set into this alias set.
116 void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA);
117
118 // Alias Set iteration - Allow access to all of the memory locations which are
119 // part of this alias set.
121 iterator begin() const { return MemoryLocs.begin(); }
122 iterator end() const { return MemoryLocs.end(); }
123
124 unsigned size() const { return MemoryLocs.size(); }
125
126 /// Retrieve the pointer values for the memory locations in this alias set.
127 /// The order matches that of the memory locations, but duplicate pointer
128 /// values are omitted.
131
132 void print(raw_ostream &OS) const;
133 void dump() const;
134
135private:
136 // Can only be created by AliasSetTracker.
137 AliasSet()
138 : RefCount(0), AliasAny(false), Access(NoAccess), Alias(SetMustAlias) {}
139
140 void removeFromTracker(AliasSetTracker &AST);
141
142 void addMemoryLocation(AliasSetTracker &AST, const MemoryLocation &MemLoc,
143 bool KnownMustAlias = false);
144 void addUnknownInst(Instruction *I, BatchAAResults &AA);
145
146public:
147 /// If the specified memory location "may" (or must) alias one of the members
148 /// in the set return the appropriate AliasResult. Otherwise return NoAlias.
150 BatchAAResults &AA) const;
151
153 BatchAAResults &AA) const;
154};
155
157 AS.print(OS);
158 return OS;
159}
160
162 BatchAAResults &AA;
163 ilist<AliasSet> AliasSets;
164
166
167 // Map from pointer values to the alias set holding one or more memory
168 // locations with that pointer value.
169 PointerMapType PointerMap;
170
171public:
172 /// Create an empty collection of AliasSets, and use the specified alias
173 /// analysis object to disambiguate load and store addresses.
174 explicit AliasSetTracker(BatchAAResults &AA) : AA(AA) {}
176
177 /// These methods are used to add different types of instructions to the alias
178 /// sets. Adding a new instruction can result in one of three actions
179 /// happening:
180 ///
181 /// 1. If the instruction doesn't alias any other sets, create a new set.
182 /// 2. If the instruction aliases exactly one set, add it to the set
183 /// 3. If the instruction aliases multiple sets, merge the sets, and add
184 /// the instruction to the result.
185 ///
186 void add(const MemoryLocation &Loc);
187 void add(LoadInst *LI);
188 void add(StoreInst *SI);
189 void add(VAArgInst *VAAI);
190 void add(AnyMemSetInst *MSI);
191 void add(AnyMemTransferInst *MTI);
192 void add(Instruction *I); // Dispatch to one of the other add methods...
193 void add(BasicBlock &BB); // Add all instructions in basic block
194 void add(const AliasSetTracker &AST); // Add alias relations from another AST
195 void addUnknown(Instruction *I);
196
197 void clear();
198
199 /// Return the alias sets that are active.
200 const ilist<AliasSet> &getAliasSets() const { return AliasSets; }
201
202 /// Return the alias set which contains the specified memory location. If
203 /// the memory location aliases two or more existing alias sets, will have
204 /// the effect of merging those alias sets before the single resulting alias
205 /// set is returned.
206 AliasSet &getAliasSetFor(const MemoryLocation &MemLoc);
207
208 /// Return the underlying alias analysis object used by this tracker.
209 BatchAAResults &getAliasAnalysis() const { return AA; }
210
213
214 const_iterator begin() const { return AliasSets.begin(); }
215 const_iterator end() const { return AliasSets.end(); }
216
217 iterator begin() { return AliasSets.begin(); }
218 iterator end() { return AliasSets.end(); }
219
220 void print(raw_ostream &OS) const;
221 void dump() const;
222
223private:
224 friend class AliasSet;
225
226 // The total number of memory locations contained in all alias sets.
227 unsigned TotalAliasSetSize = 0;
228
229 // A non-null value signifies this AST is saturated. A saturated AST lumps
230 // all elements into a single "May" set.
231 AliasSet *AliasAnyAS = nullptr;
232
233 void removeAliasSet(AliasSet *AS);
234
235 // Update an alias set field to point to its real destination. If the field is
236 // pointing to a set that has been merged with another set and is forwarding,
237 // the field is updated to point to the set obtained by following the
238 // forwarding links. The Forward fields of intermediate alias sets are
239 // collapsed as well, and alias set reference counts are updated to reflect
240 // the new situation.
241 void collapseForwardingIn(AliasSet *&AS) {
242 if (AS->Forward) {
243 collapseForwardingIn(AS->Forward);
244 // Swap out AS for AS->Forward, while updating reference counts.
245 AliasSet *NewAS = AS->Forward;
246 NewAS->addRef();
247 AS->dropRef(*this);
248 AS = NewAS;
249 }
250 }
251
252 AliasSet &addMemoryLocation(MemoryLocation Loc, AliasSet::AccessLattice E);
253 AliasSet *mergeAliasSetsForMemoryLocation(const MemoryLocation &MemLoc,
254 AliasSet *PtrAS,
255 bool &MustAliasAll);
256
257 /// Merge all alias sets into a single set that is considered to alias
258 /// any memory location or instruction.
259 AliasSet &mergeAllAliasSets();
260
261 AliasSet *findAliasSetForUnknownInst(Instruction *Inst);
262};
263
265 AST.print(OS);
266 return OS;
267}
268
269class AliasSetsPrinterPass : public PassInfoMixin<AliasSetsPrinterPass> {
270 raw_ostream &OS;
271
272public:
275 static bool isRequired() { return true; }
276};
277
278} // end namespace llvm
279
280#endif // LLVM_ANALYSIS_ALIASSETTRACKER_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file provides utility analysis objects describing memory locations.
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
The possible results of an alias query.
Definition: AliasAnalysis.h:77
ilist< AliasSet >::iterator iterator
const ilist< AliasSet > & getAliasSets() const
Return the alias sets that are active.
BatchAAResults & getAliasAnalysis() const
Return the underlying alias analysis object used by this tracker.
AliasSet & getAliasSetFor(const MemoryLocation &MemLoc)
Return the alias set which contains the specified memory location.
void addUnknown(Instruction *I)
AliasSetTracker(BatchAAResults &AA)
Create an empty collection of AliasSets, and use the specified alias analysis object to disambiguate ...
const_iterator end() const
ilist< AliasSet >::const_iterator const_iterator
const_iterator begin() const
void print(raw_ostream &OS) const
void add(const MemoryLocation &Loc)
These methods are used to add different types of instructions to the alias sets.
unsigned size() const
iterator begin() const
void mergeSetIn(AliasSet &AS, AliasSetTracker &AST, BatchAAResults &BatchAA)
Merge the specified alias set into this alias set.
void print(raw_ostream &OS) const
AliasSet(const AliasSet &)=delete
iterator end() const
bool isMayAlias() const
bool isForwardingAliasSet() const
Return true if this alias set should be ignored as part of the AliasSetTracker object.
AliasSet & operator=(const AliasSet &)=delete
ModRefInfo aliasesUnknownInst(const Instruction *Inst, BatchAAResults &AA) const
bool isMustAlias() const
AliasResult aliasesMemoryLocation(const MemoryLocation &MemLoc, BatchAAResults &AA) const
If the specified memory location "may" (or must) alias one of the members in the set return the appro...
friend class AliasSetTracker
SmallVectorImpl< MemoryLocation >::const_iterator iterator
bool isMod() const
bool isRef() const
Accessors...
PointerVector getPointers() const
void dump() const
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
This class represents any memset intrinsic.
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
An instruction for reading from memory.
Definition: Instructions.h:174
Representation for a specific memory location.
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
size_t size() const
Definition: SmallVector.h:91
typename SuperClass::const_iterator const_iterator
Definition: SmallVector.h:591
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
An instruction for storing to memory.
Definition: Instructions.h:290
This class represents the va_arg llvm instruction, which returns an argument of the specified type gi...
An intrusive list with ownership and callbacks specified/controlled by ilist_traits,...
Definition: ilist.h:328
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This file defines classes to implement an intrusive doubly linked list class (i.e.
This file defines the ilist_node class template, which is a convenient base class for creating classe...
@ BasicBlock
Various leaf nodes.
Definition: ISDOpcodes.h:71
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition: ModRef.h:27
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
Definition: APFixedPoint.h:292
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:69