LLVM  14.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"
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 
33  ItTy OpIt;
35 
36  generic_gep_type_iterator() = default;
37 
38 public:
39  using iterator_category = std::forward_iterator_tag;
40  using value_type = Type *;
41  using difference_type = std::ptrdiff_t;
42  using pointer = value_type *;
43  using reference = value_type &;
44 
47  I.CurTy = Ty;
48  I.OpIt = It;
49  return I;
50  }
51 
54  I.OpIt = It;
55  return I;
56  }
57 
58  bool operator==(const generic_gep_type_iterator &x) const {
59  return OpIt == x.OpIt;
60  }
61 
62  bool operator!=(const generic_gep_type_iterator &x) const {
63  return !operator==(x);
64  }
65 
66  // FIXME: Make this the iterator's operator*() after the 4.0 release.
67  // operator*() had a different meaning in earlier releases, so we're
68  // temporarily not giving this iterator an operator*() to avoid a subtle
69  // semantics break.
70  Type *getIndexedType() const {
71  if (auto *T = CurTy.dyn_cast<Type *>())
72  return T;
73  return CurTy.get<StructType *>()->getTypeAtIndex(getOperand());
74  }
75 
76  Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
77 
79  Type *Ty = getIndexedType();
80  if (auto *ATy = dyn_cast<ArrayType>(Ty))
81  CurTy = ATy->getElementType();
82  else if (auto *VTy = dyn_cast<VectorType>(Ty))
83  CurTy = VTy->getElementType();
84  else
85  CurTy = dyn_cast<StructType>(Ty);
86  ++OpIt;
87  return *this;
88  }
89 
90  generic_gep_type_iterator operator++(int) { // Postincrement
92  ++*this;
93  return tmp;
94  }
95 
96  // All of the below API is for querying properties of the "outer type", i.e.
97  // the type that contains the indexed type. Most of the time this is just
98  // the type that was visited immediately prior to the indexed type, but for
99  // the first element this is an unbounded array of the GEP's source element
100  // type, for which there is no clearly corresponding IR type (we've
101  // historically used a pointer type as the outer type in this case, but
102  // pointers will soon lose their element type).
103  //
104  // FIXME: Most current users of this class are just interested in byte
105  // offsets (a few need to know whether the outer type is a struct because
106  // they are trying to replace a constant with a variable, which is only
107  // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
108  // we should provide a more minimal API here that exposes not much more than
109  // that.
110 
111  bool isStruct() const { return CurTy.is<StructType *>(); }
112  bool isSequential() const { return CurTy.is<Type *>(); }
113 
114  StructType *getStructType() const { return CurTy.get<StructType *>(); }
115 
117  return CurTy.dyn_cast<StructType *>();
118  }
119 };
120 
122 
124  auto *GEPOp = cast<GEPOperator>(GEP);
126  GEPOp->getSourceElementType(),
127  GEP->op_begin() + 1);
128  }
129 
131  return gep_type_iterator::end(GEP->op_end());
132  }
133 
135  auto &GEPOp = cast<GEPOperator>(GEP);
137  GEPOp.getSourceElementType(),
138  GEP.op_begin() + 1);
139  }
140 
142  return gep_type_iterator::end(GEP.op_end());
143  }
144 
145  template<typename T>
146  inline generic_gep_type_iterator<const T *>
148  return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
149  }
150 
151  template<typename T>
152  inline generic_gep_type_iterator<const T *>
153  gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
155  }
156 
157 } // end namespace llvm
158 
159 #endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
llvm::generic_gep_type_iterator::operator++
generic_gep_type_iterator operator++(int)
Definition: GetElementPtrTypeIterator.h:90
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::generic_gep_type_iterator::operator!=
bool operator!=(const generic_gep_type_iterator &x) const
Definition: GetElementPtrTypeIterator.h:62
llvm::generic_gep_type_iterator
Definition: GetElementPtrTypeIterator.h:31
llvm::generic_gep_type_iterator::operator==
bool operator==(const generic_gep_type_iterator &x) const
Definition: GetElementPtrTypeIterator.h:58
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
T
#define T
Definition: Mips16ISelLowering.cpp:341
Operator.h
tmp
alloca< 16 x float >, align 16 %tmp2=alloca< 16 x float >, align 16 store< 16 x float > %A,< 16 x float > *%tmp %s=bitcast< 16 x float > *%tmp to i8 *%s2=bitcast< 16 x float > *%tmp2 to i8 *call void @llvm.memcpy.i64(i8 *%s, i8 *%s2, i64 64, i32 16) %R=load< 16 x float > *%tmp2 ret< 16 x float > %R } declare void @llvm.memcpy.i64(i8 *nocapture, i8 *nocapture, i64, i32) nounwind which compiles to:_foo:subl $140, %esp movaps %xmm3, 112(%esp) movaps %xmm2, 96(%esp) movaps %xmm1, 80(%esp) movaps %xmm0, 64(%esp) movl 60(%esp), %eax movl %eax, 124(%esp) movl 56(%esp), %eax movl %eax, 120(%esp) movl 52(%esp), %eax< many many more 32-bit copies > movaps(%esp), %xmm0 movaps 16(%esp), %xmm1 movaps 32(%esp), %xmm2 movaps 48(%esp), %xmm3 addl $140, %esp ret On Nehalem, it may even be cheaper to just use movups when unaligned than to fall back to lower-granularity chunks. Implement processor-specific optimizations for parity with GCC on these processors. GCC does two optimizations:1. ix86_pad_returns inserts a noop before ret instructions if immediately preceded by a conditional branch or is the target of a jump. 2. ix86_avoid_jump_misspredicts inserts noops in cases where a 16-byte block of code contains more than 3 branches. The first one is done for all AMDs, Core2, and "Generic" The second one is done for:Atom, Pentium Pro, all AMDs, Pentium 4, Nocona, Core 2, and "Generic" Testcase:int x(int a) { return(a &0xf0)> >4 tmp
Definition: README.txt:1347
llvm::gep_type_begin
gep_type_iterator gep_type_begin(const User *GEP)
Definition: GetElementPtrTypeIterator.h:123
llvm::PointerUnion::get
T get() const
Returns the value of the specified pointer type.
Definition: PointerUnion.h:144
llvm::PointerUnion::is
bool is() const
Test if the Union currently holds the type matching T.
Definition: PointerUnion.h:137
llvm::gep_type_end
gep_type_iterator gep_type_end(const User *GEP)
Definition: GetElementPtrTypeIterator.h:130
llvm::generic_gep_type_iterator::iterator_category
std::forward_iterator_tag iterator_category
Definition: GetElementPtrTypeIterator.h:39
llvm::generic_gep_type_iterator::begin
static generic_gep_type_iterator begin(Type *Ty, ItTy It)
Definition: GetElementPtrTypeIterator.h:45
llvm::User
Definition: User.h:44
ItTy
llvm::generic_gep_type_iterator::getOperand
Value * getOperand() const
Definition: GetElementPtrTypeIterator.h:76
llvm::generic_gep_type_iterator::end
static generic_gep_type_iterator end(ItTy It)
Definition: GetElementPtrTypeIterator.h:52
llvm::generic_gep_type_iterator::operator++
generic_gep_type_iterator & operator++()
Definition: GetElementPtrTypeIterator.h:78
llvm::generic_gep_type_iterator::getStructTypeOrNull
StructType * getStructTypeOrNull() const
Definition: GetElementPtrTypeIterator.h:116
llvm::generic_gep_type_iterator::getStructType
StructType * getStructType() const
Definition: GetElementPtrTypeIterator.h:114
llvm::PointerUnion::dyn_cast
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwise returns null.
Definition: PointerUnion.h:151
I
#define I(x, y, z)
Definition: MD5.cpp:58
ArrayRef.h
llvm::generic_gep_type_iterator::getIndexedType
Type * getIndexedType() const
Definition: GetElementPtrTypeIterator.h:70
PointerUnion.h
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::StructType
Class to represent struct types.
Definition: DerivedTypes.h:213
llvm::generic_gep_type_iterator::isSequential
bool isSequential() const
Definition: GetElementPtrTypeIterator.h:112
llvm::PointerUnion
A discriminated union of two or more pointer types, with the discriminator in the low bit of the poin...
Definition: PointerUnion.h:107
Casting.h
x
TODO unsigned x
Definition: README.txt:10
User.h
llvm::generic_gep_type_iterator::isStruct
bool isStruct() const
Definition: GetElementPtrTypeIterator.h:111
DerivedTypes.h
llvm::generic_gep_type_iterator::difference_type
std::ptrdiff_t difference_type
Definition: GetElementPtrTypeIterator.h:41
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:172
llvm::Value
LLVM Value Representation.
Definition: Value.h:74