Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:00

0001 //===- GetElementPtrTypeIterator.h ------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file implements an iterator for walking through the types indexed by
0010 // getelementptr instructions.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
0015 #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H
0016 
0017 #include "llvm/ADT/ArrayRef.h"
0018 #include "llvm/ADT/PointerUnion.h"
0019 #include "llvm/IR/DataLayout.h"
0020 #include "llvm/IR/DerivedTypes.h"
0021 #include "llvm/IR/Operator.h"
0022 #include "llvm/IR/User.h"
0023 #include "llvm/Support/Casting.h"
0024 #include <cstddef>
0025 #include <cstdint>
0026 #include <iterator>
0027 
0028 namespace llvm {
0029 
0030 template <typename ItTy = User::const_op_iterator>
0031 class generic_gep_type_iterator {
0032 
0033   ItTy OpIt;
0034   // We use two different mechanisms to store the type a GEP index applies to.
0035   // In some cases, we need to know the outer aggregate type the index is
0036   // applied within, e.g. a struct. In such cases, we store the aggregate type
0037   // in the iterator, and derive the element type on the fly.
0038   //
0039   // However, this is not always possible, because for the outermost index there
0040   // is no containing type. In such cases, or if the containing type is not
0041   // relevant, e.g. for arrays, the element type is stored as Type* in CurTy.
0042   //
0043   // If CurTy contains a Type* value, this does not imply anything about the
0044   // type itself, because it is the element type and not the outer type.
0045   // In particular, Type* can be a struct type.
0046   //
0047   // Consider this example:
0048   //
0049   //    %my.struct = type { i32, [ 4 x float ] }
0050   //    [...]
0051   //    %gep = getelementptr %my.struct, ptr %ptr, i32 10, i32 1, 32 3
0052   //
0053   // Iterating over the indices of this GEP, CurTy will contain the following
0054   // values:
0055   //    * i32 10: The outer index always operates on the GEP value type.
0056   //              CurTy contains a Type*       pointing at `%my.struct`.
0057   //    * i32 1:  This index is within a struct.
0058   //              CurTy contains a StructType* pointing at `%my.struct`.
0059   //    * i32 3:  This index is within an array. We reuse the "flat" indexing
0060   //              for arrays which is also used in the top level GEP index.
0061   //              CurTy contains a Type*       pointing at `float`.
0062   //
0063   // Vectors are handled separately because the layout of vectors is different
0064   // for overaligned elements: Vectors are always bit-packed, whereas arrays
0065   // respect ABI alignment of the elements.
0066   PointerUnion<StructType *, VectorType *, Type *> CurTy;
0067 
0068   generic_gep_type_iterator() = default;
0069 
0070 public:
0071   using iterator_category = std::forward_iterator_tag;
0072   using value_type = Type *;
0073   using difference_type = std::ptrdiff_t;
0074   using pointer = value_type *;
0075   using reference = value_type &;
0076 
0077   static generic_gep_type_iterator begin(Type *Ty, ItTy It) {
0078     generic_gep_type_iterator I;
0079     I.CurTy = Ty;
0080     I.OpIt = It;
0081     return I;
0082   }
0083 
0084   static generic_gep_type_iterator end(ItTy It) {
0085     generic_gep_type_iterator I;
0086     I.OpIt = It;
0087     return I;
0088   }
0089 
0090   bool operator==(const generic_gep_type_iterator &x) const {
0091     return OpIt == x.OpIt;
0092   }
0093 
0094   bool operator!=(const generic_gep_type_iterator &x) const {
0095     return !operator==(x);
0096   }
0097 
0098   // FIXME: Make this the iterator's operator*() after the 4.0 release.
0099   // operator*() had a different meaning in earlier releases, so we're
0100   // temporarily not giving this iterator an operator*() to avoid a subtle
0101   // semantics break.
0102   Type *getIndexedType() const {
0103     if (auto *T = dyn_cast_if_present<Type *>(CurTy))
0104       return T;
0105     if (auto *VT = dyn_cast_if_present<VectorType *>(CurTy))
0106       return VT->getElementType();
0107     return cast<StructType *>(CurTy)->getTypeAtIndex(getOperand());
0108   }
0109 
0110   Value *getOperand() const { return const_cast<Value *>(&**OpIt); }
0111 
0112   generic_gep_type_iterator &operator++() { // Preincrement
0113     Type *Ty = getIndexedType();
0114     if (auto *ATy = dyn_cast<ArrayType>(Ty))
0115       CurTy = ATy->getElementType();
0116     else if (auto *VTy = dyn_cast<VectorType>(Ty))
0117       CurTy = VTy;
0118     else
0119       CurTy = dyn_cast<StructType>(Ty);
0120     ++OpIt;
0121     return *this;
0122   }
0123 
0124   generic_gep_type_iterator operator++(int) { // Postincrement
0125     generic_gep_type_iterator tmp = *this;
0126     ++*this;
0127     return tmp;
0128   }
0129 
0130   // All of the below API is for querying properties of the "outer type", i.e.
0131   // the type that contains the indexed type. Most of the time this is just
0132   // the type that was visited immediately prior to the indexed type, but for
0133   // the first element this is an unbounded array of the GEP's source element
0134   // type, for which there is no clearly corresponding IR type (we've
0135   // historically used a pointer type as the outer type in this case, but
0136   // pointers will soon lose their element type).
0137   //
0138   // FIXME: Most current users of this class are just interested in byte
0139   // offsets (a few need to know whether the outer type is a struct because
0140   // they are trying to replace a constant with a variable, which is only
0141   // legal for arrays, e.g. canReplaceOperandWithVariable in SimplifyCFG.cpp);
0142   // we should provide a more minimal API here that exposes not much more than
0143   // that.
0144 
0145   bool isStruct() const { return isa<StructType *>(CurTy); }
0146   bool isVector() const { return isa<VectorType *>(CurTy); }
0147   bool isSequential() const { return !isStruct(); }
0148 
0149   // For sequential GEP indices (all except those into structs), the index value
0150   // can be translated into a byte offset by multiplying with an element stride.
0151   // This function returns this stride, which both depends on the element type,
0152   // and the containing aggregate type, as vectors always tightly bit-pack their
0153   // elements.
0154   TypeSize getSequentialElementStride(const DataLayout &DL) const {
0155     assert(isSequential());
0156     Type *ElemTy = getIndexedType();
0157     if (isVector()) {
0158       assert(DL.typeSizeEqualsStoreSize(ElemTy) && "Not byte-addressable");
0159       return DL.getTypeStoreSize(ElemTy);
0160     }
0161     return DL.getTypeAllocSize(ElemTy);
0162   }
0163 
0164   StructType *getStructType() const { return cast<StructType *>(CurTy); }
0165 
0166   StructType *getStructTypeOrNull() const {
0167     return dyn_cast_if_present<StructType *>(CurTy);
0168   }
0169 };
0170 
0171   using gep_type_iterator = generic_gep_type_iterator<>;
0172 
0173   inline gep_type_iterator gep_type_begin(const User *GEP) {
0174     auto *GEPOp = cast<GEPOperator>(GEP);
0175     return gep_type_iterator::begin(
0176         GEPOp->getSourceElementType(),
0177         GEP->op_begin() + 1);
0178   }
0179 
0180   inline gep_type_iterator gep_type_end(const User *GEP) {
0181     return gep_type_iterator::end(GEP->op_end());
0182   }
0183 
0184   inline gep_type_iterator gep_type_begin(const User &GEP) {
0185     auto &GEPOp = cast<GEPOperator>(GEP);
0186     return gep_type_iterator::begin(
0187         GEPOp.getSourceElementType(),
0188         GEP.op_begin() + 1);
0189   }
0190 
0191   inline gep_type_iterator gep_type_end(const User &GEP) {
0192     return gep_type_iterator::end(GEP.op_end());
0193   }
0194 
0195   template<typename T>
0196   inline generic_gep_type_iterator<const T *>
0197   gep_type_begin(Type *Op0, ArrayRef<T> A) {
0198     return generic_gep_type_iterator<const T *>::begin(Op0, A.begin());
0199   }
0200 
0201   template<typename T>
0202   inline generic_gep_type_iterator<const T *>
0203   gep_type_end(Type * /*Op0*/, ArrayRef<T> A) {
0204     return generic_gep_type_iterator<const T *>::end(A.end());
0205   }
0206 
0207 } // end namespace llvm
0208 
0209 #endif // LLVM_IR_GETELEMENTPTRTYPEITERATOR_H