LLVM  9.0.0svn
GetElementPtrTypeIterator.h
Go to the documentation of this file.
1 //===- GetElementPtrTypeIterator.h ------------------------------*- 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 // This file implements an iterator for walking through the types indexed by
10 // getelementptr instructions.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
15 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
16 
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/PointerUnion.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/Operator.h"
21 #include "llvm/IR/User.h"
22 #include "llvm/Support/Casting.h"
23 #include <cassert>
24 #include <cstddef>
25 #include <cstdint>
26 #include <iterator>
27 
28 namespace llvm {
29 
30  template<typename ItTy = User::const_op_iterator>
32  : public std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t> {
33  using super = std::iterator<std::forward_iterator_tag, Type *, ptrdiff_t>;
34 
35  ItTy OpIt;
37  enum : uint64_t { Unbounded = -1ull };
38  uint64_t NumElements = Unbounded;
39 
40  generic_gep_type_iterator() = default;
41 
42  public:
45  I.CurTy = Ty;
46  I.OpIt = It;
47  return I;
48  }
49 
52  I.OpIt = It;
53  return I;
54  }
55 
56  bool operator==(const generic_gep_type_iterator& x) const {
57  return OpIt == x.OpIt;
58  }
59 
60  bool operator!=(const generic_gep_type_iterator& x) const {
61  return !operator==(x);
62  }
63 
64  // FIXME: Make this the iterator's operator*() after the 4.0 release.
65  // operator*() had a different meaning in earlier releases, so we're
66  // temporarily not giving this iterator an operator*() to avoid a subtle
67  // semantics break.
68  Type *getIndexedType() const {
69  if (auto *T = CurTy.dyn_cast<Type *>())
70  return T;
71  return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
72  }
73 
74  Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
75 
77  Type *Ty = getIndexedType();
78  if (auto *STy = dyn_cast<SequentialType>(Ty)) {
79  CurTy = STy->getElementType();
80  NumElements = STy->getNumElements();
81  } else
82  CurTy = dyn_cast<StructType>(Ty);
83  ++OpIt;
84  return *this;
85  }
86 
87  generic_gep_type_iterator operator++(int) { // Postincrement
88  generic_gep_type_iterator tmp = *this; ++*this; return tmp;
89  }
90 
91  // All of the below API is for querying properties of the "outer type", i.e.
92  // the type that contains the indexed type. Most of the time this is just
93  // the type that was visited immediately prior to the indexed type, but for
94  // the first element this is an unbounded array of the GEP's source element
95  // type, for which there is no clearly corresponding IR type (we've
96  // historically used a pointer type as the outer type in this case, but
97  // pointers will soon lose their element type).
98  //
99  // FIXME: Most current users of this class are just interested in byte
100  // offsets (a few need to know whether the outer type is a struct because
101  // they are trying to replace a constant with a variable, which is only
102  // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
103  // we should provide a more minimal API here that exposes not much more than
104  // that.
105 
106  bool isStruct() const { return CurTy.is<StructType *>(); }
107  bool isSequential() const { return CurTy.is<Type *>(); }
108 
109  StructType *getStructType() const { return CurTy.get<StructType *>(); }
110 
112  return CurTy.dyn_cast<StructType *>();
113  }
114 
115  bool isBoundedSequential() const {
116  return isSequential() && NumElements != Unbounded;
117  }
118 
119  uint64_t getSequentialNumElements() const {
121  return NumElements;
122  }
123  };
124 
126 
128  auto *GEPOp = cast<GEPOperator>(GEP);
130  GEPOp->getSourceElementType(),
131  GEP->op_begin() + 1);
132  }
133 
135  return gep_type_iterator::end(GEP->op_end());
136  }
137 
139  auto &GEPOp = cast<GEPOperator>(GEP);
141  GEPOp.getSourceElementType(),
142  GEP.op_begin() + 1);
143  }
144 
146  return gep_type_iterator::end(GEP.op_end());
147  }
148 
149  template<typename T>
153  }
154 
155  template<typename T>
157  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
159  }
160 
161 } // end namespace llvm
162 
163 #endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
This class represents lattice values for constants.
Definition: AllocatorList.h:23
iterator begin() const
Definition: ArrayRef.h:136
gep_type_iterator gep_type_end(const User *GEP)
Hexagon Common GEP
op_iterator op_begin()
Definition: User.h:229
Class to represent struct types.
Definition: DerivedTypes.h:232
#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:32
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:231
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:141
static generic_gep_type_iterator begin(Type *Ty, ItTy It)
iterator end() const
Definition: ArrayRef.h:137
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:322
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:134
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:72
int is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:122
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:86
gep_type_iterator gep_type_begin(const User *GEP)