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"
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstVisitor.h"
300b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IntrinsicInst.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:
51dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    PtrInfo() : AbortedInfo(nullptr, false), EscapedInfo(nullptr, false) {}
52ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth
53ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth    /// \brief Reset the pointer info, clearing all state.
54ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth    void reset() {
55dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      AbortedInfo.setPointer(nullptr);
56ed90ed077a58d6eff6aede206273ae0aeefa3a94Chandler Carruth      AbortedInfo.setInt(false);
57dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      EscapedInfo.setPointer(nullptr);
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.
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void setAborted(Instruction *I = nullptr) {
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.
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void setEscaped(Instruction *I = nullptr) {
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.
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void setEscapedAndAborted(Instruction *I = nullptr) {
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)
22236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Offset = std::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