LLVM  6.0.0svn
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 <cassert>
25 #include <cstddef>
26 #include <cstdint>
27 #include <iterator>
28 
29 namespace llvm {
30 
31  template<typename ItTy = User::const_op_iterator>
33  : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
34  using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
35 
36  ItTy OpIt;
38  enum : uint64_t { Unbounded = -1ull };
39  uint64_t NumElements = Unbounded;
40 
41  generic_gep_type_iterator() = default;
42 
43  public:
44  static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
46  I.CurTy = Ty;
47  I.OpIt = It;
48  return I;
49  }
50 
51  static generic_gep_type_iterator end(ItTy It) {
53  I.OpIt = It;
54  return I;
55  }
56 
57  bool operator==(const generic_gep_type_iterator& x) const {
58  return OpIt == x.OpIt;
59  }
60 
61  bool operator!=(const generic_gep_type_iterator& x) const {
62  return !operator==(x);
63  }
64 
65  // FIXME: Make this the iterator's operator*() after the 4.0 release.
66  // operator*() had a different meaning in earlier releases, so we're
67  // temporarily not giving this iterator an operator*() to avoid a subtle
68  // semantics break.
69  Type *getIndexedType() const {
70  if (auto *T = CurTy.dyn_cast<Type *>())
71  return T;
72  return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
73  }
74 
75  Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
76 
78  Type *Ty = getIndexedType();
79  if (auto *STy = dyn_cast<SequentialType>(Ty)) {
80  CurTy = STy->getElementType();
81  NumElements = STy->getNumElements();
82  } else
83  CurTy = dyn_cast<StructType>(Ty);
84  ++OpIt;
85  return *this;
86  }
87 
88  generic_gep_type_iterator operator++(int) { // Postincrement
89  generic_gep_type_iterator tmp = *this; ++*this; return tmp;
90  }
91 
92  // All of the below API is for querying properties of the "outer type", i.e.
93  // the type that contains the indexed type. Most of the time this is just
94  // the type that was visited immediately prior to the indexed type, but for
95  // the first element this is an unbounded array of the GEP's source element
96  // type, for which there is no clearly corresponding IR type (we've
97  // historically used a pointer type as the outer type in this case, but
98  // pointers will soon lose their element type).
99  //
100  // FIXME: Most current users of this class are just interested in byte
101  // offsets (a few need to know whether the outer type is a struct because
102  // they are trying to replace a constant with a variable, which is only
103  // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
104  // we should provide a more minimal API here that exposes not much more than
105  // that.
106 
107  bool isStruct() const { return CurTy.is<StructType *>(); }
108  bool isSequential() const { return CurTy.is<Type *>(); }
109 
110  StructType *getStructType() const { return CurTy.get<StructType *>(); }
111 
113  return CurTy.dyn_cast<StructType *>();
114  }
115 
116  bool isBoundedSequential() const {
117  return isSequential() && NumElements != Unbounded;
118  }
119 
120  uint64_t getSequentialNumElements() const {
122  return NumElements;
123  }
124  };
125 
127 
129  auto *GEPOp = cast<GEPOperator>(GEP);
131  GEPOp->getSourceElementType(),
132  GEP->op_begin() + 1);
133  }
134 
136  return gep_type_iterator::end(GEP->op_end());
137  }
138 
140  auto &GEPOp = cast<GEPOperator>(GEP);
142  GEPOp.getSourceElementType(),
143  GEP.op_begin() + 1);
144  }
145 
147  return gep_type_iterator::end(GEP.op_end());
148  }
149 
150  template<typename T>
154  }
155 
156  template<typename T>
158  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
160  }
161 
162 } // end namespace llvm
163 
164 #endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
iterator begin() const
Definition: ArrayRef.h:137
gep_type_iterator gep_type_end(const User *GEP)
Hexagon Common GEP
op_iterator op_begin()
Definition: User.h:214
Class to represent struct types.
Definition: DerivedTypes.h:201
#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:46
op_iterator op_end()
Definition: User.h:216
bool operator!=(const generic_gep_type_iterator &x) const
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwises returns null...
Definition: PointerUnion.h:142
static generic_gep_type_iterator begin(Type *Ty, ItTy It)
iterator end() const
Definition: ArrayRef.h:138
generic_gep_type_iterator operator++(int)
#define I(x, y, z)
Definition: MD5.cpp:58
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:323
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:135
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:73
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:123
bool operator==(const generic_gep_type_iterator &x) const
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)