From bd75a9292e761dcab32855e322d9985d7d787d1e Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Thu, 21 May 2015 21:12:43 +0000 Subject: [PATCH] [opaque pointer type] Allow gep_type_iterator to work with the pointee type from the GEP instruction The raw non-instruction/constant form of this is still relying on being able to access the pointee type from a pointer type - those will be cleaned up later. For now, just focus on the cases where the pointee type is easily accessible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@237958 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/GetElementPtrTypeIterator.h | 50 ++++++++++++++++----- include/llvm/IR/Operator.h | 32 +------------ lib/IR/Constants.cpp | 30 +++++++++++++ lib/Target/AArch64/AArch64ISelLowering.cpp | 1 + lib/Target/Mips/MipsFastISel.cpp | 1 + 5 files changed, 71 insertions(+), 43 deletions(-) diff --git a/include/llvm/IR/GetElementPtrTypeIterator.h b/include/llvm/IR/GetElementPtrTypeIterator.h index dcf8e64dbb2..6bba0ae29e9 100644 --- a/include/llvm/IR/GetElementPtrTypeIterator.h +++ b/include/llvm/IR/GetElementPtrTypeIterator.h @@ -16,7 +16,9 @@ #define LLVM_IR_GETELEMENTPTRTYPEITERATOR_H #include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/User.h" +#include "llvm/ADT/PointerIntPair.h" namespace llvm { template @@ -26,19 +28,28 @@ namespace llvm { Type *, ptrdiff_t> super; ItTy OpIt; - Type *CurTy; + PointerIntPair CurTy; + unsigned AddrSpace; generic_gep_type_iterator() {} public: static generic_gep_type_iterator begin(Type *Ty, ItTy It) { generic_gep_type_iterator I; - I.CurTy = Ty; + I.CurTy.setPointer(Ty); + I.OpIt = It; + return I; + } + static generic_gep_type_iterator begin(Type *Ty, unsigned AddrSpace, + ItTy It) { + generic_gep_type_iterator I; + I.CurTy.setPointer(Ty); + I.CurTy.setInt(true); + I.AddrSpace = AddrSpace; I.OpIt = It; return I; } static generic_gep_type_iterator end(ItTy It) { generic_gep_type_iterator I; - I.CurTy = nullptr; I.OpIt = It; return I; } @@ -51,11 +62,15 @@ namespace llvm { } Type *operator*() const { - return CurTy; + if (CurTy.getInt()) + return CurTy.getPointer()->getPointerTo(AddrSpace); + return CurTy.getPointer(); } Type *getIndexedType() const { - CompositeType *CT = cast(CurTy); + if (CurTy.getInt()) + return CurTy.getPointer(); + CompositeType *CT = cast(CurTy.getPointer()); return CT->getTypeAtIndex(getOperand()); } @@ -66,10 +81,13 @@ namespace llvm { Value *getOperand() const { return *OpIt; } generic_gep_type_iterator& operator++() { // Preincrement - if (CompositeType *CT = dyn_cast(CurTy)) { - CurTy = CT->getTypeAtIndex(getOperand()); + if (CurTy.getInt()) { + CurTy.setInt(false); + } else if (CompositeType *CT = + dyn_cast(CurTy.getPointer())) { + CurTy.setPointer(CT->getTypeAtIndex(getOperand())); } else { - CurTy = nullptr; + CurTy.setPointer(nullptr); } ++OpIt; return *this; @@ -83,15 +101,23 @@ namespace llvm { typedef generic_gep_type_iterator<> gep_type_iterator; inline gep_type_iterator gep_type_begin(const User *GEP) { - return gep_type_iterator::begin - (GEP->getOperand(0)->getType()->getScalarType(), GEP->op_begin()+1); + auto *GEPOp = cast(GEP); + return gep_type_iterator::begin( + GEPOp->getSourceElementType(), + cast(GEPOp->getPointerOperandType()->getScalarType()) + ->getAddressSpace(), + GEP->op_begin() + 1); } inline gep_type_iterator gep_type_end(const User *GEP) { return gep_type_iterator::end(GEP->op_end()); } inline gep_type_iterator gep_type_begin(const User &GEP) { - return gep_type_iterator::begin - (GEP.getOperand(0)->getType()->getScalarType(), GEP.op_begin()+1); + auto &GEPOp = cast(GEP); + return gep_type_iterator::begin( + GEPOp.getSourceElementType(), + cast(GEPOp.getPointerOperandType()->getScalarType()) + ->getAddressSpace(), + GEP.op_begin() + 1); } inline gep_type_iterator gep_type_end(const User &GEP) { return gep_type_iterator::end(GEP.op_end()); diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 81eec413c84..1b9102ecc7e 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -18,7 +18,6 @@ #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Type.h" @@ -447,36 +446,7 @@ public: /// undefined (it is *not* preserved!). The APInt passed into this routine /// must be at exactly as wide as the IntPtr type for the address space of the /// base GEP pointer. - bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const { - assert(Offset.getBitWidth() == - DL.getPointerSizeInBits(getPointerAddressSpace()) && - "The offset must have exactly as many bits as our pointer."); - - for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); - GTI != GTE; ++GTI) { - ConstantInt *OpC = dyn_cast(GTI.getOperand()); - if (!OpC) - return false; - if (OpC->isZero()) - continue; - - // Handle a struct index, which adds its field offset to the pointer. - if (StructType *STy = dyn_cast(*GTI)) { - unsigned ElementIdx = OpC->getZExtValue(); - const StructLayout *SL = DL.getStructLayout(STy); - Offset += APInt(Offset.getBitWidth(), - SL->getElementOffset(ElementIdx)); - continue; - } - - // For array or vector indices, scale the index by the size of the type. - APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); - Offset += Index * APInt(Offset.getBitWidth(), - DL.getTypeAllocSize(GTI.getIndexedType())); - } - return true; - } - + bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const; }; class PtrToIntOperator diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index d35372a2f8e..3665d5abb41 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -3050,3 +3050,33 @@ Instruction *ConstantExpr::getAsInstruction() { return BO; } } + +bool GEPOperator::accumulateConstantOffset(const DataLayout &DL, + APInt &Offset) const { + assert(Offset.getBitWidth() == + DL.getPointerSizeInBits(getPointerAddressSpace()) && + "The offset must have exactly as many bits as our pointer."); + + for (gep_type_iterator GTI = gep_type_begin(this), GTE = gep_type_end(this); + GTI != GTE; ++GTI) { + ConstantInt *OpC = dyn_cast(GTI.getOperand()); + if (!OpC) + return false; + if (OpC->isZero()) + continue; + + // Handle a struct index, which adds its field offset to the pointer. + if (StructType *STy = dyn_cast(*GTI)) { + unsigned ElementIdx = OpC->getZExtValue(); + const StructLayout *SL = DL.getStructLayout(STy); + Offset += APInt(Offset.getBitWidth(), SL->getElementOffset(ElementIdx)); + continue; + } + + // For array or vector indices, scale the index by the size of the type. + APInt Index = OpC->getValue().sextOrTrunc(Offset.getBitWidth()); + Offset += Index * APInt(Offset.getBitWidth(), + DL.getTypeAllocSize(GTI.getIndexedType())); + } + return true; +} diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 8f7e661070f..e6108c3e95e 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/IR/Function.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" diff --git a/lib/Target/Mips/MipsFastISel.cpp b/lib/Target/Mips/MipsFastISel.cpp index 3ad55e036f7..4faee10744b 100644 --- a/lib/Target/Mips/MipsFastISel.cpp +++ b/lib/Target/Mips/MipsFastISel.cpp @@ -13,6 +13,7 @@ #include "llvm/CodeGen/FunctionLoweringInfo.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineRegisterInfo.h" +#include "llvm/IR/GetElementPtrTypeIterator.h" #include "llvm/IR/GlobalAlias.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/Target/TargetInstrInfo.h" -- 2.34.1