diff options
-rw-r--r-- | include/llvm/IR/GetElementPtrTypeIterator.h | 50 | ||||
-rw-r--r-- | include/llvm/IR/Operator.h | 32 | ||||
-rw-r--r-- | lib/IR/Constants.cpp | 30 | ||||
-rw-r--r-- | lib/Target/AArch64/AArch64ISelLowering.cpp | 1 | ||||
-rw-r--r-- | 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<typename ItTy = User::const_op_iterator> @@ -26,19 +28,28 @@ namespace llvm { Type *, ptrdiff_t> super; ItTy OpIt; - Type *CurTy; + PointerIntPair<Type *, 1> 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<CompositeType>(CurTy); + if (CurTy.getInt()) + return CurTy.getPointer(); + CompositeType *CT = cast<CompositeType>(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<CompositeType>(CurTy)) { - CurTy = CT->getTypeAtIndex(getOperand()); + if (CurTy.getInt()) { + CurTy.setInt(false); + } else if (CompositeType *CT = + dyn_cast<CompositeType>(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<GEPOperator>(GEP); + return gep_type_iterator::begin( + GEPOp->getSourceElementType(), + cast<PointerType>(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<GEPOperator>(GEP); + return gep_type_iterator::begin( + GEPOp.getSourceElementType(), + cast<PointerType>(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<ConstantInt>(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<StructType>(*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<ConstantInt>(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<StructType>(*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" |