From cc63f1c67456f41b25e8ccb8c1dce72067ddbadf Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Aug 2002 23:37:20 +0000 Subject: [PATCH] Eliminated the MemAccessInst class, folding contents into GEP class. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3487 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/iMemory.h | 103 ++++++------------ lib/Bytecode/Reader/InstructionReader.cpp | 8 +- lib/CodeGen/InstrSelection/InstrForest.cpp | 7 +- .../InstrSelection/InstrSelectionSupport.cpp | 10 +- lib/ExecutionEngine/Interpreter/Execution.cpp | 7 +- .../SparcV9/InstrSelection/InstrForest.cpp | 7 +- .../InstrSelection/InstrSelectionSupport.cpp | 10 +- lib/Transforms/ExprTypeConvert.cpp | 26 ++--- .../Scalar/DecomposeMultiDimRefs.cpp | 29 ++--- lib/Transforms/Scalar/SCCP.cpp | 3 +- .../Utils/PromoteMemoryToRegister.cpp | 20 +--- lib/VMCore/Verifier.cpp | 5 +- lib/VMCore/iMemory.cpp | 63 +++++------ 13 files changed, 114 insertions(+), 184 deletions(-) diff --git a/include/llvm/iMemory.h b/include/llvm/iMemory.h index fd502315c43..ab1b593387b 100644 --- a/include/llvm/iMemory.h +++ b/include/llvm/iMemory.h @@ -127,70 +127,6 @@ struct FreeInst : public Instruction { }; -//===----------------------------------------------------------------------===// -// MemAccessInst Class -//===----------------------------------------------------------------------===// -// -// MemAccessInst - Common base class of GetElementPtrInst... -// -class MemAccessInst : public Instruction { -protected: - inline MemAccessInst(const Type *Ty, unsigned Opcode, - const std::string &Nam = "") - : Instruction(Ty, Opcode, Nam) {} -public: - // getIndexedType - Returns the type of the element that would be loaded with - // a load instruction with the specified parameters. - // - // A null type is returned if the indices are invalid for the specified - // pointer type. - // - static const Type *getIndexedType(const Type *Ptr, - const std::vector &Indices, - bool AllowStructLeaf = false); - - inline op_iterator idx_begin() { - return op_begin()+getFirstIndexOperandNumber(); - } - inline const_op_iterator idx_begin() const { - return op_begin()+getFirstIndexOperandNumber(); - } - inline op_iterator idx_end() { return op_end(); } - inline const_op_iterator idx_end() const { return op_end(); } - - - std::vector copyIndices() const { - return std::vector(idx_begin(), idx_end()); - } - - Value *getPointerOperand() { - return getOperand(getFirstIndexOperandNumber()-1); - } - const Value *getPointerOperand() const { - return getOperand(getFirstIndexOperandNumber()-1); - } - - virtual unsigned getFirstIndexOperandNumber() const = 0; - - inline unsigned getNumIndices() const { // Note: always non-negative - return (getNumOperands() - getFirstIndexOperandNumber()); - } - - inline bool hasIndices() const { - return getNumIndices() > 0; - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const MemAccessInst *) { return true; } - static inline bool classof(const Instruction *I) { - return I->getOpcode() == GetElementPtr; - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); - } -}; - - //===----------------------------------------------------------------------===// // LoadInst Class //===----------------------------------------------------------------------===// @@ -253,9 +189,9 @@ public: // GetElementPtrInst Class //===----------------------------------------------------------------------===// -class GetElementPtrInst : public MemAccessInst { +class GetElementPtrInst : public Instruction { GetElementPtrInst(const GetElementPtrInst &EPI) - : MemAccessInst((Type*)EPI.getType(), GetElementPtr) { + : Instruction((Type*)EPI.getType(), GetElementPtr) { Operands.reserve(EPI.Operands.size()); for (unsigned i = 0, E = EPI.Operands.size(); i != E; ++i) Operands.push_back(Use(EPI.Operands[i], this)); @@ -264,13 +200,46 @@ public: GetElementPtrInst(Value *Ptr, const std::vector &Idx, const std::string &Name = ""); virtual Instruction *clone() const { return new GetElementPtrInst(*this); } - virtual unsigned getFirstIndexOperandNumber() const { return 1; } // getType - Overload to return most specific pointer type... inline const PointerType *getType() const { return (PointerType*)Instruction::getType(); } + /// getIndexedType - Returns the type of the element that would be loaded with + /// a load instruction with the specified parameters. + /// + /// A null type is returned if the indices are invalid for the specified + /// pointer type. + /// + static const Type *getIndexedType(const Type *Ptr, + const std::vector &Indices, + bool AllowStructLeaf = false); + + inline op_iterator idx_begin() { + return op_begin()+1; + } + inline const_op_iterator idx_begin() const { + return op_begin()+1; + } + inline op_iterator idx_end() { return op_end(); } + inline const_op_iterator idx_end() const { return op_end(); } + + Value *getPointerOperand() { + return getOperand(0); + } + const Value *getPointerOperand() const { + return getOperand(0); + } + + inline unsigned getNumIndices() const { // Note: always non-negative + return getNumOperands() - 1; + } + + inline bool hasIndices() const { + return getNumOperands() > 1; + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const GetElementPtrInst *) { return true; } static inline bool classof(const Instruction *I) { diff --git a/lib/Bytecode/Reader/InstructionReader.cpp b/lib/Bytecode/Reader/InstructionReader.cpp index 123a94c9dc5..0b75c41b008 100644 --- a/lib/Bytecode/Reader/InstructionReader.cpp +++ b/lib/Bytecode/Reader/InstructionReader.cpp @@ -363,7 +363,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, Idx.push_back(V = getValue(TopTy->getIndexType(), Raw.Arg2)); if (!V) return true; - const Type *ETy = MemAccessInst::getIndexedType(TopTy, Idx, true); + const Type *ETy = GetElementPtrInst::getIndexedType(TopTy, Idx, true); const CompositeType *ElTy = dyn_cast_or_null(ETy); if (!ElTy) return true; @@ -378,7 +378,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, vector &args = *Raw.VarArgs; for (unsigned i = 0, E = args.size(); i != E; ++i) { - const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true); + const Type *ETy = GetElementPtrInst::getIndexedType(Raw.Ty, Idx, true); const CompositeType *ElTy = dyn_cast_or_null(ETy); if (!ElTy) return true; Idx.push_back(V = getValue(ElTy->getIndexType(), args[i])); @@ -393,7 +393,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, if (!Idx.empty()) { cerr << "WARNING: Bytecode contains load instruction with indices. " << "Replacing with getelementptr/load pair\n"; - assert(MemAccessInst::getIndexedType(Raw.Ty, Idx) && + assert(GetElementPtrInst::getIndexedType(Raw.Ty, Idx) && "Bad indices for Load!"); Src = new GetElementPtrInst(Src, Idx); // FIXME: Remove this compatibility code and the BB parameter to this @@ -429,7 +429,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf, Idx.push_back(V = getValue(ElTy->getIndexType(), args[i])); if (!V) return true; - const Type *ETy = MemAccessInst::getIndexedType(Raw.Ty, Idx, true); + const Type *ETy = GetElementPtrInst::getIndexedType(Raw.Ty, Idx, true); ElTy = dyn_cast_or_null(ETy); } if (i != E) diff --git a/lib/CodeGen/InstrSelection/InstrForest.cpp b/lib/CodeGen/InstrSelection/InstrForest.cpp index eb9e7f940ed..91956f53a4d 100644 --- a/lib/CodeGen/InstrSelection/InstrForest.cpp +++ b/lib/CodeGen/InstrSelection/InstrForest.cpp @@ -67,11 +67,10 @@ InstructionNode::InstructionNode(Instruction* I) { opLabel = AllocaN; // Alloca(ptr, N) operation } - else if ((opLabel == Instruction::Load || - opLabel == Instruction::GetElementPtr) && - cast(I)->hasIndices()) + else if (opLabel == Instruction::GetElementPtr && + cast(I)->hasIndices()) { - opLabel = opLabel + 100; // load/getElem with index vector + opLabel = opLabel + 100; // getElem with index vector } else if (opLabel == Instruction::Xor && BinaryOperator::isNot(I)) diff --git a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp index 914fec35762..294fdaec252 100644 --- a/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/CodeGen/InstrSelection/InstrSelectionSupport.cpp @@ -111,8 +111,8 @@ Value* FoldGetElemChain(const InstructionNode* getElemInstrNode, vector& chainIdxVec) { - MemAccessInst* getElemInst = (MemAccessInst*) - getElemInstrNode->getInstruction(); + GetElementPtrInst* getElemInst = + cast(getElemInstrNode->getInstruction()); // Return NULL if we don't fold any instructions in. Value* ptrVal = NULL; @@ -128,9 +128,9 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode, ptrChild->getOpLabel() == GetElemPtrIdx) { // Child is a GetElemPtr instruction - getElemInst = cast(ptrChild->getValue()); - MemAccessInst::op_iterator OI, firstIdx = getElemInst->idx_begin(); - MemAccessInst::op_iterator lastIdx = getElemInst->idx_end(); + getElemInst = cast(ptrChild->getValue()); + User::op_iterator OI, firstIdx = getElemInst->idx_begin(); + User::op_iterator lastIdx = getElemInst->idx_end(); bool allConstantOffsets = true; // Check that all offsets are constant for this instruction diff --git a/lib/ExecutionEngine/Interpreter/Execution.cpp b/lib/ExecutionEngine/Interpreter/Execution.cpp index 7b5a63ead07..8bd6774b093 100644 --- a/lib/ExecutionEngine/Interpreter/Execution.cpp +++ b/lib/ExecutionEngine/Interpreter/Execution.cpp @@ -769,14 +769,14 @@ static void executeFreeInst(FreeInst &I, ExecutionContext &SF) { // the offset that arguments ArgOff+1 -> NumArgs specify for the pointer type // specified by argument Arg. // -static PointerTy getElementOffset(MemAccessInst &I, ExecutionContext &SF) { +static PointerTy getElementOffset(GetElementPtrInst &I, ExecutionContext &SF) { assert(isa(I.getPointerOperand()->getType()) && "Cannot getElementOffset of a nonpointer type!"); PointerTy Total = 0; const Type *Ty = I.getPointerOperand()->getType(); - unsigned ArgOff = I.getFirstIndexOperandNumber(); + unsigned ArgOff = 1; while (ArgOff < I.getNumOperands()) { if (const StructType *STy = dyn_cast(Ty)) { const StructLayout *SLO = TD.getStructLayout(STy); @@ -806,8 +806,7 @@ static PointerTy getElementOffset(MemAccessInst &I, ExecutionContext &SF) { if (Idx >= AT->getNumElements() && ArrayChecksEnabled) { cerr << "Out of range memory access to element #" << Idx << " of a " << AT->getNumElements() << " element array." - << " Subscript #" << (ArgOff-I.getFirstIndexOperandNumber()) - << "\n"; + << " Subscript #" << (ArgOff-1) << "\n"; // Get outta here!!! siglongjmp(SignalRecoverBuffer, SIGTRAP); } diff --git a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp index eb9e7f940ed..91956f53a4d 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrForest.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrForest.cpp @@ -67,11 +67,10 @@ InstructionNode::InstructionNode(Instruction* I) { opLabel = AllocaN; // Alloca(ptr, N) operation } - else if ((opLabel == Instruction::Load || - opLabel == Instruction::GetElementPtr) && - cast(I)->hasIndices()) + else if (opLabel == Instruction::GetElementPtr && + cast(I)->hasIndices()) { - opLabel = opLabel + 100; // load/getElem with index vector + opLabel = opLabel + 100; // getElem with index vector } else if (opLabel == Instruction::Xor && BinaryOperator::isNot(I)) diff --git a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp index 914fec35762..294fdaec252 100644 --- a/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp +++ b/lib/Target/SparcV9/InstrSelection/InstrSelectionSupport.cpp @@ -111,8 +111,8 @@ Value* FoldGetElemChain(const InstructionNode* getElemInstrNode, vector& chainIdxVec) { - MemAccessInst* getElemInst = (MemAccessInst*) - getElemInstrNode->getInstruction(); + GetElementPtrInst* getElemInst = + cast(getElemInstrNode->getInstruction()); // Return NULL if we don't fold any instructions in. Value* ptrVal = NULL; @@ -128,9 +128,9 @@ FoldGetElemChain(const InstructionNode* getElemInstrNode, ptrChild->getOpLabel() == GetElemPtrIdx) { // Child is a GetElemPtr instruction - getElemInst = cast(ptrChild->getValue()); - MemAccessInst::op_iterator OI, firstIdx = getElemInst->idx_begin(); - MemAccessInst::op_iterator lastIdx = getElemInst->idx_end(); + getElemInst = cast(ptrChild->getValue()); + User::op_iterator OI, firstIdx = getElemInst->idx_begin(); + User::op_iterator lastIdx = getElemInst->idx_end(); bool allConstantOffsets = true; // Check that all offsets are constant for this instruction diff --git a/lib/Transforms/ExprTypeConvert.cpp b/lib/Transforms/ExprTypeConvert.cpp index a84f1d0f5e3..33aa3cb4751 100644 --- a/lib/Transforms/ExprTypeConvert.cpp +++ b/lib/Transforms/ExprTypeConvert.cpp @@ -24,19 +24,6 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, ValueMapCache &VMC); -// AllIndicesZero - Return true if all of the indices of the specified memory -// access instruction are zero, indicating an effectively nil offset to the -// pointer value. -// -static bool AllIndicesZero(const MemAccessInst *MAI) { - for (User::const_op_iterator S = MAI->idx_begin(), E = MAI->idx_end(); - S != E; ++S) - if (!isa(S->get()) || !cast(S->get())->isNullValue()) - return false; - return true; -} - - // Peephole Malloc instructions: we take a look at the use chain of the // malloc instruction, and try to find out if the following conditions hold: // 1. The malloc is of the form: 'malloc [sbyte], uint ' @@ -253,7 +240,7 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, // index array. If there are, check to see if removing them causes us to // get to the right type... // - std::vector Indices = GEP->copyIndices(); + std::vector Indices(GEP->idx_begin(), GEP->idx_end()); const Type *BaseType = GEP->getPointerOperand()->getType(); const Type *ElTy = 0; @@ -446,7 +433,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { // index array. If there are, check to see if removing them causes us to // get to the right type... // - std::vector Indices = GEP->copyIndices(); + std::vector Indices(GEP->idx_begin(), GEP->idx_end()); const Type *BaseType = GEP->getPointerOperand()->getType(); const Type *PVTy = cast(Ty)->getElementType(); Res = 0; @@ -497,8 +484,9 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { // if (Res == 0) { const PointerType *NewSrcTy = PointerType::get(PVTy); + std::vector Indices(GEP->idx_begin(), GEP->idx_end()); Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy), - GEP->copyIndices(), Name); + Indices, Name); VMC.ExprMap[I] = Res; Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), NewSrcTy, VMC)); @@ -1108,9 +1096,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, // to getelementptr long * %reg123, uint %N // ... where the type must simply stay the same size... // - Res = new GetElementPtrInst(NewVal, - cast(I)->copyIndices(), - Name); + GetElementPtrInst *GEP = cast(I); + std::vector Indices(GEP->idx_begin(), GEP->idx_end()); + Res = new GetElementPtrInst(NewVal, Indices, Name); } #endif break; diff --git a/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp b/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp index 4e6cbcf5f4f..b50c4fb5bf8 100644 --- a/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp +++ b/lib/Transforms/Scalar/DecomposeMultiDimRefs.cpp @@ -47,8 +47,8 @@ DecomposePass::runOnBasicBlock(BasicBlock &BB) { bool Changed = false; for (BasicBlock::iterator II = BB.begin(); II != BB.end(); ) { - if (MemAccessInst *MAI = dyn_cast(&*II)) - if (MAI->getNumIndices() >= 2) { + if (GetElementPtrInst *GEP = dyn_cast(&*II)) + if (GEP->getNumIndices() >= 2) { Changed |= decomposeArrayRef(II); // always modifies II continue; } @@ -64,7 +64,7 @@ IsZero(Value* idx) return (isa(idx) && cast(idx)->isNullValue()); } -// For any MemAccessInst with 2 or more array and structure indices: +// For any GetElementPtrInst with 2 or more array and structure indices: // // opCode CompositeType* P, [uint|ubyte] idx1, ..., [uint|ubyte] idxN // @@ -88,9 +88,9 @@ IsZero(Value* idx) bool DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) { - MemAccessInst &MAI = cast(*BBI); - BasicBlock *BB = MAI.getParent(); - Value *LastPtr = MAI.getPointerOperand(); + GetElementPtrInst &GEP = cast(*BBI); + BasicBlock *BB = GEP.getParent(); + Value *LastPtr = GEP.getPointerOperand(); // Remove the instruction from the stream BB->getInstList().remove(BBI); @@ -99,12 +99,12 @@ DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) std::vector NewInsts; // Process each index except the last one. - User::const_op_iterator OI = MAI.idx_begin(), OE = MAI.idx_end(); + User::const_op_iterator OI = GEP.idx_begin(), OE = GEP.idx_end(); for (; OI+1 != OE; ++OI) { std::vector Indices; // If this is the first index and is 0, skip it and move on! - if (OI == MAI.idx_begin()) { + if (OI == GEP.idx_begin()) { if (IsZero(*OI)) continue; } else // Not the first index: include initial [0] to deref the last ptr @@ -127,21 +127,14 @@ DecomposePass::decomposeArrayRef(BasicBlock::iterator &BBI) Indices.push_back(Constant::getNullValue(Type::UIntTy)); Indices.push_back(*OI); - Instruction *NewI = 0; - switch(MAI.getOpcode()) { - case Instruction::GetElementPtr: - NewI = new GetElementPtrInst(LastPtr, Indices, MAI.getName()); - break; - default: - assert(0 && "Unrecognized memory access instruction"); - } + Instruction *NewI = new GetElementPtrInst(LastPtr, Indices, GEP.getName()); NewInsts.push_back(NewI); // Replace all uses of the old instruction with the new - MAI.replaceAllUsesWith(NewI); + GEP.replaceAllUsesWith(NewI); // Now delete the old instruction... - delete &MAI; + delete &GEP; // Insert all of the new instructions... BB->getInstList().insert(BBI, NewInsts.begin(), NewInsts.end()); diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index 61f41e140b1..899bc5c8814 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -183,7 +183,8 @@ private: // Instructions that cannot be folded away... void visitStoreInst (Instruction &I) { /*returns void*/ } - void visitMemAccessInst (Instruction &I) { markOverdefined(&I); } + void visitLoadInst (Instruction &I) { markOverdefined(&I); } + void visitGetElementPtrInst(Instruction &I) { markOverdefined(&I); } // FIXME void visitCallInst (Instruction &I) { markOverdefined(&I); } void visitInvokeInst (Instruction &I) { markOverdefined(&I); } void visitAllocationInst(Instruction &I) { markOverdefined(&I); } diff --git a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp index d3aca318b0a..5fcab970352 100644 --- a/lib/Transforms/Utils/PromoteMemoryToRegister.cpp +++ b/lib/Transforms/Utils/PromoteMemoryToRegister.cpp @@ -76,25 +76,11 @@ namespace { static inline bool isSafeAlloca(const AllocaInst *AI) { if (AI->isArrayAllocation()) return false; + // Only allow direct loads and stores... for (Value::use_const_iterator UI = AI->use_begin(), UE = AI->use_end(); - UI != UE; ++UI) { // Loop over all of the uses of the alloca - - // Only allow nonindexed memory access instructions... - if (MemAccessInst *MAI = dyn_cast(*UI)) { - if (MAI->getPointerOperand() != (Value*)AI) - return false; // Reject stores of alloca pointer into some other loc. - - if (MAI->hasIndices()) { // indexed? - // Allow the access if there is only one index and the index is - // zero. - if (*MAI->idx_begin() != Constant::getNullValue(Type::UIntTy) || - MAI->idx_begin()+1 != MAI->idx_end()) - return false; - } - } else { + UI != UE; ++UI) // Loop over all of the uses of the alloca + if (!isa(*UI) && !isa(*UI)) return false; // Not a load or store? - } - } return true; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index da65b1ce30a..01a28352915 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -321,8 +321,9 @@ void Verifier::visitBinaryOperator(BinaryOperator &B) { } void Verifier::visitGetElementPtrInst(GetElementPtrInst &GEP) { - const Type *ElTy = MemAccessInst::getIndexedType(GEP.getOperand(0)->getType(), - GEP.copyIndices(), true); + const Type *ElTy = + GetElementPtrInst::getIndexedType(GEP.getOperand(0)->getType(), + std::vector(GEP.idx_begin(), GEP.idx_end()), true); Assert1(ElTy, "Invalid indices for GEP pointer type!", &GEP); Assert2(PointerType::get(ElTy) == GEP.getType(), "GEP is not of right type for indices!", &GEP, ElTy); diff --git a/lib/VMCore/iMemory.cpp b/lib/VMCore/iMemory.cpp index 469a2c33611..4ec9e26fbe2 100644 --- a/lib/VMCore/iMemory.cpp +++ b/lib/VMCore/iMemory.cpp @@ -38,39 +38,6 @@ const Type *AllocationInst::getAllocatedType() const { } -//===----------------------------------------------------------------------===// -// MemAccessInst Implementation -//===----------------------------------------------------------------------===// - -// getIndexedType - Returns the type of the element that would be loaded with -// a load instruction with the specified parameters. -// -// A null type is returned if the indices are invalid for the specified -// pointer type. -// -const Type* MemAccessInst::getIndexedType(const Type *Ptr, - const std::vector &Idx, - bool AllowCompositeLeaf) { - if (!isa(Ptr)) return 0; // Type isn't a pointer type! - - // Handle the special case of the empty set index set... - if (Idx.empty()) return cast(Ptr)->getElementType(); - - unsigned CurIDX = 0; - while (const CompositeType *CT = dyn_cast(Ptr)) { - if (Idx.size() == CurIDX) { - if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr; - return 0; // Can't load a whole structure or array!?!? - } - - Value *Index = Idx[CurIDX++]; - if (!CT->indexValid(Index)) return 0; - Ptr = CT->getTypeAtIndex(Index); - } - return CurIDX == Idx.size() ? Ptr : 0; -} - - //===----------------------------------------------------------------------===// // LoadInst Implementation //===----------------------------------------------------------------------===// @@ -102,7 +69,7 @@ StoreInst::StoreInst(Value *Val, Value *Ptr) GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, const std::string &Name) - : MemAccessInst(PointerType::get(checkType(getIndexedType(Ptr->getType(), + : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(), Idx, true))), GetElementPtr, Name) { assert(getIndexedType(Ptr->getType(), Idx, true) && "gep operands invalid!"); @@ -113,6 +80,34 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector &Idx, Operands.push_back(Use(Idx[i], this)); } +// getIndexedType - Returns the type of the element that would be loaded with +// a load instruction with the specified parameters. +// +// A null type is returned if the indices are invalid for the specified +// pointer type. +// +const Type* GetElementPtrInst::getIndexedType(const Type *Ptr, + const std::vector &Idx, + bool AllowCompositeLeaf) { + if (!isa(Ptr)) return 0; // Type isn't a pointer type! + + // Handle the special case of the empty set index set... + if (Idx.empty()) return cast(Ptr)->getElementType(); + + unsigned CurIDX = 0; + while (const CompositeType *CT = dyn_cast(Ptr)) { + if (Idx.size() == CurIDX) { + if (AllowCompositeLeaf || CT->isFirstClassType()) return Ptr; + return 0; // Can't load a whole structure or array!?!? + } + + Value *Index = Idx[CurIDX++]; + if (!CT->indexValid(Index)) return 0; + Ptr = CT->getTypeAtIndex(Index); + } + return CurIDX == Idx.size() ? Ptr : 0; +} + //===----------------------------------------------------------------------===// // FreeInst Implementation -- 2.34.1