LLVM 22.0.0git
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"
19#include "llvm/IR/DataLayout.h"
21#include "llvm/IR/Operator.h"
22#include "llvm/IR/User.h"
24#include <cstddef>
25#include <cstdint>
26#include <iterator>
27
28namespace llvm {
29
30template <typename ItTy = User::const_op_iterator>
31class generic_gep_type_iterator {
32
33 ItTy OpIt;
34 // We use two different mechanisms to store the type a GEP index applies to.
35 // In some cases, we need to know the outer aggregate type the index is
36 // applied within, e.g. a struct. In such cases, we store the aggregate type
37 // in the iterator, and derive the element type on the fly.
38 //
39 // However, this is not always possible, because for the outermost index there
40 // is no containing type. In such cases, or if the containing type is not
41 // relevant, e.g. for arrays, the element type is stored as Type* in CurTy.
42 //
43 // If CurTy contains a Type* value, this does not imply anything about the
44 // type itself, because it is the element type and not the outer type.
45 // In particular, Type* can be a struct type.
46 //
47 // Consider this example:
48 //
49 // %my.struct = type { i32, [ 4 x float ] }
50 // [...]
51 // %gep = getelementptr %my.struct, ptr %ptr, i32 10, i32 1, 32 3
52 //
53 // Iterating over the indices of this GEP, CurTy will contain the following
54 // values:
55 // * i32 10: The outer index always operates on the GEP value type.
56 // CurTy contains a Type* pointing at `%my.struct`.
57 // * i32 1: This index is within a struct.
58 // CurTy contains a StructType* pointing at `%my.struct`.
59 // * i32 3: This index is within an array. We reuse the "flat" indexing
60 // for arrays which is also used in the top level GEP index.
61 // CurTy contains a Type* pointing at `float`.
62 //
63 // Vectors are handled separately because the layout of vectors is different
64 // for overaligned elements: Vectors are always bit-packed, whereas arrays
65 // respect ABI alignment of the elements.
67
68 generic_gep_type_iterator() = default;
69
70public:
71 using iterator_category = std::forward_iterator_tag;
72 using value_type = Type *;
73 using difference_type = std::ptrdiff_t;
76
77 static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
78 generic_gep_type_iterator I;
79 I.CurTy = Ty;
80 I.OpIt = It;
81 return I;
82 }
83
84 static generic_gep_type_iterator end(ItTy It) {
85 generic_gep_type_iterator I;
86 I.OpIt = It;
87 return I;
88 }
89
90 bool operator==(const generic_gep_type_iterator &x) const {
91 return OpIt == x.OpIt;
92 }
93
94 bool operator!=(const generic_gep_type_iterator &x) const {
95 return !operator==(x);
96 }
97
98 // FIXME: Make this the iterator's operator*() after the 4.0 release.
99 // operator*() had a different meaning in earlier releases, so we're
100 // temporarily not giving this iterator an operator*() to avoid a subtle
101 // semantics break.
103 if (auto *T = dyn_cast_if_present<Type *>(CurTy))
104 return T;
105 if (auto *VT = dyn_cast_if_present<VectorType *>(CurTy))
106 return VT->getElementType();
107 return cast<StructType *>(CurTy)->getTypeAtIndex(getOperand());
108 }
109
110 Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
111
112 generic_gep_type_iterator &operator++() { // Preincrement
113 Type *Ty = getIndexedType();
114 if (auto *ATy = dyn_cast<ArrayType>(Ty))
115 CurTy = ATy->getElementType();
116 else if (auto *VTy = dyn_cast<VectorType>(Ty))
117 CurTy = VTy;
118 else
119 CurTy = dyn_cast<StructType>(Ty);
120 ++OpIt;
121 return *this;
122 }
123
124 generic_gep_type_iterator operator++(int) { // Postincrement
125 generic_gep_type_iterator tmp = *this;
126 ++*this;
127 return tmp;
128 }
129
130 // All of the below API is for querying properties of the "outer type", i.e.
131 // the type that contains the indexed type. Most of the time this is just
132 // the type that was visited immediately prior to the indexed type, but for
133 // the first element this is an unbounded array of the GEP's source element
134 // type, for which there is no clearly corresponding IR type (we've
135 // historically used a pointer type as the outer type in this case, but
136 // pointers will soon lose their element type).
137 //
138 // FIXME: Most current users of this class are just interested in byte
139 // offsets (a few need to know whether the outer type is a struct because
140 // they are trying to replace a constant with a variable, which is only
141 // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
142 // we should provide a more minimal API here that exposes not much more than
143 // that.
144
145 bool isStruct() const { return isa<StructType *>(CurTy); }
146 bool isVector() const { return isa<VectorType *>(CurTy); }
147 bool isSequential() const { return !isStruct(); }
148
149 // For sequential GEP indices (all except those into structs), the index value
150 // can be translated into a byte offset by multiplying with an element stride.
151 // This function returns this stride, which both depends on the element type,
152 // and the containing aggregate type, as vectors always tightly bit-pack their
153 // elements.
156 Type *ElemTy = getIndexedType();
157 if (isVector()) {
158 assert(DL.typeSizeEqualsStoreSize(ElemTy) && "Not byte-addressable");
159 return DL.getTypeStoreSize(ElemTy);
160 }
161 return DL.getTypeAllocSize(ElemTy);
162 }
163
164 StructType *getStructType() const { return cast<StructType *>(CurTy); }
165
169};
170
172
174 auto *GEPOp = cast<GEPOperator>(GEP);
176 GEPOp->getSourceElementType(),
177 GEP->op_begin() + 1);
178 }
179
181 return gep_type_iterator::end(GEP->op_end());
182 }
183
185 auto &GEPOp = cast<GEPOperator>(GEP);
187 GEPOp.getSourceElementType(),
188 GEP.op_begin() + 1);
189 }
190
192 return gep_type_iterator::end(GEP.op_end());
193 }
194
195 template<typename T>
196 inline generic_gep_type_iterator<const T *>
200
201 template<typename T>
202 inline generic_gep_type_iterator<const T *>
206
207} // end namespace llvm
208
209#endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Hexagon Common GEP
#define I(x, y, z)
Definition MD5.cpp:58
#define T
This file defines the PointerUnion class, which is a discriminated union of pointer types.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:63
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Class to represent struct types.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:45
LLVM Value Representation.
Definition Value.h:75
static generic_gep_type_iterator begin(Type *Ty, ItTy It)
bool operator==(const generic_gep_type_iterator &x) const
generic_gep_type_iterator & operator++()
static generic_gep_type_iterator end(ItTy It)
std::forward_iterator_tag iterator_category
TypeSize getSequentialElementStride(const DataLayout &DL) const
generic_gep_type_iterator operator++(int)
bool operator!=(const generic_gep_type_iterator &x) const
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
auto dyn_cast_if_present(const Y &Val)
dyn_cast_if_present<X> - Functionally identical to dyn_cast, except that a null (or none in the case ...
Definition Casting.h:738
gep_type_iterator gep_type_end(const User *GEP)
generic_gep_type_iterator<> gep_type_iterator
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:565
gep_type_iterator gep_type_begin(const User *GEP)