LLVM 20.0.0git
PtrUseVisitor.h
Go to the documentation of this file.
1//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- 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/// \file
10/// This file provides a collection of visitors which walk the (instruction)
11/// uses of a pointer. These visitors all provide the same essential behavior
12/// as an InstVisitor with similar template-based flexibility and
13/// implementation strategies.
14///
15/// These can be used, for example, to quickly analyze the uses of an alloca,
16/// global variable, or function argument.
17///
18/// FIXME: Provide a variant which doesn't track offsets and is cheaper.
19//
20//===----------------------------------------------------------------------===//
21
22#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H
23#define LLVM_ANALYSIS_PTRUSEVISITOR_H
24
25#include "llvm/ADT/APInt.h"
30#include "llvm/IR/InstVisitor.h"
32#include <cassert>
33#include <type_traits>
34
35namespace llvm {
36class DataLayout;
37
38namespace detail {
39
40/// Implementation of non-dependent functionality for \c PtrUseVisitor.
41///
42/// See \c PtrUseVisitor for the public interface and detailed comments about
43/// usage. This class is just a helper base class which is not templated and
44/// contains all common code to be shared between different instantiations of
45/// PtrUseVisitor.
47public:
48 /// This class provides information about the result of a visit.
49 ///
50 /// After walking all the users (recursively) of a pointer, the basic
51 /// infrastructure records some commonly useful information such as escape
52 /// analysis and whether the visit completed or aborted early.
53 class PtrInfo {
54 public:
55 /// Reset the pointer info, clearing all state.
56 void reset() {
57 AbortedInfo = nullptr;
58 EscapedInfo = nullptr;
59 }
60
61 /// Did we abort the visit early?
62 bool isAborted() const { return AbortedInfo != nullptr; }
63
64 /// Is the pointer escaped at some point?
65 bool isEscaped() const { return EscapedInfo != nullptr; }
66
67 /// Is the pointer escaped into a read-only nocapture call at some point?
68 bool isEscapedReadOnly() const { return EscapedReadOnly != nullptr; }
69
70 /// Get the instruction causing the visit to abort.
71 /// \returns a pointer to the instruction causing the abort if one is
72 /// available; otherwise returns null.
73 Instruction *getAbortingInst() const { return AbortedInfo; }
74
75 /// Get the instruction causing the pointer to escape.
76 /// \returns a pointer to the instruction which escapes the pointer if one
77 /// is available; otherwise returns null.
78 Instruction *getEscapingInst() const { return EscapedInfo; }
79
80 /// Get the instruction causing the pointer to escape which is a read-only
81 /// nocapture call.
82 Instruction *getEscapedReadOnlyInst() const { return EscapedReadOnly; }
83
84 /// Mark the visit as aborted. Intended for use in a void return.
85 /// \param I The instruction which caused the visit to abort, if available.
87 assert(I && "Expected a valid pointer in setAborted");
88 AbortedInfo = I;
89 }
90
91 /// Mark the pointer as escaped. Intended for use in a void return.
92 /// \param I The instruction which escapes the pointer, if available.
94 assert(I && "Expected a valid pointer in setEscaped");
95 EscapedInfo = I;
96 }
97
98 /// Mark the pointer as escaped into a readonly-nocapture call.
100 assert(I && "Expected a valid pointer in setEscapedReadOnly");
101 EscapedReadOnly = I;
102 }
103
104 /// Mark the pointer as escaped, and the visit as aborted. Intended
105 /// for use in a void return.
106 /// \param I The instruction which both escapes the pointer and aborts the
107 /// visit, if available.
109 setEscaped(I);
110 setAborted(I);
111 }
112
113 private:
114 Instruction *AbortedInfo = nullptr;
115 Instruction *EscapedInfo = nullptr;
116 Instruction *EscapedReadOnly = nullptr;
117 };
118
119protected:
121
122 /// \name Visitation infrastructure
123 /// @{
124
125 /// The info collected about the pointer being visited thus far.
127
128 /// A struct of the data needed to visit a particular use.
129 ///
130 /// This is used to maintain a worklist fo to-visit uses. This is used to
131 /// make the visit be iterative rather than recursive.
132 struct UseToVisit {
134
137 };
138
139 /// The worklist of to-visit uses.
141
142 /// A set of visited uses to break cycles in unreachable code.
144
145 /// @}
146
147 /// \name Per-visit state
148 /// This state is reset for each instruction visited.
149 /// @{
150
151 /// The use currently being visited.
153
154 /// True if we have a known constant offset for the use currently
155 /// being visited.
157
158 /// The constant offset of the use if that is known.
160
161 /// @}
162
163 /// Note that the constructor is protected because this class must be a base
164 /// class, we can't create instances directly of this class.
166
167 /// Enqueue the users of this instruction in the visit worklist.
168 ///
169 /// This will visit the users with the same offset of the current visit
170 /// (including an unknown offset if that is the current state).
171 void enqueueUsers(Value &I);
172
173 /// Walk the operands of a GEP and adjust the offset as appropriate.
174 ///
175 /// This routine does the heavy lifting of the pointer walk by computing
176 /// offsets and looking through GEPs.
178};
179
180} // end namespace detail
181
182/// A base class for visitors over the uses of a pointer value.
183///
184/// Once constructed, a user can call \c visit on a pointer value, and this
185/// will walk its uses and visit each instruction using an InstVisitor. It also
186/// provides visit methods which will recurse through any pointer-to-pointer
187/// transformations such as GEPs and bitcasts.
188///
189/// During the visit, the current Use* being visited is available to the
190/// subclass, as well as the current offset from the original base pointer if
191/// known.
192///
193/// The recursive visit of uses is accomplished with a worklist, so the only
194/// ordering guarantee is that an instruction is visited before any uses of it
195/// are visited. Note that this does *not* mean before any of its users are
196/// visited! This is because users can be visited multiple times due to
197/// multiple, different uses of pointers derived from the same base.
198///
199/// A particular Use will only be visited once, but a User may be visited
200/// multiple times, once per Use. This visits may notably have different
201/// offsets.
202///
203/// All visit methods on the underlying InstVisitor return a boolean. This
204/// return short-circuits the visit, stopping it immediately.
205///
206/// FIXME: Generalize this for all values rather than just instructions.
207template <typename DerivedT>
208class PtrUseVisitor : protected InstVisitor<DerivedT>,
210 friend class InstVisitor<DerivedT>;
211
213
214public:
216 static_assert(std::is_base_of<PtrUseVisitor, DerivedT>::value,
217 "Must pass the derived type to this template!");
218 }
219
220 /// Recursively visit the uses of the given pointer.
221 /// \returns An info struct about the pointer. See \c PtrInfo for details.
222 /// We may also need to process Argument pointers, so the input uses is
223 /// a common Value type.
225 // This must be a pointer type. Get an integer type suitable to hold
226 // offsets on this pointer.
227 // FIXME: Support a vector of pointers.
228 assert(I.getType()->isPointerTy());
229 assert(isa<Instruction>(I) || isa<Argument>(I));
230 IntegerType *IntIdxTy = cast<IntegerType>(DL.getIndexType(I.getType()));
231 IsOffsetKnown = true;
232 Offset = APInt(IntIdxTy->getBitWidth(), 0);
233 PI.reset();
234
235 // Enqueue the uses of this pointer.
237
238 // Visit all the uses off the worklist until it is empty.
239 while (!Worklist.empty()) {
240 UseToVisit ToVisit = Worklist.pop_back_val();
241 U = ToVisit.UseAndIsOffsetKnown.getPointer();
243 if (IsOffsetKnown)
244 Offset = std::move(ToVisit.Offset);
245
246 Instruction *I = cast<Instruction>(U->getUser());
247 static_cast<DerivedT*>(this)->visit(I);
248 if (PI.isAborted())
249 break;
250 }
251 return PI;
252 }
253
254protected:
256 if (SI.getValueOperand() == U->get())
257 PI.setEscaped(&SI);
258 }
259
261 enqueueUsers(BC);
262 }
263
265 enqueueUsers(ASC);
266 }
267
269 PI.setEscaped(&I);
270 }
271
273 if (GEPI.use_empty())
274 return;
275
276 // If we can't walk the GEP, clear the offset.
277 if (!adjustOffsetForGEP(GEPI)) {
278 IsOffsetKnown = false;
279 Offset = APInt();
280 }
281
282 // Enqueue the users now that the offset has been adjusted.
283 enqueueUsers(GEPI);
284 }
285
286 // No-op intrinsics which we know don't escape the pointer to logic in
287 // some other function.
291 switch (II.getIntrinsicID()) {
292 default:
294
295 // We escape pointers used by a fake_use to prevent SROA from transforming
296 // them.
297 case Intrinsic::fake_use:
298 PI.setEscaped(&II);
299 return;
300
301 case Intrinsic::lifetime_start:
302 case Intrinsic::lifetime_end:
303 return; // No-op intrinsics.
304 }
305 }
306
307 // Generically, arguments to calls and invokes escape the pointer to some
308 // other function. Mark that.
310 PI.setEscaped(&CB);
312 }
313};
314
315} // end namespace llvm
316
317#endif // LLVM_ANALYSIS_PTRUSEVISITOR_H
This file implements a class to represent arbitrary precision integral constant values and operations...
#define I(x, y, z)
Definition: MD5.cpp:58
uint64_t IntrinsicInst * II
StandardInstrumentations SI(Mod->getContext(), Debug, VerifyEach)
This file defines the PointerIntPair class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
Class for arbitrary precision integers.
Definition: APInt.h:78
This class represents a conversion between pointers from one address space to another.
This class represents a no-op cast from one type to another.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1120
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
IntegerType * getIndexType(LLVMContext &C, unsigned AddressSpace) const
Returns the type of a GEP index in AddressSpace.
Definition: DataLayout.cpp:878
This is the common base class for debug info intrinsics.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:933
Base class for instruction visitors.
Definition: InstVisitor.h:78
void visitCallBase(CallBase &I)
Definition: InstVisitor.h:270
void visitIntrinsicInst(IntrinsicInst &I)
Definition: InstVisitor.h:222
void visit(Iterator Start, Iterator End)
Definition: InstVisitor.h:87
Class to represent integer types.
Definition: DerivedTypes.h:42
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:74
A wrapper class for inspecting calls to intrinsic functions.
Definition: IntrinsicInst.h:48
This is the common base class for memset/memcpy/memmove.
IntType getInt() const
PointerTy getPointer() const
This class represents a cast from a pointer to an integer.
A base class for visitors over the uses of a pointer value.
void visitCallBase(CallBase &CB)
void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I)
PtrUseVisitor(const DataLayout &DL)
PtrInfo visitPtr(Value &I)
Recursively visit the uses of the given pointer.
void visitGetElementPtrInst(GetElementPtrInst &GEPI)
void visitAddrSpaceCastInst(AddrSpaceCastInst &ASC)
void visitBitCastInst(BitCastInst &BC)
void visitStoreInst(StoreInst &SI)
void visitIntrinsicInst(IntrinsicInst &II)
void visitPtrToIntInst(PtrToIntInst &I)
void visitMemIntrinsic(MemIntrinsic &I)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
An instruction for storing to memory.
Definition: Instructions.h:292
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
bool use_empty() const
Definition: Value.h:344
This class provides information about the result of a visit.
Definition: PtrUseVisitor.h:53
Instruction * getEscapedReadOnlyInst() const
Get the instruction causing the pointer to escape which is a read-only nocapture call.
Definition: PtrUseVisitor.h:82
Instruction * getAbortingInst() const
Get the instruction causing the visit to abort.
Definition: PtrUseVisitor.h:73
Instruction * getEscapingInst() const
Get the instruction causing the pointer to escape.
Definition: PtrUseVisitor.h:78
bool isEscaped() const
Is the pointer escaped at some point?
Definition: PtrUseVisitor.h:65
void setEscaped(Instruction *I)
Mark the pointer as escaped.
Definition: PtrUseVisitor.h:93
void setAborted(Instruction *I)
Mark the visit as aborted.
Definition: PtrUseVisitor.h:86
bool isEscapedReadOnly() const
Is the pointer escaped into a read-only nocapture call at some point?
Definition: PtrUseVisitor.h:68
void reset()
Reset the pointer info, clearing all state.
Definition: PtrUseVisitor.h:56
bool isAborted() const
Did we abort the visit early?
Definition: PtrUseVisitor.h:62
void setEscapedAndAborted(Instruction *I)
Mark the pointer as escaped, and the visit as aborted.
void setEscapedReadOnly(Instruction *I)
Mark the pointer as escaped into a readonly-nocapture call.
Definition: PtrUseVisitor.h:99
Implementation of non-dependent functionality for PtrUseVisitor.
Definition: PtrUseVisitor.h:46
APInt Offset
The constant offset of the use if that is known.
void enqueueUsers(Value &I)
Enqueue the users of this instruction in the visit worklist.
PtrUseVisitorBase(const DataLayout &DL)
Note that the constructor is protected because this class must be a base class, we can't create insta...
SmallVector< UseToVisit, 8 > Worklist
The worklist of to-visit uses.
bool IsOffsetKnown
True if we have a known constant offset for the use currently being visited.
bool adjustOffsetForGEP(GetElementPtrInst &GEPI)
Walk the operands of a GEP and adjust the offset as appropriate.
PtrInfo PI
The info collected about the pointer being visited thus far.
Use * U
The use currently being visited.
SmallPtrSet< Use *, 8 > VisitedUses
A set of visited uses to break cycles in unreachable code.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
A struct of the data needed to visit a particular use.