1ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth//===- PtrUseVisitor.h - InstVisitors over a pointers uses ------*- C++ -*-===// 2ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// 3ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// The LLVM Compiler Infrastructure 4ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// 5ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// This file is distributed under the University of Illinois Open Source 6ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// License. See LICENSE.TXT for details. 7ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth// 8ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth//===----------------------------------------------------------------------===// 9ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// \file 10ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// This file provides a collection of visitors which walk the (instruction) 11ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// uses of a pointer. These visitors all provide the same essential behavior 12ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// as an InstVisitor with similar template-based flexibility and 13ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// implementation strategies. 14ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 15ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// These can be used, for example, to quickly analyze the uses of an alloca, 16ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// global variable, or function argument. 17ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 18ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// FIXME: Provide a variant which doesn't track offsets and is cheaper. 19ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 20ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth//===----------------------------------------------------------------------===// 21ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 22ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#ifndef LLVM_ANALYSIS_PTRUSEVISITOR_H 23ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#define LLVM_ANALYSIS_PTRUSEVISITOR_H 24ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 25ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#include "llvm/ADT/APInt.h" 26ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#include "llvm/ADT/SmallPtrSet.h" 27ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#include "llvm/ADT/SmallVector.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/DataLayout.h" 290b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.h" 30ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#include "llvm/InstVisitor.h" 31ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#include "llvm/Support/Compiler.h" 32ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 33ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthnamespace llvm { 34ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 35ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthnamespace detail { 36ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// \brief Implementation of non-dependent functionality for \c PtrUseVisitor. 37ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 38ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// See \c PtrUseVisitor for the public interface and detailed comments about 39ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// usage. This class is just a helper base class which is not templated and 40ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// contains all common code to be shared between different instantiations of 41ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// PtrUseVisitor. 42ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthclass PtrUseVisitorBase { 43ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthpublic: 44ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief This class provides information about the result of a visit. 45ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// 46ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// After walking all the users (recursively) of a pointer, the basic 47ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// infrastructure records some commonly useful information such as escape 48ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// analysis and whether the visit completed or aborted early. 49ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth class PtrInfo { 50ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth public: 51ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PtrInfo() : AbortedInfo(0, false), EscapedInfo(0, false) {} 52ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 53ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Reset the pointer info, clearing all state. 54ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void reset() { 55ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth AbortedInfo.setPointer(0); 56ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth AbortedInfo.setInt(false); 57ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth EscapedInfo.setPointer(0); 58ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth EscapedInfo.setInt(false); 59ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 60ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 61ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Did we abort the visit early? 62ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth bool isAborted() const { return AbortedInfo.getInt(); } 63ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 64ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Is the pointer escaped at some point? 65ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth bool isEscaped() const { return EscapedInfo.getInt(); } 66ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 67ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Get the instruction causing the visit to abort. 68ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \returns a pointer to the instruction causing the abort if one is 69ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// available; otherwise returns null. 70ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Instruction *getAbortingInst() const { return AbortedInfo.getPointer(); } 71ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 72ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Get the instruction causing the pointer to escape. 73ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \returns a pointer to the instruction which escapes the pointer if one 74ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// is available; otherwise returns null. 75ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Instruction *getEscapingInst() const { return EscapedInfo.getPointer(); } 76ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 77ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Mark the visit as aborted. Intended for use in a void return. 78ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \param I The instruction which caused the visit to abort, if available. 79ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void setAborted(Instruction *I = 0) { 80ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth AbortedInfo.setInt(true); 81ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth AbortedInfo.setPointer(I); 82ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 83ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 84ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Mark the pointer as escaped. Intended for use in a void return. 85ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \param I The instruction which escapes the pointer, if available. 86ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void setEscaped(Instruction *I = 0) { 87ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth EscapedInfo.setInt(true); 88ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth EscapedInfo.setPointer(I); 89ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 90ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 91ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Mark the pointer as escaped, and the visit as aborted. Intended 92ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// for use in a void return. 93ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \param I The instruction which both escapes the pointer and aborts the 94ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// visit, if available. 95ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void setEscapedAndAborted(Instruction *I = 0) { 96ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth setEscaped(I); 97ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth setAborted(I); 98ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 99ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 100ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth private: 101ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PointerIntPair<Instruction *, 1, bool> AbortedInfo, EscapedInfo; 102ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth }; 103ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 104ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthprotected: 105ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth const DataLayout &DL; 106ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 107ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \name Visitation infrastructure 108ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// @{ 109ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 110ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief The info collected about the pointer being visited thus far. 111ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PtrInfo PI; 112ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 113ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief A struct of the data needed to visit a particular use. 114ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// 115ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// This is used to maintain a worklist fo to-visit uses. This is used to 116ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// make the visit be iterative rather than recursive. 117ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth struct UseToVisit { 118ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth typedef PointerIntPair<Use *, 1, bool> UseAndIsOffsetKnownPair; 119ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth UseAndIsOffsetKnownPair UseAndIsOffsetKnown; 120ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth APInt Offset; 121ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth }; 122ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 123ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief The worklist of to-visit uses. 124ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth SmallVector<UseToVisit, 8> Worklist; 125ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 126ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief A set of visited uses to break cycles in unreachable code. 127ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth SmallPtrSet<Use *, 8> VisitedUses; 128ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 129ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// @} 130ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 131ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 132ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \name Per-visit state 133ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// This state is reset for each instruction visited. 134ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// @{ 135ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 136ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief The use currently being visited. 137ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Use *U; 138ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 139ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief True if we have a known constant offset for the use currently 140ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// being visited. 141ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth bool IsOffsetKnown; 142ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 143ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief The constant offset of the use if that is known. 144ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth APInt Offset; 145ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 146ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// @} 147ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 148ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 149ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// Note that the constructor is protected because this class must be a base 150ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// class, we can't create instances directly of this class. 151ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PtrUseVisitorBase(const DataLayout &DL) : DL(DL) {} 152ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 153ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Enqueue the users of this instruction in the visit worklist. 154ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// 155ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// This will visit the users with the same offset of the current visit 156ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// (including an unknown offset if that is the current state). 157ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void enqueueUsers(Instruction &I); 158ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 159ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Walk the operands of a GEP and adjust the offset as appropriate. 160ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// 161ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// This routine does the heavy lifting of the pointer walk by computing 162ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// offsets and looking through GEPs. 163ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth bool adjustOffsetForGEP(GetElementPtrInst &GEPI); 164ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth}; 165ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth} // end namespace detail 166ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 167ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// \brief A base class for visitors over the uses of a pointer value. 168ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 169ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// Once constructed, a user can call \c visit on a pointer value, and this 170ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// will walk its uses and visit each instruction using an InstVisitor. It also 171ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// provides visit methods which will recurse through any pointer-to-pointer 172ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// transformations such as GEPs and bitcasts. 173ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 174ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// During the visit, the current Use* being visited is available to the 175ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// subclass, as well as the current offset from the original base pointer if 176ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// known. 177ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 178ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// The recursive visit of uses is accomplished with a worklist, so the only 179ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// ordering guarantee is that an instruction is visited before any uses of it 180ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// are visited. Note that this does *not* mean before any of its users are 181ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// visited! This is because users can be visited multiple times due to 182ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// multiple, different uses of pointers derived from the same base. 183ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 184ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// A particular Use will only be visited once, but a User may be visited 185ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// multiple times, once per Use. This visits may notably have different 186ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// offsets. 187ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 188ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// All visit methods on the underlying InstVisitor return a boolean. This 189ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// return short-circuits the visit, stopping it immediately. 190ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// 191ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth/// FIXME: Generalize this for all values rather than just instructions. 192ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthtemplate <typename DerivedT> 193ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthclass PtrUseVisitor : protected InstVisitor<DerivedT>, 194ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth public detail::PtrUseVisitorBase { 195ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth friend class InstVisitor<DerivedT>; 196ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth typedef InstVisitor<DerivedT> Base; 197ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 198ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthpublic: 199ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PtrUseVisitor(const DataLayout &DL) : PtrUseVisitorBase(DL) {} 200ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 201ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \brief Recursively visit the uses of the given pointer. 202ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth /// \returns An info struct about the pointer. See \c PtrInfo for details. 203ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PtrInfo visitPtr(Instruction &I) { 204ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // This must be a pointer type. Get an integer type suitable to hold 205ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // offsets on this pointer. 206ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // FIXME: Support a vector of pointers. 207ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth assert(I.getType()->isPointerTy()); 208ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth IntegerType *IntPtrTy = cast<IntegerType>(DL.getIntPtrType(I.getType())); 209ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth IsOffsetKnown = true; 210ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Offset = APInt(IntPtrTy->getBitWidth(), 0); 211ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PI.reset(); 212ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 213ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // Enqueue the uses of this pointer. 214ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth enqueueUsers(I); 215ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 216ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // Visit all the uses off the worklist until it is empty. 217ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth while (!Worklist.empty()) { 218ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth UseToVisit ToVisit = Worklist.pop_back_val(); 219ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth U = ToVisit.UseAndIsOffsetKnown.getPointer(); 220ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth IsOffsetKnown = ToVisit.UseAndIsOffsetKnown.getInt(); 221ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth if (IsOffsetKnown) 222ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Offset = llvm_move(ToVisit.Offset); 223ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 224ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Instruction *I = cast<Instruction>(U->getUser()); 225ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth static_cast<DerivedT*>(this)->visit(I); 226ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth if (PI.isAborted()) 227ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth break; 228ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 229ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth return PI; 230ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 231ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 232ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruthprotected: 233ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitStoreInst(StoreInst &SI) { 234ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth if (SI.getValueOperand() == U->get()) 235ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PI.setEscaped(&SI); 236ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 237ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 238ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitBitCastInst(BitCastInst &BC) { 239ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth enqueueUsers(BC); 240ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 241ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 242ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitPtrToIntInst(PtrToIntInst &I) { 243ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PI.setEscaped(&I); 244ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 245ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 246ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitGetElementPtrInst(GetElementPtrInst &GEPI) { 247ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth if (GEPI.use_empty()) 248ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth return; 249ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 250ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // If we can't walk the GEP, clear the offset. 251ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth if (!adjustOffsetForGEP(GEPI)) { 252ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth IsOffsetKnown = false; 253ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Offset = APInt(); 254ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 255ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 256ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // Enqueue the users now that the offset has been adjusted. 257ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth enqueueUsers(GEPI); 258ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 259ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 260ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // No-op intrinsics which we know don't escape the pointer to to logic in 261ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // some other function. 262ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitDbgInfoIntrinsic(DbgInfoIntrinsic &I) {} 263ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitMemIntrinsic(MemIntrinsic &I) {} 264ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitIntrinsicInst(IntrinsicInst &II) { 265ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth switch (II.getIntrinsicID()) { 266ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth default: 267ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth return Base::visitIntrinsicInst(II); 268ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 269ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth case Intrinsic::lifetime_start: 270ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth case Intrinsic::lifetime_end: 271ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth return; // No-op intrinsics. 272ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 273ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 274ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 275ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // Generically, arguments to calls and invokes escape the pointer to some 276ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth // other function. Mark that. 277ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth void visitCallSite(CallSite CS) { 278ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth PI.setEscaped(CS.getInstruction()); 279ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth Base::visitCallSite(CS); 280ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth } 281ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth}; 282ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 283ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth} 284ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth 285ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth#endif 286