if (const ConstantFP *CFP = dyn_cast<ConstantFP>(this))
return CFP->isZero() && CFP->isNegative();
+ // Equivalent for a vector of -0.0's.
+ if (const ConstantDataVector *CV = dyn_cast<ConstantDataVector>(this))
+ if (ConstantFP *SplatCFP = dyn_cast_or_null<ConstantFP>(CV->getSplatValue()))
+ if (SplatCFP && SplatCFP->isZero() && SplatCFP->isNegative())
+ return true;
+
+ // We've already handled true FP case; any other FP vectors can't represent -0.0.
+ if (getType()->isFPOrFPVectorTy())
+ return false;
+
// Otherwise, just use +0.0.
return isNullValue();
}
delete this;
}
-/// canTrap - Return true if evaluation of this constant could trap. This is
-/// true for things like constant expressions that could divide by zero.
-bool Constant::canTrap() const {
- assert(getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
+static bool canTrapImpl(const Constant *C,
+ SmallPtrSet<const ConstantExpr *, 4> &NonTrappingOps) {
+ assert(C->getType()->isFirstClassType() && "Cannot evaluate aggregate vals!");
// The only thing that could possibly trap are constant exprs.
- const ConstantExpr *CE = dyn_cast<ConstantExpr>(this);
- if (!CE) return false;
+ const ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
+ if (!CE)
+ return false;
// ConstantExpr traps if any operands can trap.
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (CE->getOperand(i)->canTrap())
- return true;
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
+ if (ConstantExpr *Op = dyn_cast<ConstantExpr>(CE->getOperand(i))) {
+ if (NonTrappingOps.insert(Op) && canTrapImpl(Op, NonTrappingOps))
+ return true;
+ }
+ }
// Otherwise, only specific operations can trap.
switch (CE->getOpcode()) {
}
}
+/// canTrap - Return true if evaluation of this constant could trap. This is
+/// true for things like constant expressions that could divide by zero.
+bool Constant::canTrap() const {
+ SmallPtrSet<const ConstantExpr *, 4> NonTrappingOps;
+ return canTrapImpl(this, NonTrappingOps);
+}
+
/// isThreadDependent - Return true if the value can vary between threads.
bool Constant::isThreadDependent() const {
SmallPtrSet<const Constant*, 64> Visited;
// Get the corresponding integer type for the bit width of the value.
IntegerType *ITy = IntegerType::get(Context, V.getBitWidth());
// get an existing value or the insertion position
- DenseMapAPIntKeyInfo::KeyTy Key(V, ITy);
- ConstantInt *&Slot = Context.pImpl->IntConstants[Key];
+ LLVMContextImpl *pImpl = Context.pImpl;
+ ConstantInt *&Slot = pImpl->IntConstants[DenseMapAPIntKeyInfo::KeyTy(V, ITy)];
if (!Slot) Slot = new ConstantInt(ITy, V);
return Slot;
}
return C;
}
+Constant *ConstantFP::getNegativeZero(Type *Ty) {
+ const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
+ APFloat NegZero = APFloat::getZero(Semantics, /*Negative=*/true);
+ Constant *C = get(Ty->getContext(), NegZero);
-ConstantFP *ConstantFP::getNegativeZero(Type *Ty) {
- LLVMContext &Context = Ty->getContext();
- APFloat apf = cast<ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
- apf.changeSign();
- return get(Context, apf);
+ if (VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return ConstantVector::getSplat(VTy->getNumElements(), C);
+
+ return C;
}
Constant *ConstantFP::getZeroValueForNegation(Type *Ty) {
- Type *ScalarTy = Ty->getScalarType();
- if (ScalarTy->isFloatingPointTy()) {
- Constant *C = getNegativeZero(ScalarTy);
- if (VectorType *VTy = dyn_cast<VectorType>(Ty))
- return ConstantVector::getSplat(VTy->getNumElements(), C);
- return C;
- }
+ if (Ty->isFPOrFPVectorTy())
+ return getNegativeZero(Ty);
return Constant::getNullValue(Ty);
}
// ConstantFP accessors.
ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) {
- DenseMapAPFloatKeyInfo::KeyTy Key(V);
-
LLVMContextImpl* pImpl = Context.pImpl;
- ConstantFP *&Slot = pImpl->FPConstants[Key];
+ ConstantFP *&Slot = pImpl->FPConstants[DenseMapAPFloatKeyInfo::KeyTy(V)];
if (!Slot) {
Type *Ty;
return Slot;
}
-ConstantFP *ConstantFP::getInfinity(Type *Ty, bool Negative) {
- const fltSemantics &Semantics = *TypeToFloatSemantics(Ty);
- return ConstantFP::get(Ty->getContext(),
- APFloat::getInf(Semantics, Negative));
+Constant *ConstantFP::getInfinity(Type *Ty, bool Negative) {
+ const fltSemantics &Semantics = *TypeToFloatSemantics(Ty->getScalarType());
+ Constant *C = get(Ty->getContext(), APFloat::getInf(Semantics, Negative));
+
+ if (VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return ConstantVector::getSplat(VTy->getNumElements(), C);
+
+ return C;
}
ConstantFP::ConstantFP(Type *Ty, const APFloat& V)
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::AddrSpaceCast:
return ConstantExpr::getCast(getOpcode(), Ops[0], Ty);
case Instruction::Select:
return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
BB->AdjustBlockAddressRefCount(1);
}
+BlockAddress *BlockAddress::lookup(const BasicBlock *BB) {
+ if (!BB->hasAddressTaken())
+ return 0;
+
+ const Function *F = BB->getParent();
+ assert(F != 0 && "Block must have a parent");
+ BlockAddress *BA =
+ F->getContext().pImpl->BlockAddresses.lookup(std::make_pair(F, BB));
+ assert(BA && "Refcount and block address map disagree!");
+ return BA;
+}
// destroyConstant - Remove the constant from the constant table.
//
BasicBlock *NewBB = getBasicBlock();
if (U == &Op<0>())
- NewF = cast<Function>(To);
+ NewF = cast<Function>(To->stripPointerCasts());
else
NewBB = cast<BasicBlock>(To);
case Instruction::PtrToInt: return getPtrToInt(C, Ty);
case Instruction::IntToPtr: return getIntToPtr(C, Ty);
case Instruction::BitCast: return getBitCast(C, Ty);
+ case Instruction::AddrSpaceCast: return getAddrSpaceCast(C, Ty);
}
}
if (Ty->isIntOrIntVectorTy())
return getPtrToInt(S, Ty);
+
+ unsigned SrcAS = S->getType()->getPointerAddressSpace();
+ if (Ty->isPtrOrPtrVectorTy() && SrcAS != Ty->getPointerAddressSpace())
+ return getAddrSpaceCast(S, Ty);
+
return getBitCast(S, Ty);
}
-Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty,
+Constant *ConstantExpr::getPointerBitCastOrAddrSpaceCast(Constant *S,
+ Type *Ty) {
+ assert(S->getType()->isPtrOrPtrVectorTy() && "Invalid cast");
+ assert(Ty->isPtrOrPtrVectorTy() && "Invalid cast");
+
+ if (S->getType()->getPointerAddressSpace() != Ty->getPointerAddressSpace())
+ return getAddrSpaceCast(S, Ty);
+
+ return getBitCast(S, Ty);
+}
+
+Constant *ConstantExpr::getIntegerCast(Constant *C, Type *Ty,
bool isSigned) {
assert(C->getType()->isIntOrIntVectorTy() &&
Ty->isIntOrIntVectorTy() && "Invalid cast");
return getFoldedCast(Instruction::BitCast, C, DstTy);
}
+Constant *ConstantExpr::getAddrSpaceCast(Constant *C, Type *DstTy) {
+ assert(CastInst::castIsValid(Instruction::AddrSpaceCast, C, DstTy) &&
+ "Invalid constantexpr addrspacecast!");
+
+ return getFoldedCast(Instruction::AddrSpaceCast, C, DstTy);
+}
+
Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2,
unsigned Flags) {
// Check the operands for consistency first.
Constant *ConstantExpr::getInsertValue(Constant *Agg, Constant *Val,
ArrayRef<unsigned> Idxs) {
+ assert(Agg->getType()->isFirstClassType() &&
+ "Non-first-class type for constant insertvalue expression");
+
assert(ExtractValueInst::getIndexedType(Agg->getType(),
Idxs) == Val->getType() &&
"insertvalue indices invalid!");
- assert(Agg->getType()->isFirstClassType() &&
- "Non-first-class type for constant insertvalue expression");
- Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs);
- assert(FC && "insertvalue constant expr couldn't be folded!");
- return FC;
+ Type *ReqTy = Val->getType();
+
+ if (Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs))
+ return FC;
+
+ Constant *ArgVec[] = { Agg, Val };
+ const ExprMapKeyType Key(Instruction::InsertValue, ArgVec, 0, 0, Idxs);
+
+ LLVMContextImpl *pImpl = Agg->getContext().pImpl;
+ return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getExtractValue(Constant *Agg,
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
- Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs);
- assert(FC && "ExtractValue constant expr couldn't be folded!");
- return FC;
+ if (Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs))
+ return FC;
+
+ Constant *ArgVec[] = { Agg };
+ const ExprMapKeyType Key(Instruction::ExtractValue, ArgVec, 0, 0, Idxs);
+
+ LLVMContextImpl *pImpl = Agg->getContext().pImpl;
+ return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getNeg(Constant *C, bool HasNUW, bool HasNSW) {
case Instruction::PtrToInt:
case Instruction::IntToPtr:
case Instruction::BitCast:
+ case Instruction::AddrSpaceCast:
return CastInst::Create((Instruction::CastOps)getOpcode(),
Ops[0], getType());
case Instruction::Select: