diff options
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Constants.cpp | 89 | ||||
-rw-r--r-- | lib/VMCore/ConstantsContext.h | 49 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 15 |
3 files changed, 106 insertions, 47 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index 37efafc9b2..a5b4f28968 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -632,21 +632,13 @@ Constant* ConstantVector::get(Constant* const* Vals, unsigned NumVals) { } Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) { - Constant *C = getAdd(C1, C2); - // Set nsw attribute, assuming constant folding didn't eliminate the - // Add. - if (AddOperator *Add = dyn_cast<AddOperator>(C)) - Add->setHasNoSignedWrap(true); - return C; + return getTy(C1->getType(), Instruction::Add, C1, C2, + OverflowingBinaryOperator::NoSignedWrap); } Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) { - Constant *C = getSDiv(C1, C2); - // Set exact attribute, assuming constant folding didn't eliminate the - // SDiv. - if (SDivOperator *SDiv = dyn_cast<SDivOperator>(C)) - SDiv->setIsExact(true); - return C; + return getTy(C1->getType(), Instruction::SDiv, C1, C2, + SDivOperator::IsExact); } // Utility function for determining if a ConstantExpr is a CastOp or not. This @@ -729,15 +721,19 @@ ConstantExpr::getWithOperandReplaced(unsigned OpNo, Constant *Op) const { for (unsigned i = 1, e = getNumOperands(); i != e; ++i) Ops[i-1] = getOperand(i); if (OpNo == 0) - return ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(Op, &Ops[0], Ops.size()) : + ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size()); Ops[OpNo-1] = Op; - return ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) : + ConstantExpr::getGetElementPtr(getOperand(0), &Ops[0], Ops.size()); } default: assert(getNumOperands() == 2 && "Must be binary operator?"); Op0 = (OpNo == 0) ? Op : getOperand(0); Op1 = (OpNo == 1) ? Op : getOperand(1); - return ConstantExpr::get(getOpcode(), Op0, Op1); + return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassData); } } @@ -779,13 +775,15 @@ getWithOperands(Constant* const *Ops, unsigned NumOps) const { case Instruction::ShuffleVector: return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]); case Instruction::GetElementPtr: - return ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1); + return cast<GEPOperator>(this)->isInBounds() ? + ConstantExpr::getInBoundsGetElementPtr(Ops[0], &Ops[1], NumOps-1) : + ConstantExpr::getGetElementPtr(Ops[0], &Ops[1], NumOps-1); case Instruction::ICmp: case Instruction::FCmp: return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]); default: assert(getNumOperands() == 2 && "Must be binary operator?"); - return ConstantExpr::get(getOpcode(), Ops[0], Ops[1]); + return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData); } } @@ -1031,8 +1029,9 @@ static ExprMapKeyType getValType(ConstantExpr *CE) { Operands.reserve(CE->getNumOperands()); for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) Operands.push_back(cast<Constant>(CE->getOperand(i))); - return ExprMapKeyType(CE->getOpcode(), Operands, + return ExprMapKeyType(CE->getOpcode(), Operands, CE->isCompare() ? CE->getPredicate() : 0, + CE->getRawSubclassOptionalData(), CE->hasIndices() ? CE->getIndices() : SmallVector<unsigned, 4>()); } @@ -1280,7 +1279,8 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { } Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, - Constant *C1, Constant *C2) { + Constant *C1, Constant *C2, + unsigned Flags) { // Check the operands for consistency first assert(Opcode >= Instruction::BinaryOpsBegin && Opcode < Instruction::BinaryOpsEnd && @@ -1294,7 +1294,7 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode, return FC; // Fold a few common cases... std::vector<Constant*> argVec(1, C1); argVec.push_back(C2); - ExprMapKeyType Key(Opcode, argVec); + ExprMapKeyType Key(Opcode, argVec, 0, Flags); LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; @@ -1322,7 +1322,8 @@ Constant *ConstantExpr::getCompareTy(unsigned short predicate, } } -Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { +Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) { // API compatibility: Adjust integer opcodes to floating-point opcodes. if (C1->getType()->isFPOrFPVector()) { if (Opcode == Instruction::Add) Opcode = Instruction::FAdd; @@ -1387,7 +1388,7 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) { } #endif - return getTy(C1->getType(), Opcode, C1, C2); + return getTy(C1->getType(), Opcode, C1, C2, Flags); } Constant* ConstantExpr::getSizeOf(const Type* Ty) { @@ -1481,6 +1482,36 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C, return pImpl->ExprConstants.getOrCreate(ReqTy, Key); } +Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy, + Constant *C, + Value* const *Idxs, + unsigned NumIdx) { + assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, + Idxs+NumIdx) == + cast<PointerType>(ReqTy)->getElementType() && + "GEP indices invalid!"); + + if (Constant *FC = ConstantFoldGetElementPtr( + ReqTy->getContext(), C, (Constant**)Idxs, NumIdx)) + return FC; // Fold a few common cases... + + assert(isa<PointerType>(C->getType()) && + "Non-pointer type for constant GetElementPtr expression"); + // Look up the constant in the table first to ensure uniqueness + std::vector<Constant*> ArgVec; + ArgVec.reserve(NumIdx+1); + ArgVec.push_back(C); + for (unsigned i = 0; i != NumIdx; ++i) + ArgVec.push_back(cast<Constant>(Idxs[i])); + const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec, 0, + GEPOperator::IsInBounds); + + LLVMContextImpl *pImpl = ReqTy->getContext().pImpl; + + // Implicitly locked. + return pImpl->ExprConstants.getOrCreate(ReqTy, Key); +} + Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, unsigned NumIdx) { // Get the result type of the getelementptr! @@ -1494,12 +1525,12 @@ Constant *ConstantExpr::getGetElementPtr(Constant *C, Value* const *Idxs, Constant *ConstantExpr::getInBoundsGetElementPtr(Constant *C, Value* const *Idxs, unsigned NumIdx) { - Constant *Result = getGetElementPtr(C, Idxs, NumIdx); - // Set in bounds attribute, assuming constant folding didn't eliminate the - // GEP. - if (GEPOperator *GEP = dyn_cast<GEPOperator>(Result)) - GEP->setIsInBounds(true); - return Result; + // Get the result type of the getelementptr! + const Type *Ty = + GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx); + assert(Ty && "GEP indices invalid!"); + unsigned As = cast<PointerType>(C->getType())->getAddressSpace(); + return getInBoundsGetElementPtrTy(PointerType::get(Ty, As), C, Idxs, NumIdx); } Constant *ConstantExpr::getGetElementPtr(Constant *C, Constant* const *Idxs, @@ -2104,7 +2135,7 @@ void ConstantExpr::replaceUsesOfWithOnConstant(Value *From, Value *ToV, Constant *C2 = getOperand(1); if (C1 == From) C1 = To; if (C2 == From) C2 = To; - Replacement = ConstantExpr::get(getOpcode(), C1, C2); + Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData); } else { llvm_unreachable("Unknown ConstantExpr type!"); return; diff --git a/lib/VMCore/ConstantsContext.h b/lib/VMCore/ConstantsContext.h index 718470aff4..16975b3611 100644 --- a/lib/VMCore/ConstantsContext.h +++ b/lib/VMCore/ConstantsContext.h @@ -53,10 +53,12 @@ public: void *operator new(size_t s) { return User::operator new(s, 2); } - BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2) + BinaryConstantExpr(unsigned Opcode, Constant *C1, Constant *C2, + unsigned Flags) : ConstantExpr(C1->getType(), Opcode, &Op<0>(), 2) { Op<0>() = C1; Op<1>() = C2; + SubclassOptionalData = Flags; } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -206,9 +208,12 @@ class GetElementPtrConstantExpr : public ConstantExpr { public: static GetElementPtrConstantExpr *Create(Constant *C, const std::vector<Constant*>&IdxList, - const Type *DestTy) { - return + const Type *DestTy, + unsigned Flags) { + GetElementPtrConstantExpr *Result = new(IdxList.size() + 1) GetElementPtrConstantExpr(C, IdxList, DestTy); + Result->SubclassOptionalData = Flags; + return Result; } /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -291,26 +296,32 @@ struct ExprMapKeyType { ExprMapKeyType(unsigned opc, const std::vector<Constant*> &ops, - unsigned short pred = 0, + unsigned short flags = 0, + unsigned short optionalflags = 0, const IndexList &inds = IndexList()) - : opcode(opc), predicate(pred), operands(ops), indices(inds) {} - uint16_t opcode; - uint16_t predicate; + : opcode(opc), subclassoptionaldata(optionalflags), subclassdata(flags), + operands(ops), indices(inds) {} + uint8_t opcode; + uint8_t subclassoptionaldata; + uint16_t subclassdata; std::vector<Constant*> operands; IndexList indices; bool operator==(const ExprMapKeyType& that) const { return this->opcode == that.opcode && - this->predicate == that.predicate && + this->subclassdata == that.subclassdata && + this->subclassoptionaldata == that.subclassoptionaldata && this->operands == that.operands && this->indices == that.indices; } bool operator<(const ExprMapKeyType & that) const { - return this->opcode < that.opcode || - (this->opcode == that.opcode && this->predicate < that.predicate) || - (this->opcode == that.opcode && this->predicate == that.predicate && - this->operands < that.operands) || - (this->opcode == that.opcode && this->predicate == that.predicate && - this->operands == that.operands && this->indices < that.indices); + if (this->opcode != that.opcode) return this->opcode < that.opcode; + if (this->operands != that.operands) return this->operands < that.operands; + if (this->subclassdata != that.subclassdata) + return this->subclassdata < that.subclassdata; + if (this->subclassoptionaldata != that.subclassoptionaldata) + return this->subclassoptionaldata < that.subclassoptionaldata; + if (this->indices != that.indices) return this->indices < that.indices; + return false; } bool operator!=(const ExprMapKeyType& that) const { @@ -354,7 +365,8 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { return new UnaryConstantExpr(V.opcode, V.operands[0], Ty); if ((V.opcode >= Instruction::BinaryOpsBegin && V.opcode < Instruction::BinaryOpsEnd)) - return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1]); + return new BinaryConstantExpr(V.opcode, V.operands[0], V.operands[1], + V.subclassoptionaldata); if (V.opcode == Instruction::Select) return new SelectConstantExpr(V.operands[0], V.operands[1], V.operands[2]); @@ -373,17 +385,18 @@ struct ConstantCreator<ConstantExpr, Type, ExprMapKeyType> { return new ExtractValueConstantExpr(V.operands[0], V.indices, Ty); if (V.opcode == Instruction::GetElementPtr) { std::vector<Constant*> IdxList(V.operands.begin()+1, V.operands.end()); - return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty); + return GetElementPtrConstantExpr::Create(V.operands[0], IdxList, Ty, + V.subclassoptionaldata); } // The compare instructions are weird. We have to encode the predicate // value and it is combined with the instruction opcode by multiplying // the opcode by one hundred. We must decode this to get the predicate. if (V.opcode == Instruction::ICmp) - return new CompareConstantExpr(Ty, Instruction::ICmp, V.predicate, + return new CompareConstantExpr(Ty, Instruction::ICmp, V.subclassdata, V.operands[0], V.operands[1]); if (V.opcode == Instruction::FCmp) - return new CompareConstantExpr(Ty, Instruction::FCmp, V.predicate, + return new CompareConstantExpr(Ty, Instruction::FCmp, V.subclassdata, V.operands[0], V.operands[1]); llvm_unreachable("Invalid ConstantExpr!"); return 0; diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 2d4ab55721..9d8e0477ee 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -1171,6 +1171,9 @@ bool GetElementPtrInst::hasAllConstantIndices() const { return true; } +void GetElementPtrInst::setIsInBounds(bool B) { + cast<GEPOperator>(this)->setIsInBounds(B); +} //===----------------------------------------------------------------------===// // ExtractElementInst Implementation @@ -1716,6 +1719,18 @@ bool BinaryOperator::swapOperands() { return false; } +void BinaryOperator::setHasNoUnsignedWrap(bool b) { + cast<OverflowingBinaryOperator>(this)->setHasNoUnsignedWrap(b); +} + +void BinaryOperator::setHasNoSignedWrap(bool b) { + cast<OverflowingBinaryOperator>(this)->setHasNoSignedWrap(b); +} + +void BinaryOperator::setIsExact(bool b) { + cast<SDivOperator>(this)->setIsExact(b); +} + //===----------------------------------------------------------------------===// // CastInst Class //===----------------------------------------------------------------------===// |