From: David Blaikie Date: Fri, 8 May 2015 00:42:26 +0000 (+0000) Subject: [opaque pointer type] Explicit pointee type for GEPOperator/GEPConstantExpr. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=66583e491735fa8798341f3050f590730ef0c494;hp=8227e6a8b4b6bb7f85e281dce6ee8a4c172c13c0 [opaque pointer type] Explicit pointee type for GEPOperator/GEPConstantExpr. Also a couple of other changes to avoid use of PointerType::getElementType here & there too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236799 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/IR/Operator.h b/include/llvm/IR/Operator.h index 8c3afdd86ae..81eec413c84 100644 --- a/include/llvm/IR/Operator.h +++ b/include/llvm/IR/Operator.h @@ -400,10 +400,7 @@ public: return getPointerOperand()->getType(); } - Type *getSourceElementType() const { - return cast(getPointerOperandType()->getScalarType()) - ->getElementType(); - } + Type *getSourceElementType() const; /// Method to return the address space of the pointer operand. unsigned getPointerAddressSpace() const { diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index aed1196f3ce..cb03218bff8 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -3523,10 +3523,12 @@ std::error_code BitcodeReader::ParseFunctionBody(Function *F) { if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) return Error("Invalid record"); - if (Ty && - Ty != - cast(BasePtr->getType()->getScalarType()) - ->getElementType()) + if (!Ty) + Ty = cast(BasePtr->getType()->getScalarType()) + ->getElementType(); + else if (Ty != + cast(BasePtr->getType()->getScalarType()) + ->getElementType()) return Error( "Explicit gep type does not match pointee type of pointer operand"); diff --git a/lib/IR/CMakeLists.txt b/lib/IR/CMakeLists.txt index d2e0c383c82..aabeaefc0c7 100644 --- a/lib/IR/CMakeLists.txt +++ b/lib/IR/CMakeLists.txt @@ -34,6 +34,7 @@ add_llvm_library(LLVMCore Metadata.cpp MetadataTracking.cpp Module.cpp + Operator.cpp Pass.cpp PassManager.cpp PassRegistry.cpp diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index b598c2807ce..d35372a2f8e 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -2050,7 +2050,8 @@ Constant *ConstantExpr::getGetElementPtr(Type *Ty, Constant *C, ArgVec.push_back(cast(Idxs[i])); } const ConstantExprKeyType Key(Instruction::GetElementPtr, ArgVec, 0, - InBounds ? GEPOperator::IsInBounds : 0); + InBounds ? GEPOperator::IsInBounds : 0, None, + Ty); LLVMContextImpl *pImpl = C->getContext().pImpl; return pImpl->ExprConstants.getOrCreate(ReqTy, Key); @@ -2380,19 +2381,22 @@ const char *ConstantExpr::getOpcodeName() const { return Instruction::getOpcodeName(getOpcode()); } - - -GetElementPtrConstantExpr:: -GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, - Type *DestTy) - : ConstantExpr(DestTy, Instruction::GetElementPtr, - OperandTraits::op_end(this) - - (IdxList.size()+1), IdxList.size()+1) { +GetElementPtrConstantExpr::GetElementPtrConstantExpr( + Type *SrcElementTy, Constant *C, ArrayRef IdxList, Type *DestTy) + : ConstantExpr(DestTy, Instruction::GetElementPtr, + OperandTraits::op_end(this) - + (IdxList.size() + 1), + IdxList.size() + 1), + SrcElementTy(SrcElementTy) { OperandList[0] = C; for (unsigned i = 0, E = IdxList.size(); i != E; ++i) OperandList[i+1] = IdxList[i]; } +Type *GetElementPtrConstantExpr::getSourceElementType() const { + return SrcElementTy; +} + //===----------------------------------------------------------------------===// // ConstantData* implementations diff --git a/lib/IR/ConstantsContext.h b/lib/IR/ConstantsContext.h index c1dfcf13b2d..e385766fbb8 100644 --- a/lib/IR/ConstantsContext.h +++ b/lib/IR/ConstantsContext.h @@ -211,19 +211,29 @@ public: /// GetElementPtrConstantExpr - This class is private to Constants.cpp, and is /// used behind the scenes to implement getelementpr constant exprs. class GetElementPtrConstantExpr : public ConstantExpr { + Type *SrcElementTy; void anchor() override; - GetElementPtrConstantExpr(Constant *C, ArrayRef IdxList, - Type *DestTy); + GetElementPtrConstantExpr(Type *SrcElementTy, Constant *C, + ArrayRef IdxList, Type *DestTy); + public: static GetElementPtrConstantExpr *Create(Constant *C, ArrayRef IdxList, Type *DestTy, unsigned Flags) { - GetElementPtrConstantExpr *Result = - new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); + return Create( + cast(C->getType()->getScalarType())->getElementType(), C, + IdxList, DestTy, Flags); + } + static GetElementPtrConstantExpr *Create(Type *SrcElementTy, Constant *C, + ArrayRef IdxList, + Type *DestTy, unsigned Flags) { + GetElementPtrConstantExpr *Result = new (IdxList.size() + 1) + GetElementPtrConstantExpr(SrcElementTy, C, IdxList, DestTy); Result->SubclassOptionalData = Flags; return Result; } + Type *getSourceElementType() const; /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); }; @@ -420,13 +430,16 @@ struct ConstantExprKeyType { uint16_t SubclassData; ArrayRef Ops; ArrayRef Indexes; + Type *ExplicitTy; ConstantExprKeyType(unsigned Opcode, ArrayRef Ops, unsigned short SubclassData = 0, unsigned short SubclassOptionalData = 0, - ArrayRef Indexes = None) + ArrayRef Indexes = None, + Type *ExplicitTy = nullptr) : Opcode(Opcode), SubclassOptionalData(SubclassOptionalData), - SubclassData(SubclassData), Ops(Ops), Indexes(Indexes) {} + SubclassData(SubclassData), Ops(Ops), Indexes(Indexes), + ExplicitTy(ExplicitTy) {} ConstantExprKeyType(ArrayRef Operands, const ConstantExpr *CE) : Opcode(CE->getOpcode()), SubclassOptionalData(CE->getRawSubclassOptionalData()), @@ -497,8 +510,11 @@ struct ConstantExprKeyType { case Instruction::ExtractValue: return new ExtractValueConstantExpr(Ops[0], Indexes, Ty); case Instruction::GetElementPtr: - return GetElementPtrConstantExpr::Create(Ops[0], Ops.slice(1), Ty, - SubclassOptionalData); + return GetElementPtrConstantExpr::Create( + ExplicitTy ? ExplicitTy + : cast(Ops[0]->getType()->getScalarType()) + ->getElementType(), + Ops[0], Ops.slice(1), Ty, SubclassOptionalData); case Instruction::ICmp: return new CompareConstantExpr(Ty, Instruction::ICmp, SubclassData, Ops[0], Ops[1]); diff --git a/lib/IR/Operator.cpp b/lib/IR/Operator.cpp new file mode 100644 index 00000000000..dd62b04c867 --- /dev/null +++ b/lib/IR/Operator.cpp @@ -0,0 +1,13 @@ +#include "llvm/IR/Operator.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Type.h" + +#include "ConstantsContext.h" + +namespace llvm { +Type *GEPOperator::getSourceElementType() const { + if (auto *I = dyn_cast(this)) + return I->getSourceElementType(); + return cast(this)->getSourceElementType(); +} +} diff --git a/lib/IR/Verifier.cpp b/lib/IR/Verifier.cpp index 1a30d5b5448..4b54f278219 100644 --- a/lib/IR/Verifier.cpp +++ b/lib/IR/Verifier.cpp @@ -437,7 +437,7 @@ void Verifier::visitGlobalValue(const GlobalValue &GV) { if (GV.hasAppendingLinkage()) { const GlobalVariable *GVar = dyn_cast(&GV); - Assert(GVar && GVar->getType()->getElementType()->isArrayTy(), + Assert(GVar && GVar->getValueType()->isArrayTy(), "Only global arrays can have appending linkage!", GVar); } } @@ -469,7 +469,7 @@ void Verifier::visitGlobalVariable(const GlobalVariable &GV) { "invalid linkage for intrinsic global variable", &GV); // Don't worry about emitting an error for it not being an array, // visitGlobalValue will complain on appending non-array. - if (ArrayType *ATy = dyn_cast(GV.getType()->getElementType())) { + if (ArrayType *ATy = dyn_cast(GV.getValueType())) { StructType *STy = dyn_cast(ATy->getElementType()); PointerType *FuncPtrTy = FunctionType::get(Type::getVoidTy(*Context), false)->getPointerTo();