LLVM  4.0.0
GetElementPtrTypeIterator.h
Go to the documentation of this file.
1 //===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements an iterator for walking through the types indexed by
11 // getelementptr instructions.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
16 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
17 
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/PointerUnion.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/Operator.h"
22 #include "llvm/IR/User.h"
23 #include "llvm/Support/Casting.h"
24 #include <cstddef>
25 #include <iterator>
26 
27 namespace llvm {
28 
29  template<typename ItTy = User::const_op_iterator>
31  : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
32  typedef std::iterator<std::forward_iterator_tag,
33  Type *, ptrdiff_t> super;
34 
35  ItTy OpIt;
37  enum : uint64_t { Unbounded = -1ull };
38  uint64_t NumElements = Unbounded;
39  generic_gep_type_iterator() = default;
40 
41  public:
42  static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
44  I.CurTy = Ty;
45  I.OpIt = It;
46  return I;
47  }
48 
49  static generic_gep_type_iterator end(ItTy It) {
51  I.OpIt = It;
52  return I;
53  }
54 
55  bool operator==(const generic_gep_type_iterator& x) const {
56  return OpIt == x.OpIt;
57  }
58 
59  bool operator!=(const generic_gep_type_iterator& x) const {
60  return !operator==(x);
61  }
62 
63  // FIXME: Make this the iterator's operator*() after the 4.0 release.
64  // operator*() had a different meaning in earlier releases, so we're
65  // temporarily not giving this iterator an operator*() to avoid a subtle
66  // semantics break.
67  Type *getIndexedType() const {
68  if (auto *T = CurTy.dyn_cast<Type *>())
69  return T;
70  return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
71  }
72 
73  Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
74 
76  Type *Ty = getIndexedType();
77  if (auto *STy = dyn_cast<SequentialType>(Ty)) {
78  CurTy = STy->getElementType();
79  NumElements = STy->getNumElements();
80  } else
81  CurTy = dyn_cast<StructType>(Ty);
82  ++OpIt;
83  return *this;
84  }
85 
86  generic_gep_type_iterator operator++(int) { // Postincrement
87  generic_gep_type_iterator tmp = *this; ++*this; return tmp;
88  }
89 
90  // All of the below API is for querying properties of the "outer type", i.e.
91  // the type that contains the indexed type. Most of the time this is just
92  // the type that was visited immediately prior to the indexed type, but for
93  // the first element this is an unbounded array of the GEP's source element
94  // type, for which there is no clearly corresponding IR type (we've
95  // historically used a pointer type as the outer type in this case, but
96  // pointers will soon lose their element type).
97  //
98  // FIXME: Most current users of this class are just interested in byte
99  // offsets (a few need to know whether the outer type is a struct because
100  // they are trying to replace a constant with a variable, which is only
101  // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
102  // we should provide a more minimal API here that exposes not much more than
103  // that.
104 
105  bool isStruct() const { return CurTy.is<StructType *>(); }
106  bool isSequential() const { return CurTy.is<Type *>(); }
107 
108  StructType *getStructType() const { return CurTy.get<StructType *>(); }
109 
111  return CurTy.dyn_cast<StructType *>();
112  }
113 
114  bool isBoundedSequential() const {
115  return isSequential() && NumElements != Unbounded;
116  }
117 
118  uint64_t getSequentialNumElements() const {
120  return NumElements;
121  }
122  };
123 
125 
127  auto *GEPOp = cast<GEPOperator>(GEP);
129  GEPOp->getSourceElementType(),
130  GEP->op_begin() + 1);
131  }
132 
134  return gep_type_iterator::end(GEP->op_end());
135  }
136 
138  auto &GEPOp = cast<GEPOperator>(GEP);
140  GEPOp.getSourceElementType(),
141  GEP.op_begin() + 1);
142  }
143 
145  return gep_type_iterator::end(GEP.op_end());
146  }
147 
148  template<typename T>
149  inline generic_gep_type_iterator<const T *>
152  }
153 
154  template<typename T>
155  inline generic_gep_type_iterator<const T *>
158  }
159 
160 } // end namespace llvm
161 
162 #endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
generic_gep_type_iterator gep_type_iterator
iterator end() const
Definition: ArrayRef.h:130
gep_type_iterator gep_type_end(const User *GEP)
Hexagon Common GEP
op_iterator op_begin()
Definition: User.h:205
Class to represent struct types.
Definition: DerivedTypes.h:199
bool operator==(const generic_gep_type_iterator &x) const
#define T
generic_gep_type_iterator & operator++()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static generic_gep_type_iterator end(ItTy It)
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
op_iterator op_end()
Definition: User.h:207
iterator begin() const
Definition: ArrayRef.h:129
static generic_gep_type_iterator begin(Type *Ty, ItTy It)
generic_gep_type_iterator operator++(int)
#define I(x, y, z)
Definition: MD5.cpp:54
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Definition: Casting.h:287
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:71
bool operator!=(const generic_gep_type_iterator &x) const
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
A discriminated union of two pointer types, with the discriminator in the low bit of the pointer...
Definition: PointerUnion.h:87
gep_type_iterator gep_type_begin(const User *GEP)