From 7fa6e666ece60455cf9d75eff6e6915bebf05cbc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 11 Oct 2004 22:52:25 +0000 Subject: [PATCH] Allow creation of GEP constantexprs with a vector of value* operands as well as a vector of constant*'s. It turns out that this is more efficient and all of the clients want to do that, so we should cater to them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@16923 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Constants.h | 7 +++++-- lib/VMCore/ConstantFold.cpp | 31 ++++++++++++++++--------------- lib/VMCore/ConstantFold.h | 3 ++- lib/VMCore/ConstantFolding.h | 3 ++- lib/VMCore/Constants.cpp | 29 +++++++++++++++++++---------- 5 files changed, 44 insertions(+), 29 deletions(-) diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index d0f577311eb..e04b359a869 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -533,7 +533,7 @@ protected: static Constant *getSelectTy(const Type *Ty, Constant *C1, Constant *C2, Constant *C3); static Constant *getGetElementPtrTy(const Type *Ty, Constant *C, - const std::vector &IdxList); + const std::vector &IdxList); public: // Static methods to construct a ConstantExpr of different kinds. Note that @@ -584,10 +584,13 @@ public: static Constant *getUShr(Constant *C1, Constant *C2); // unsigned shr static Constant *getSShr(Constant *C1, Constant *C2); // signed shr - /// Getelementptr form... + /// Getelementptr form. std::vector is only accepted for convenience: + /// all elements must be Constant's. /// static Constant *getGetElementPtr(Constant *C, const std::vector &IdxList); + static Constant *getGetElementPtr(Constant *C, + const std::vector &IdxList); /// isNullValue - Return true if this is the value that would be returned by /// getNullValue. diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 703a324126a..a6ae0d5ac34 100644 --- a/lib/VMCore/ConstantFold.cpp +++ b/lib/VMCore/ConstantFold.cpp @@ -905,7 +905,7 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, if (V2->isNullValue()) return const_cast(V2); // X & 0 == 0 if (CE1->getOpcode() == Instruction::Cast && isa(CE1->getOperand(0))) { - GlobalValue *CPR =cast(CE1->getOperand(0)); + GlobalValue *CPR = cast(CE1->getOperand(0)); // Functions are at least 4-byte aligned. If and'ing the address of a // function with a constant < 4, fold it to zero. @@ -960,21 +960,21 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode, } Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, - const std::vector &IdxList) { + const std::vector &IdxList) { if (IdxList.size() == 0 || - (IdxList.size() == 1 && IdxList[0]->isNullValue())) + (IdxList.size() == 1 && cast(IdxList[0])->isNullValue())) return const_cast(C); + Constant *Idx0 = cast(IdxList[0]); if (C->isNullValue()) { bool isNull = true; for (unsigned i = 0, e = IdxList.size(); i != e; ++i) - if (!IdxList[i]->isNullValue()) { + if (!cast(IdxList[i])->isNullValue()) { isNull = false; break; } if (isNull) { - std::vector VIdxList(IdxList.begin(), IdxList.end()); - const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), VIdxList, + const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), IdxList, true); assert(Ty != 0 && "Invalid indices for GEP!"); return ConstantPointerNull::get(PointerType::get(Ty)); @@ -986,8 +986,8 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // gep null, C is equal to C*sizeof(nullty). If nullty is a known llvm // type, we can statically fold this. Constant *R = ConstantUInt::get(Type::UIntTy, ElSize); - R = ConstantExpr::getCast(R, IdxList[0]->getType()); - R = ConstantExpr::getMul(R, IdxList[0]); + R = ConstantExpr::getCast(R, Idx0->getType()); + R = ConstantExpr::getMul(R, Idx0); return ConstantExpr::getCast(R, C->getType()); } } @@ -1004,21 +1004,22 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, I != E; ++I) LastTy = *I; - if ((LastTy && isa(LastTy)) || IdxList[0]->isNullValue()) { - std::vector NewIndices; + if ((LastTy && isa(LastTy)) || Idx0->isNullValue()) { + std::vector NewIndices; NewIndices.reserve(IdxList.size() + CE->getNumOperands()); for (unsigned i = 1, e = CE->getNumOperands()-1; i != e; ++i) - NewIndices.push_back(cast(CE->getOperand(i))); + NewIndices.push_back(CE->getOperand(i)); // Add the last index of the source with the first index of the new GEP. // Make sure to handle the case when they are actually different types. Constant *Combined = CE->getOperand(CE->getNumOperands()-1); - if (!IdxList[0]->isNullValue()) { // Otherwise it must be an array + // Otherwise it must be an array. + if (!Idx0->isNullValue()) { const Type *IdxTy = Combined->getType(); - if (IdxTy != IdxList[0]->getType()) IdxTy = Type::LongTy; + if (IdxTy != Idx0->getType()) IdxTy = Type::LongTy; Combined = ConstantExpr::get(Instruction::Add, - ConstantExpr::getCast(IdxList[0], IdxTy), + ConstantExpr::getCast(Idx0, IdxTy), ConstantExpr::getCast(Combined, IdxTy)); } @@ -1034,7 +1035,7 @@ Constant *llvm::ConstantFoldGetElementPtr(const Constant *C, // To: int* getelementptr ([3 x int]* %X, long 0, long 0) // if (CE->getOpcode() == Instruction::Cast && IdxList.size() > 1 && - IdxList[0]->isNullValue()) + Idx0->isNullValue()) if (const PointerType *SPT = dyn_cast(CE->getOperand(0)->getType())) if (const ArrayType *SAT = dyn_cast(SPT->getElementType())) diff --git a/lib/VMCore/ConstantFold.h b/lib/VMCore/ConstantFold.h index 24ef180b867..676b4b8cd83 100644 --- a/lib/VMCore/ConstantFold.h +++ b/lib/VMCore/ConstantFold.h @@ -22,6 +22,7 @@ #include namespace llvm { + class Value; class Constant; struct Type; @@ -33,7 +34,7 @@ namespace llvm { Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldGetElementPtr(const Constant *C, - const std::vector &IdxList); + const std::vector &IdxList); } // End llvm namespace #endif diff --git a/lib/VMCore/ConstantFolding.h b/lib/VMCore/ConstantFolding.h index 24ef180b867..676b4b8cd83 100644 --- a/lib/VMCore/ConstantFolding.h +++ b/lib/VMCore/ConstantFolding.h @@ -22,6 +22,7 @@ #include namespace llvm { + class Value; class Constant; struct Type; @@ -33,7 +34,7 @@ namespace llvm { Constant *ConstantFoldBinaryInstruction(unsigned Opcode, const Constant *V1, const Constant *V2); Constant *ConstantFoldGetElementPtr(const Constant *C, - const std::vector &IdxList); + const std::vector &IdxList); } // End llvm namespace #endif diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index a029d8466bf..8d964bcb242 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -1148,10 +1148,8 @@ namespace llvm { break; case Instruction::GetElementPtr: // Make everyone now use a constant of the new type... - std::vector C; - for (unsigned i = 1, e = OldC->getNumOperands(); i != e; ++i) - C.push_back(cast(OldC->getOperand(i))); - New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), C); + std::vector Idx(OldC->op_begin()+1, OldC->op_end()); + New = ConstantExpr::getGetElementPtrTy(NewTy, OldC->getOperand(0), Idx); break; } @@ -1298,9 +1296,8 @@ Constant *ConstantExpr::getShiftTy(const Type *ReqTy, unsigned Opcode, Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, - const std::vector &IdxList) { - assert(GetElementPtrInst::getIndexedType(C->getType(), - std::vector(IdxList.begin(), IdxList.end()), true) && + const std::vector &IdxList) { + assert(GetElementPtrInst::getIndexedType(C->getType(), IdxList, true) && "GEP indices invalid!"); if (Constant *FC = ConstantFoldGetElementPtr(C, IdxList)) @@ -1309,9 +1306,12 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, assert(isa(C->getType()) && "Non-pointer type for constant GetElementPtr expression"); // Look up the constant in the table first to ensure uniqueness - std::vector argVec(1, C); - argVec.insert(argVec.end(), IdxList.begin(), IdxList.end()); - const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,argVec); + std::vector ArgVec; + ArgVec.reserve(IdxList.size()+1); + ArgVec.push_back(C); + for (unsigned i = 0, e = IdxList.size(); i != e; ++i) + ArgVec.push_back(cast(IdxList[i])); + const ExprMapKeyType &Key = std::make_pair(Instruction::GetElementPtr,ArgVec); return ExprConstants.getOrCreate(ReqTy, Key); } @@ -1323,6 +1323,15 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), VIdxList, true); assert(Ty && "GEP indices invalid!"); + return getGetElementPtrTy(PointerType::get(Ty), C, VIdxList); +} + +Constant *ConstantExpr::getGetElementPtr(Constant *C, + const std::vector &IdxList) { + // Get the result type of the getelementptr! + const Type *Ty = GetElementPtrInst::getIndexedType(C->getType(), IdxList, + true); + assert(Ty && "GEP indices invalid!"); return getGetElementPtrTy(PointerType::get(Ty), C, IdxList); } -- 2.34.1