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" 26 #include "llvm/ADT/PointerIntPair.h" 27 #include "llvm/ADT/SmallPtrSet.h" 28 #include "llvm/ADT/SmallVector.h" 29 #include "llvm/IR/DerivedTypes.h" 30 #include "llvm/IR/InstVisitor.h" 31 #include "llvm/IR/IntrinsicInst.h" 32 #include <cassert> 33 #include <type_traits> 34 35 namespace llvm { 36 class DataLayout; 37 38 namespace 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. 46 class PtrUseVisitorBase { 47 public: 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. 86 void setAborted(Instruction *I) { 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. 93 void setEscaped(Instruction *I) { 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. 99 void setEscapedReadOnly(Instruction *I) { 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. 108 void setEscapedAndAborted(Instruction *I) { 109 setEscaped(I); 110 setAborted(I); 111 } 112 113 private: 114 Instruction *AbortedInfo = nullptr; 115 Instruction *EscapedInfo = nullptr; 116 Instruction *EscapedReadOnly = nullptr; 117 }; 118 119 protected: 120 const DataLayout &DL; 121 122 /// \name Visitation infrastructure 123 /// @{ 124 125 /// The info collected about the pointer being visited thus far. 126 PtrInfo PI; 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 { 133 using UseAndIsOffsetKnownPair = PointerIntPair<Use *, 1, bool>; 134 135 UseAndIsOffsetKnownPair UseAndIsOffsetKnown; 136 APInt Offset; 137 }; 138 139 /// The worklist of to-visit uses. 140 SmallVector<UseToVisit, 8> Worklist; 141 142 /// A set of visited uses to break cycles in unreachable code. 143 SmallPtrSet<Use *, 8> VisitedUses; 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. 152 Use *U; 153 154 /// True if we have a known constant offset for the use currently 155 /// being visited. 156 bool IsOffsetKnown; 157 158 /// The constant offset of the use if that is known. 159 APInt Offset; 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. 165 PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} 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. 177 bool adjustOffsetForGEP(GetElementPtrInst &GEPI); 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. 207 template <typename DerivedT> 208 class PtrUseVisitor : protected InstVisitor<DerivedT>, 209 public detail::PtrUseVisitorBase { 210 friend class InstVisitor<DerivedT>; 211 212 using Base = InstVisitor<DerivedT>; 213 214 public: 215 PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) { 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. 224 PtrInfo visitPtr(Value &I) { 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. 236 enqueueUsers(I); 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(); 242 IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt(); 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 254 protected: 255 void visitStoreInst(StoreInst &SI) { 256 if (SI.getValueOperand() == U->get()) 257 PI.setEscaped(&SI); 258 } 259 260 void visitBitCastInst(BitCastInst &BC) { 261 enqueueUsers(BC); 262 } 263 264 void visitAddrSpaceCastInst(AddrSpaceCastInst &ASC) { 265 enqueueUsers(ASC); 266 } 267 268 void visitPtrToIntInst(PtrToIntInst &I) { 269 PI.setEscaped(&I); 270 } 271 272 void visitGetElementPtrInst(GetElementPtrInst &GEPI) { 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. 288 void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {} 289 void visitMemIntrinsic(MemIntrinsic &I) {} 290 void visitIntrinsicInst(IntrinsicInst &II) { 291 switch (II.getIntrinsicID()) { 292 default: 293 return Base::visitIntrinsicInst(II); 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. 309 void visitCallBase(CallBase &CB) { 310 PI.setEscaped(&CB); 311 Base::visitCallBase(CB); 312 } 313 }; 314 315 } // end namespace llvm 316 317 #endif // LLVM_ANALYSIS_PTRUSEVISITOR_H 318