summaryrefslogtreecommitdiff
path: root/lib/VMCore
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore')
-rw-r--r--lib/VMCore/Constants.cpp89
-rw-r--r--lib/VMCore/ConstantsContext.h49
-rw-r--r--lib/VMCore/Instructions.cpp15
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
//===----------------------------------------------------------------------===//