//
//===----------------------------------------------------------------------===//
//
-// This file implements the Constant* classes...
+// This file implements the Constant* classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/GetElementPtrTypeIterator.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/RWMutex.h"
-#include "llvm/System/Threading.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include <algorithm>
// Constructor to create a '0' constant of arbitrary type...
static const uint64_t zero[2] = {0, 0};
-Constant* Constant::getNullValue(const Type* Ty) {
+Constant *Constant::getNullValue(const Type *Ty) {
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
return ConstantInt::get(Ty, 0);
}
}
-Constant* Constant::getIntegerValue(const Type* Ty, const APInt &V) {
+Constant* Constant::getIntegerValue(const Type *Ty, const APInt &V) {
const Type *ScalarTy = Ty->getScalarType();
// Create the base integer constant.
return C;
}
-Constant* Constant::getAllOnesValue(const Type* Ty) {
- if (const IntegerType* ITy = dyn_cast<IntegerType>(Ty))
+Constant* Constant::getAllOnesValue(const Type *Ty) {
+ if (const IntegerType *ITy = dyn_cast<IntegerType>(Ty))
return ConstantInt::get(Ty->getContext(),
APInt::getAllOnesValue(ITy->getBitWidth()));
std::vector<Constant*> Elts;
- const VectorType* VTy = cast<VectorType>(Ty);
+ const VectorType *VTy = cast<VectorType>(Ty);
Elts.resize(VTy->getNumElements(), getAllOnesValue(VTy->getElementType()));
assert(Elts[0] && "Not a vector integer type!");
return cast<ConstantVector>(ConstantVector::get(Elts));
Value *V = use_back();
#ifndef NDEBUG // Only in -g mode...
if (!isa<Constant>(V)) {
- errs() << "While deleting: " << *this
+ dbgs() << "While deleting: " << *this
<< "\n\nUse still stuck around after Def is destroyed: "
<< *V << "\n\n";
}
// ConstantExpr traps if any operands can trap.
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- if (getOperand(i)->canTrap())
+ if (CE->getOperand(i)->canTrap())
return true;
// Otherwise, only specific operations can trap.
case Instruction::SRem:
case Instruction::FRem:
// Div and rem can trap if the RHS is not known to be non-zero.
- if (!isa<ConstantInt>(getOperand(1)) || getOperand(1)->isNullValue())
+ if (!isa<ConstantInt>(CE->getOperand(1)) ||CE->getOperand(1)->isNullValue())
return true;
return false;
}
}
+/// isConstantUsed - Return true if the constant has users other than constant
+/// exprs and other dangling things.
+bool Constant::isConstantUsed() const {
+ for (const_use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+ const Constant *UC = dyn_cast<Constant>(*UI);
+ if (UC == 0 || isa<GlobalValue>(UC))
+ return true;
+
+ if (UC->isConstantUsed())
+ return true;
+ }
+ return false;
+}
+
+
/// getRelocationInfo - This method classifies the entry according to
/// whether or not it may generate a relocation entry. This must be
return GlobalRelocations; // Global reference.
}
+ if (const BlockAddress *BA = dyn_cast<BlockAddress>(this))
+ return BA->getFunction()->getRelocationInfo();
+
+ // While raw uses of blockaddress need to be relocated, differences between
+ // two of them don't when they are for labels in the same function. This is a
+ // common idiom when creating a table for the indirect goto extension, so we
+ // handle it efficiently here.
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(this))
+ if (CE->getOpcode() == Instruction::Sub) {
+ ConstantExpr *LHS = dyn_cast<ConstantExpr>(CE->getOperand(0));
+ ConstantExpr *RHS = dyn_cast<ConstantExpr>(CE->getOperand(1));
+ if (LHS && RHS &&
+ LHS->getOpcode() == Instruction::PtrToInt &&
+ RHS->getOpcode() == Instruction::PtrToInt &&
+ isa<BlockAddress>(LHS->getOperand(0)) &&
+ isa<BlockAddress>(RHS->getOperand(0)) &&
+ cast<BlockAddress>(LHS->getOperand(0))->getFunction() ==
+ cast<BlockAddress>(RHS->getOperand(0))->getFunction())
+ return NoRelocation;
+ }
+
PossibleRelocationsTy Result = NoRelocation;
for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
- Result = std::max(Result, getOperand(i)->getRelocationInfo());
+ Result = std::max(Result,
+ cast<Constant>(getOperand(i))->getRelocationInfo());
return Result;
}
/// type, returns the elements of the vector in the specified smallvector.
/// This handles breaking down a vector undef into undef elements, etc. For
/// constant exprs and other cases we can't handle, we return an empty vector.
-void Constant::getVectorElements(LLVMContext &Context,
- SmallVectorImpl<Constant*> &Elts) const {
- assert(isa<VectorType>(getType()) && "Not a vector constant!");
+void Constant::getVectorElements(SmallVectorImpl<Constant*> &Elts) const {
+ assert(getType()->isVectorTy() && "Not a vector constant!");
if (const ConstantVector *CV = dyn_cast<ConstantVector>(this)) {
for (unsigned i = 0, e = CV->getNumOperands(); i != e; ++i)
ConstantInt* ConstantInt::getTrue(LLVMContext &Context) {
LLVMContextImpl *pImpl = Context.pImpl;
- sys::SmartScopedWriter<true>(pImpl->ConstantsLock);
if (pImpl->TheTrueVal)
return pImpl->TheTrueVal;
else
ConstantInt* ConstantInt::getFalse(LLVMContext &Context) {
LLVMContextImpl *pImpl = Context.pImpl;
- sys::SmartScopedWriter<true>(pImpl->ConstantsLock);
if (pImpl->TheFalseVal)
return pImpl->TheFalseVal;
else
const IntegerType *ITy = IntegerType::get(Context, V.getBitWidth());
// get an existing value or the insertion position
DenseMapAPIntKeyInfo::KeyTy Key(V, ITy);
-
- Context.pImpl->ConstantsLock.reader_acquire();
ConstantInt *&Slot = Context.pImpl->IntConstants[Key];
- Context.pImpl->ConstantsLock.reader_release();
-
- if (!Slot) {
- sys::SmartScopedWriter<true> Writer(Context.pImpl->ConstantsLock);
- ConstantInt *&NewSlot = Context.pImpl->IntConstants[Key];
- if (!Slot) {
- NewSlot = new ConstantInt(ITy, V);
- }
-
- return NewSlot;
- } else {
- return Slot;
- }
+ if (!Slot) Slot = new ConstantInt(ITy, V);
+ return Slot;
}
Constant* ConstantInt::get(const Type* Ty, uint64_t V, bool isSigned) {
return C;
}
-ConstantInt* ConstantInt::get(const IntegerType* Ty, const StringRef& Str,
+ConstantInt* ConstantInt::get(const IntegerType* Ty, StringRef Str,
uint8_t radix) {
return get(Ty->getContext(), APInt(Ty->getBitWidth(), Str, radix));
}
//===----------------------------------------------------------------------===//
static const fltSemantics *TypeToFloatSemantics(const Type *Ty) {
- if (Ty == Type::getFloatTy(Ty->getContext()))
+ if (Ty->isFloatTy())
return &APFloat::IEEEsingle;
- if (Ty == Type::getDoubleTy(Ty->getContext()))
+ if (Ty->isDoubleTy())
return &APFloat::IEEEdouble;
- if (Ty == Type::getX86_FP80Ty(Ty->getContext()))
+ if (Ty->isX86_FP80Ty())
return &APFloat::x87DoubleExtended;
- else if (Ty == Type::getFP128Ty(Ty->getContext()))
+ else if (Ty->isFP128Ty())
return &APFloat::IEEEquad;
- assert(Ty == Type::getPPC_FP128Ty(Ty->getContext()) && "Unknown FP format");
+ assert(Ty->isPPC_FP128Ty() && "Unknown FP format");
return &APFloat::PPCDoubleDouble;
}
}
-Constant* ConstantFP::get(const Type* Ty, const StringRef& Str) {
+Constant* ConstantFP::get(const Type* Ty, StringRef Str) {
LLVMContext &Context = Ty->getContext();
APFloat FV(*TypeToFloatSemantics(Ty->getScalarType()), Str);
Constant* ConstantFP::getZeroValueForNegation(const Type* Ty) {
if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
- if (PTy->getElementType()->isFloatingPoint()) {
+ if (PTy->getElementType()->isFloatingPointTy()) {
std::vector<Constant*> zeros(PTy->getNumElements(),
getNegativeZero(PTy->getElementType()));
return ConstantVector::get(PTy, zeros);
}
- if (Ty->isFloatingPoint())
+ if (Ty->isFloatingPointTy())
return getNegativeZero(Ty);
return Constant::getNullValue(Ty);
LLVMContextImpl* pImpl = Context.pImpl;
- pImpl->ConstantsLock.reader_acquire();
ConstantFP *&Slot = pImpl->FPConstants[Key];
- pImpl->ConstantsLock.reader_release();
if (!Slot) {
- sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
- ConstantFP *&NewSlot = pImpl->FPConstants[Key];
- if (!NewSlot) {
- const Type *Ty;
- if (&V.getSemantics() == &APFloat::IEEEsingle)
- Ty = Type::getFloatTy(Context);
- else if (&V.getSemantics() == &APFloat::IEEEdouble)
- Ty = Type::getDoubleTy(Context);
- else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
- Ty = Type::getX86_FP80Ty(Context);
- else if (&V.getSemantics() == &APFloat::IEEEquad)
- Ty = Type::getFP128Ty(Context);
- else {
- assert(&V.getSemantics() == &APFloat::PPCDoubleDouble &&
- "Unknown FP format");
- Ty = Type::getPPC_FP128Ty(Context);
- }
- NewSlot = new ConstantFP(Ty, V);
+ const Type *Ty;
+ if (&V.getSemantics() == &APFloat::IEEEsingle)
+ Ty = Type::getFloatTy(Context);
+ else if (&V.getSemantics() == &APFloat::IEEEdouble)
+ Ty = Type::getDoubleTy(Context);
+ else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
+ Ty = Type::getX86_FP80Ty(Context);
+ else if (&V.getSemantics() == &APFloat::IEEEquad)
+ Ty = Type::getFP128Ty(Context);
+ else {
+ assert(&V.getSemantics() == &APFloat::PPCDoubleDouble &&
+ "Unknown FP format");
+ Ty = Type::getPPC_FP128Ty(Context);
}
-
- return NewSlot;
+ Slot = new ConstantFP(Ty, V);
}
return Slot;
// If this is an all-zero array, return a ConstantAggregateZero object
if (!V.empty()) {
Constant *C = V[0];
- if (!C->isNullValue()) {
- // Implicitly locked.
+ if (!C->isNullValue())
return pImpl->ArrayConstants.getOrCreate(Ty, V);
- }
+
for (unsigned i = 1, e = V.size(); i != e; ++i)
- if (V[i] != C) {
- // Implicitly locked.
+ if (V[i] != C)
return pImpl->ArrayConstants.getOrCreate(Ty, V);
- }
}
return ConstantAggregateZero::get(Ty);
/// Otherwise, the length parameter specifies how much of the string to use
/// and it won't be null terminated.
///
-Constant* ConstantArray::get(LLVMContext &Context, const StringRef &Str,
+Constant* ConstantArray::get(LLVMContext &Context, StringRef Str,
bool AddNull) {
std::vector<Constant*> ElementVals;
+ ElementVals.reserve(Str.size() + size_t(AddNull));
for (unsigned i = 0; i < Str.size(); ++i)
ElementVals.push_back(ConstantInt::get(Type::getInt8Ty(Context), Str[i]));
// Create a ConstantAggregateZero value if all elements are zeros...
for (unsigned i = 0, e = V.size(); i != e; ++i)
if (!V[i]->isNullValue())
- // Implicitly locked.
return pImpl->StructConstants.getOrCreate(T, V);
return ConstantAggregateZero::get(T);
if (isUndef)
return UndefValue::get(T);
- // Implicitly locked.
return pImpl->VectorConstants.getOrCreate(T, V);
}
return get(std::vector<Constant*>(Vals, Vals+NumVals));
}
+Constant* ConstantExpr::getNSWNeg(Constant* C) {
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ "Cannot NEG a nonintegral value!");
+ return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+}
+
+Constant* ConstantExpr::getNUWNeg(Constant* C) {
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ "Cannot NEG a nonintegral value!");
+ return getNUWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+}
+
Constant* ConstantExpr::getNSWAdd(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::Add, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
+Constant* ConstantExpr::getNUWAdd(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Add, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
Constant* ConstantExpr::getNSWSub(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::Sub, C1, C2,
OverflowingBinaryOperator::NoSignedWrap);
}
+Constant* ConstantExpr::getNUWSub(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Sub, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
+Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Mul, C1, C2,
+ OverflowingBinaryOperator::NoSignedWrap);
+}
+
+Constant* ConstantExpr::getNUWMul(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Mul, C1, C2,
+ OverflowingBinaryOperator::NoUnsignedWrap);
+}
+
Constant* ConstantExpr::getExactSDiv(Constant* C1, Constant* C2) {
return getTy(C1->getType(), Instruction::SDiv, C1, C2,
SDivOperator::IsExact);
if (getOpcode() != Instruction::GetElementPtr) return false;
gep_type_iterator GEPI = gep_type_begin(this), E = gep_type_end(this);
- User::const_op_iterator OI = next(this->op_begin());
+ User::const_op_iterator OI = llvm::next(this->op_begin());
// Skip the first index, as it has no static limit.
++GEPI;
ConstantExpr::getGetElementPtr(Op, &Ops[0], Ops.size());
Ops[OpNo-1] = Op;
return cast<GEPOperator>(this)->isInBounds() ?
- ConstantExpr::getInBoundsGetElementPtr(getOperand(0), &Ops[0], Ops.size()) :
+ 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, SubclassData);
+ return ConstantExpr::get(getOpcode(), Op0, Op1, SubclassOptionalData);
}
}
return ConstantExpr::getCompare(getPredicate(), Ops[0], Ops[1]);
default:
assert(getNumOperands() == 2 && "Must be binary operator?");
- return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassData);
+ return ConstantExpr::get(getOpcode(), Ops[0], Ops[1], SubclassOptionalData);
}
}
// Factory Function Implementation
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
- assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
+ assert((Ty->isStructTy() || Ty->isArrayTy() || Ty->isVectorTy()) &&
"Cannot create an aggregate zero of non-aggregate type!");
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
- // Implicitly locked.
return pImpl->AggZeroConstants.getOrCreate(Ty, 0);
}
/// destroyConstant - Remove the constant from the constant table...
///
void ConstantAggregateZero::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->AggZeroConstants.remove(this);
+ getRawType()->getContext().pImpl->AggZeroConstants.remove(this);
destroyConstantImpl();
}
/// destroyConstant - Remove the constant from the constant table...
///
void ConstantArray::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->ArrayConstants.remove(this);
+ getRawType()->getContext().pImpl->ArrayConstants.remove(this);
destroyConstantImpl();
}
/// if the elements of the array are all ConstantInt's.
bool ConstantArray::isString() const {
// Check the element type for i8...
- if (getType()->getElementType() != Type::getInt8Ty(getContext()))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Check the elements to make sure they are all integers, not constant
// expressions.
/// null bytes except its terminator.
bool ConstantArray::isCString() const {
// Check the element type for i8...
- if (getType()->getElementType() != Type::getInt8Ty(getContext()))
+ if (!getType()->getElementType()->isIntegerTy(8))
return false;
// Last element must be a null.
// destroyConstant - Remove the constant from the constant table...
//
void ConstantStruct::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->StructConstants.remove(this);
+ getRawType()->getContext().pImpl->StructConstants.remove(this);
destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantVector::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->VectorConstants.remove(this);
+ getRawType()->getContext().pImpl->VectorConstants.remove(this);
destroyConstantImpl();
}
return Elt;
}
-//---- ConstantPointerNull::get() implementation...
+//---- ConstantPointerNull::get() implementation.
//
ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) {
- // Implicitly locked.
return Ty->getContext().pImpl->NullPtrConstants.getOrCreate(Ty, 0);
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantPointerNull::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->NullPtrConstants.remove(this);
+ getRawType()->getContext().pImpl->NullPtrConstants.remove(this);
destroyConstantImpl();
}
-//---- UndefValue::get() implementation...
+//---- UndefValue::get() implementation.
//
UndefValue *UndefValue::get(const Type *Ty) {
- // Implicitly locked.
return Ty->getContext().pImpl->UndefValueConstants.getOrCreate(Ty, 0);
}
// destroyConstant - Remove the constant from the constant table.
//
void UndefValue::destroyConstant() {
- // Implicitly locked.
- getType()->getContext().pImpl->UndefValueConstants.remove(this);
+ getRawType()->getContext().pImpl->UndefValueConstants.remove(this);
+ destroyConstantImpl();
+}
+
+//---- BlockAddress::get() implementation.
+//
+
+BlockAddress *BlockAddress::get(BasicBlock *BB) {
+ assert(BB->getParent() != 0 && "Block must have a parent");
+ return get(BB->getParent(), BB);
+}
+
+BlockAddress *BlockAddress::get(Function *F, BasicBlock *BB) {
+ BlockAddress *&BA =
+ F->getContext().pImpl->BlockAddresses[std::make_pair(F, BB)];
+ if (BA == 0)
+ BA = new BlockAddress(F, BB);
+
+ assert(BA->getFunction() == F && "Basic block moved between functions");
+ return BA;
+}
+
+BlockAddress::BlockAddress(Function *F, BasicBlock *BB)
+: Constant(Type::getInt8PtrTy(F->getContext()), Value::BlockAddressVal,
+ &Op<0>(), 2) {
+ setOperand(0, F);
+ setOperand(1, BB);
+ BB->AdjustBlockAddressRefCount(1);
+}
+
+
+// destroyConstant - Remove the constant from the constant table.
+//
+void BlockAddress::destroyConstant() {
+ getFunction()->getRawType()->getContext().pImpl
+ ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
+ getBasicBlock()->AdjustBlockAddressRefCount(-1);
destroyConstantImpl();
}
-//---- ConstantExpr::get() implementations...
+void BlockAddress::replaceUsesOfWithOnConstant(Value *From, Value *To, Use *U) {
+ // This could be replacing either the Basic Block or the Function. In either
+ // case, we have to remove the map entry.
+ Function *NewF = getFunction();
+ BasicBlock *NewBB = getBasicBlock();
+
+ if (U == &Op<0>())
+ NewF = cast<Function>(To);
+ else
+ NewBB = cast<BasicBlock>(To);
+
+ // See if the 'new' entry already exists, if not, just update this in place
+ // and return early.
+ BlockAddress *&NewBA =
+ getContext().pImpl->BlockAddresses[std::make_pair(NewF, NewBB)];
+ if (NewBA == 0) {
+ getBasicBlock()->AdjustBlockAddressRefCount(-1);
+
+ // Remove the old entry, this can't cause the map to rehash (just a
+ // tombstone will get added).
+ getContext().pImpl->BlockAddresses.erase(std::make_pair(getFunction(),
+ getBasicBlock()));
+ NewBA = this;
+ setOperand(0, NewF);
+ setOperand(1, NewBB);
+ getBasicBlock()->AdjustBlockAddressRefCount(1);
+ return;
+ }
+
+ // Otherwise, I do need to replace this with an existing value.
+ assert(NewBA != this && "I didn't contain From!");
+
+ // Everyone using this now uses the replacement.
+ uncheckedReplaceAllUsesWith(NewBA);
+
+ destroyConstant();
+}
+
+//---- ConstantExpr::get() implementations.
//
/// This is a utility function to handle folding of casts and lookup of the
Instruction::CastOps opc, Constant *C, const Type *Ty) {
assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
// Fold a few common cases
- if (Constant *FC = ConstantFoldCastInstruction(Ty->getContext(), opc, C, Ty))
+ if (Constant *FC = ConstantFoldCastInstruction(opc, C, Ty))
return FC;
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
std::vector<Constant*> argVec(1, C);
ExprMapKeyType Key(opc, argVec);
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(Ty, Key);
}
Instruction::CastOps opc = Instruction::CastOps(oc);
assert(Instruction::isCast(opc) && "opcode out of range");
assert(C && Ty && "Null arguments to getCast");
- assert(Ty->isFirstClassType() && "Cannot cast to an aggregate type!");
+ assert(CastInst::castIsValid(opc, C, Ty) && "Invalid constantexpr cast!");
switch (opc) {
- default:
- llvm_unreachable("Invalid cast opcode");
- break;
- case Instruction::Trunc: return getTrunc(C, Ty);
- case Instruction::ZExt: return getZExt(C, Ty);
- case Instruction::SExt: return getSExt(C, Ty);
- case Instruction::FPTrunc: return getFPTrunc(C, Ty);
- case Instruction::FPExt: return getFPExtend(C, Ty);
- case Instruction::UIToFP: return getUIToFP(C, Ty);
- case Instruction::SIToFP: return getSIToFP(C, Ty);
- case Instruction::FPToUI: return getFPToUI(C, Ty);
- case Instruction::FPToSI: return getFPToSI(C, Ty);
- case Instruction::PtrToInt: return getPtrToInt(C, Ty);
- case Instruction::IntToPtr: return getIntToPtr(C, Ty);
- case Instruction::BitCast: return getBitCast(C, Ty);
+ default:
+ llvm_unreachable("Invalid cast opcode");
+ break;
+ case Instruction::Trunc: return getTrunc(C, Ty);
+ case Instruction::ZExt: return getZExt(C, Ty);
+ case Instruction::SExt: return getSExt(C, Ty);
+ case Instruction::FPTrunc: return getFPTrunc(C, Ty);
+ case Instruction::FPExt: return getFPExtend(C, Ty);
+ case Instruction::UIToFP: return getUIToFP(C, Ty);
+ case Instruction::SIToFP: return getSIToFP(C, Ty);
+ case Instruction::FPToUI: return getFPToUI(C, Ty);
+ case Instruction::FPToSI: return getFPToSI(C, Ty);
+ case Instruction::PtrToInt: return getPtrToInt(C, Ty);
+ case Instruction::IntToPtr: return getIntToPtr(C, Ty);
+ case Instruction::BitCast: return getBitCast(C, Ty);
}
return 0;
}
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::ZExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getZExt(C, Ty);
}
Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::SExt, C, Ty);
+ return getBitCast(C, Ty);
+ return getSExt(C, Ty);
}
Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
- return getCast(Instruction::BitCast, C, Ty);
- return getCast(Instruction::Trunc, C, Ty);
+ return getBitCast(C, Ty);
+ return getTrunc(C, Ty);
}
Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
- assert(isa<PointerType>(S->getType()) && "Invalid cast");
- assert((Ty->isInteger() || isa<PointerType>(Ty)) && "Invalid cast");
+ assert(S->getType()->isPointerTy() && "Invalid cast");
+ assert((Ty->isIntegerTy() || Ty->isPointerTy()) && "Invalid cast");
- if (Ty->isInteger())
- return getCast(Instruction::PtrToInt, S, Ty);
- return getCast(Instruction::BitCast, S, Ty);
+ if (Ty->isIntegerTy())
+ return getPtrToInt(S, Ty);
+ return getBitCast(S, Ty);
}
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
bool isSigned) {
- assert(C->getType()->isIntOrIntVector() &&
- Ty->isIntOrIntVector() && "Invalid cast");
+ assert(C->getType()->isIntOrIntVectorTy() &&
+ Ty->isIntOrIntVectorTy() && "Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
}
Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
"Invalid cast");
unsigned SrcBits = C->getType()->getScalarSizeInBits();
unsigned DstBits = Ty->getScalarSizeInBits();
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "Trunc operand must be integer");
- assert(Ty->isIntOrIntVector() && "Trunc produces only integral");
+ assert(C->getType()->isIntOrIntVectorTy() && "Trunc operand must be integer");
+ assert(Ty->isIntOrIntVectorTy() && "Trunc produces only integral");
assert(C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"SrcTy must be larger than DestTy for Trunc!");
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "SExt operand must be integral");
- assert(Ty->isIntOrIntVector() && "SExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "SExt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "SExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for SExt!");
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && "ZEXt operand must be integral");
- assert(Ty->isIntOrIntVector() && "ZExt produces only integer");
+ assert(C->getType()->isIntOrIntVectorTy() && "ZEXt operand must be integral");
+ assert(Ty->isIntOrIntVectorTy() && "ZExt produces only integer");
assert(C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for ZExt!");
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"This is an illegal floating point truncation!");
return getFoldedCast(Instruction::FPTrunc, C, Ty);
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isFPOrFPVectorTy() &&
C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"This is an illegal floating point extension!");
return getFoldedCast(Instruction::FPExt, C, Ty);
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal uint to floating point cast!");
return getFoldedCast(Instruction::UIToFP, C, Ty);
}
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isIntOrIntVector() && Ty->isFPOrFPVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() && Ty->isFPOrFPVectorTy() &&
"This is an illegal sint to floating point cast!");
return getFoldedCast(Instruction::SIToFP, C, Ty);
}
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to uint cast!");
return getFoldedCast(Instruction::FPToUI, C, Ty);
}
bool toVec = Ty->getTypeID() == Type::VectorTyID;
#endif
assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
- assert(C->getType()->isFPOrFPVector() && Ty->isIntOrIntVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() && Ty->isIntOrIntVectorTy() &&
"This is an illegal floating point to sint cast!");
return getFoldedCast(Instruction::FPToSI, C, Ty);
}
Constant *ConstantExpr::getPtrToInt(Constant *C, const Type *DstTy) {
- assert(isa<PointerType>(C->getType()) && "PtrToInt source must be pointer");
- assert(DstTy->isInteger() && "PtrToInt destination must be integral");
+ assert(C->getType()->isPointerTy() && "PtrToInt source must be pointer");
+ assert(DstTy->isIntegerTy() && "PtrToInt destination must be integral");
return getFoldedCast(Instruction::PtrToInt, C, DstTy);
}
Constant *ConstantExpr::getIntToPtr(Constant *C, const Type *DstTy) {
- assert(C->getType()->isInteger() && "IntToPtr source must be integral");
- assert(isa<PointerType>(DstTy) && "IntToPtr destination must be a pointer");
+ assert(C->getType()->isIntegerTy() && "IntToPtr source must be integral");
+ assert(DstTy->isPointerTy() && "IntToPtr destination must be a pointer");
return getFoldedCast(Instruction::IntToPtr, C, DstTy);
}
Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
- // BitCast implies a no-op cast of type only. No bits change. However, you
- // can't cast pointers to anything but pointers.
-#ifndef NDEBUG
- const Type *SrcTy = C->getType();
- assert((isa<PointerType>(SrcTy) == isa<PointerType>(DstTy)) &&
- "BitCast cannot cast pointer to non-pointer and vice versa");
-
- // Now we know we're not dealing with mismatched pointer casts (ptr->nonptr
- // or nonptr->ptr). For all the other types, the cast is okay if source and
- // destination bit widths are identical.
- unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits();
- unsigned DstBitSize = DstTy->getPrimitiveSizeInBits();
-#endif
- assert(SrcBitSize == DstBitSize && "BitCast requires types of same width");
+ assert(CastInst::castIsValid(Instruction::BitCast, C, DstTy) &&
+ "Invalid constantexpr bitcast!");
// It is common to ask for a bitcast of a value to its own type, handle this
// speedily.
"Operand types in binary constant expression should match");
if (ReqTy == C1->getType() || ReqTy == Type::getInt1Ty(ReqTy->getContext()))
- if (Constant *FC = ConstantFoldBinaryInstruction(ReqTy->getContext(),
- Opcode, C1, C2))
+ if (Constant *FC = ConstantFoldBinaryInstruction(Opcode, C1, C2))
return FC; // Fold a few common cases...
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
ExprMapKeyType Key(Opcode, argVec, 0, Flags);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
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;
- else if (Opcode == Instruction::Sub) Opcode = Instruction::FSub;
- else if (Opcode == Instruction::Mul) Opcode = Instruction::FMul;
- }
#ifndef NDEBUG
switch (Opcode) {
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an integer operation on a non-integer type!");
break;
case Instruction::FAdd:
case Instruction::FSub:
case Instruction::FMul:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create a floating-point operation on a "
"non-floating-point type!");
break;
case Instruction::UDiv:
case Instruction::SDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::URem:
case Instruction::SRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::FRem:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isFPOrFPVector() &&
+ assert(C1->getType()->isFPOrFPVectorTy() &&
"Tried to create an arithmetic operation on a non-arithmetic type!");
break;
case Instruction::And:
case Instruction::Or:
case Instruction::Xor:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::Shl:
case Instruction::LShr:
case Instruction::AShr:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert(C1->getType()->isIntOrIntVector() &&
+ assert(C1->getType()->isIntOrIntVectorTy() &&
"Tried to create a shift operation on a non-integer type!");
break;
default:
Constant *GEPIdx = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *GEP = getGetElementPtr(
Constant::getNullValue(PointerType::getUnqual(Ty)), &GEPIdx, 1);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getAlignOf(const Type* Ty) {
- // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1
+ // alignof is implemented as: (i64) gep ({i1,Ty}*)null, 0, 1
// Note that a non-inbounds gep is used, as null isn't within any object.
const Type *AligningTy = StructType::get(Ty->getContext(),
- Type::getInt8Ty(Ty->getContext()), Ty, NULL);
+ Type::getInt1Ty(Ty->getContext()), Ty, NULL);
Constant *NullPtr = Constant::getNullValue(AligningTy->getPointerTo());
- Constant *Zero = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 0);
+ Constant *Zero = ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0);
Constant *One = ConstantInt::get(Type::getInt32Ty(Ty->getContext()), 1);
Constant *Indices[2] = { Zero, One };
Constant *GEP = getGetElementPtr(NullPtr, Indices, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt32Ty(Ty->getContext()));
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant* ConstantExpr::getOffsetOf(const StructType* STy, unsigned FieldNo) {
+ return getOffsetOf(STy, ConstantInt::get(Type::getInt32Ty(STy->getContext()),
+ FieldNo));
+}
+
+Constant* ConstantExpr::getOffsetOf(const Type* Ty, Constant *FieldNo) {
// offsetof is implemented as: (i64) gep (Ty*)null, 0, FieldNo
// Note that a non-inbounds gep is used, as null isn't within any object.
Constant *GEPIdx[] = {
- ConstantInt::get(Type::getInt64Ty(STy->getContext()), 0),
- ConstantInt::get(Type::getInt32Ty(STy->getContext()), FieldNo)
+ ConstantInt::get(Type::getInt64Ty(Ty->getContext()), 0),
+ FieldNo
};
Constant *GEP = getGetElementPtr(
- Constant::getNullValue(PointerType::getUnqual(STy)), GEPIdx, 2);
- return getCast(Instruction::PtrToInt, GEP,
- Type::getInt64Ty(STy->getContext()));
+ Constant::getNullValue(PointerType::getUnqual(Ty)), GEPIdx, 2);
+ return getPtrToInt(GEP,
+ Type::getInt64Ty(Ty->getContext()));
}
Constant *ConstantExpr::getCompare(unsigned short pred,
assert(!SelectInst::areInvalidOperands(C, V1, V2)&&"Invalid select operands");
if (ReqTy == V1->getType())
- if (Constant *SC = ConstantFoldSelectInstruction(
- ReqTy->getContext(), C, V1, V2))
+ if (Constant *SC = ConstantFoldSelectInstruction(C, V1, V2))
return SC; // Fold common cases
std::vector<Constant*> argVec(3, C);
ExprMapKeyType Key(Instruction::Select, argVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
cast<PointerType>(ReqTy)->getElementType() &&
"GEP indices invalid!");
- if (Constant *FC = ConstantFoldGetElementPtr(
- ReqTy->getContext(), C, /*inBounds=*/false,
- (Constant**)Idxs, NumIdx))
+ if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/false,
+ (Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
- assert(isa<PointerType>(C->getType()) &&
+ assert(C->getType()->isPointerTy() &&
"Non-pointer type for constant GetElementPtr expression");
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getInBoundsGetElementPtrTy(const Type *ReqTy,
Constant *C,
- Value* const *Idxs,
+ 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, /*inBounds=*/true,
- (Constant**)Idxs, NumIdx))
+ if (Constant *FC = ConstantFoldGetElementPtr(C, /*inBounds=*/true,
+ (Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
- assert(isa<PointerType>(C->getType()) &&
+ assert(C->getType()->isPointerTy() &&
"Non-pointer type for constant GetElementPtr expression");
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec;
GEPOperator::IsInBounds);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
}
Constant *
-ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ConstantExpr::getICmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred >= ICmpInst::FIRST_ICMP_PREDICATE &&
pred <= ICmpInst::LAST_ICMP_PREDICATE && "Invalid ICmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(
- LHS->getContext(), pred, LHS, RHS))
+ if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
- LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
+ const Type *ResultTy = Type::getInt1Ty(LHS->getContext());
+ if (const VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
+ ResultTy = VectorType::get(ResultTy, VT->getNumElements());
- // Implicitly locked.
- return
- pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
+ LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
+ return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
}
Constant *
-ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
+ConstantExpr::getFCmp(unsigned short pred, Constant *LHS, Constant *RHS) {
assert(LHS->getType() == RHS->getType());
assert(pred <= FCmpInst::LAST_FCMP_PREDICATE && "Invalid FCmp Predicate");
- if (Constant *FC = ConstantFoldCompareInstruction(
- LHS->getContext(), pred, LHS, RHS))
+ if (Constant *FC = ConstantFoldCompareInstruction(pred, LHS, RHS))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
-
+
+ const Type *ResultTy = Type::getInt1Ty(LHS->getContext());
+ if (const VectorType *VT = dyn_cast<VectorType>(LHS->getType()))
+ ResultTy = VectorType::get(ResultTy, VT->getNumElements());
+
LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
-
- // Implicitly locked.
- return
- pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
+ return pImpl->ExprConstants.getOrCreate(ResultTy, Key);
}
Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
Constant *Idx) {
- if (Constant *FC = ConstantFoldExtractElementInstruction(
- ReqTy->getContext(), Val, Idx))
- return FC; // Fold a few common cases...
+ if (Constant *FC = ConstantFoldExtractElementInstruction(Val, Idx))
+ return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Idx);
const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getExtractElement(Constant *Val, Constant *Idx) {
- assert(isa<VectorType>(Val->getType()) &&
+ assert(Val->getType()->isVectorTy() &&
"Tried to create extractelement operation on non-vector type!");
- assert(Idx->getType() == Type::getInt32Ty(Val->getContext()) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Extractelement index must be i32 type!");
return getExtractElementTy(cast<VectorType>(Val->getType())->getElementType(),
Val, Idx);
Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
Constant *Elt, Constant *Idx) {
- if (Constant *FC = ConstantFoldInsertElementInstruction(
- ReqTy->getContext(), Val, Elt, Idx))
- return FC; // Fold a few common cases...
+ if (Constant *FC = ConstantFoldInsertElementInstruction(Val, Elt, Idx))
+ return FC; // Fold a few common cases.
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Elt);
const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
Constant *ConstantExpr::getInsertElement(Constant *Val, Constant *Elt,
Constant *Idx) {
- assert(isa<VectorType>(Val->getType()) &&
+ assert(Val->getType()->isVectorTy() &&
"Tried to create insertelement operation on non-vector type!");
assert(Elt->getType() == cast<VectorType>(Val->getType())->getElementType()
&& "Insertelement types must match!");
- assert(Idx->getType() == Type::getInt32Ty(Val->getContext()) &&
+ assert(Idx->getType()->isIntegerTy(32) &&
"Insertelement index must be i32 type!");
return getInsertElementTy(Val->getType(), Val, Elt, Idx);
}
Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
Constant *V2, Constant *Mask) {
- if (Constant *FC = ConstantFoldShuffleVectorInstruction(
- ReqTy->getContext(), V1, V2, Mask))
+ if (Constant *FC = ConstantFoldShuffleVectorInstruction(V1, V2, Mask))
return FC; // Fold a few common cases...
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> ArgVec(1, V1);
const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
"insertvalue type invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant InsertValue expression");
- Constant *FC = ConstantFoldInsertValueInstruction(
- ReqTy->getContext(), Agg, Val, Idxs, NumIdx);
+ Constant *FC = ConstantFoldInsertValueInstruction(Agg, Val, Idxs, NumIdx);
assert(FC && "InsertValue constant expr couldn't be folded!");
return FC;
}
"extractvalue indices invalid!");
assert(Agg->getType()->isFirstClassType() &&
"Non-first-class type for constant extractvalue expression");
- Constant *FC = ConstantFoldExtractValueInstruction(
- ReqTy->getContext(), Agg, Idxs, NumIdx);
+ Constant *FC = ConstantFoldExtractValueInstruction(Agg, Idxs, NumIdx);
assert(FC && "ExtractValue constant expr couldn't be folded!");
return FC;
}
}
Constant* ConstantExpr::getNeg(Constant* C) {
- // API compatibility: Adjust integer opcodes to floating-point opcodes.
- if (C->getType()->isFPOrFPVector())
- return getFNeg(C);
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NEG a nonintegral value!");
return get(Instruction::Sub,
ConstantFP::getZeroValueForNegation(C->getType()),
}
Constant* ConstantExpr::getFNeg(Constant* C) {
- assert(C->getType()->isFPOrFPVector() &&
+ assert(C->getType()->isFPOrFPVectorTy() &&
"Cannot FNEG a non-floating-point value!");
return get(Instruction::FSub,
ConstantFP::getZeroValueForNegation(C->getType()),
}
Constant* ConstantExpr::getNot(Constant* C) {
- assert(C->getType()->isIntOrIntVector() &&
+ assert(C->getType()->isIntOrIntVectorTy() &&
"Cannot NOT a nonintegral value!");
return get(Instruction::Xor, C, Constant::getAllOnesValue(C->getType()));
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantExpr::destroyConstant() {
- // Implicitly locked.
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- pImpl->ExprConstants.remove(this);
+ getRawType()->getContext().pImpl->ExprConstants.remove(this);
destroyConstantImpl();
}
return Instruction::getOpcodeName(getOpcode());
}
+
+
+GetElementPtrConstantExpr::
+GetElementPtrConstantExpr(Constant *C, const std::vector<Constant*> &IdxList,
+ const Type *DestTy)
+ : ConstantExpr(DestTy, Instruction::GetElementPtr,
+ OperandTraits<GetElementPtrConstantExpr>::op_end(this)
+ - (IdxList.size()+1), IdxList.size()+1) {
+ OperandList[0] = C;
+ for (unsigned i = 0, E = IdxList.size(); i != E; ++i)
+ OperandList[i+1] = IdxList[i];
+}
+
+
//===----------------------------------------------------------------------===//
// replaceUsesOfWithOnConstant implementations
/// single invocation handles all 1000 uses. Handling them one at a time would
/// work, but would be really slow because it would have to unique each updated
/// array instance.
-
+///
void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
Constant *ToC = cast<Constant>(To);
- LLVMContext &Context = getType()->getContext();
- LLVMContextImpl *pImpl = Context.pImpl;
+ LLVMContextImpl *pImpl = getRawType()->getContext().pImpl;
std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, ConstantArray*> Lookup;
- Lookup.first.first = getType();
+ Lookup.first.first = cast<ArrayType>(getRawType());
Lookup.second = this;
std::vector<Constant*> &Values = Lookup.first.second;
Constant *Replacement = 0;
if (isAllZeros) {
- Replacement = ConstantAggregateZero::get(getType());
+ Replacement = ConstantAggregateZero::get(getRawType());
} else {
// Check to see if we have this array type already.
- sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
bool Exists;
LLVMContextImpl::ArrayConstantsTy::MapTy::iterator I =
pImpl->ArrayConstants.InsertOrGetItem(Lookup, Exists);
assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
std::pair<LLVMContextImpl::StructConstantsTy::MapKey, ConstantStruct*> Lookup;
- Lookup.first.first = getType();
+ Lookup.first.first = cast<StructType>(getRawType());
Lookup.second = this;
std::vector<Constant*> &Values = Lookup.first.second;
Values.reserve(getNumOperands()); // Build replacement struct.
}
Values[OperandToUpdate] = ToC;
- LLVMContext &Context = getType()->getContext();
- LLVMContextImpl *pImpl = Context.pImpl;
+ LLVMContextImpl *pImpl = getRawType()->getContext().pImpl;
Constant *Replacement = 0;
if (isAllZeros) {
- Replacement = ConstantAggregateZero::get(getType());
+ Replacement = ConstantAggregateZero::get(getRawType());
} else {
- // Check to see if we have this array type already.
- sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
+ // Check to see if we have this struct type already.
bool Exists;
LLVMContextImpl::StructConstantsTy::MapTy::iterator I =
pImpl->StructConstants.InsertOrGetItem(Lookup, Exists);
Values.push_back(Val);
}
- Constant *Replacement = get(getType(), Values);
+ Constant *Replacement = get(cast<VectorType>(getRawType()), Values);
assert(Replacement != this && "I didn't contain From!");
// Everyone using this now uses the replacement.
&Indices[0], Indices.size());
} else if (isCast()) {
assert(getOperand(0) == From && "Cast only has one use!");
- Replacement = ConstantExpr::getCast(getOpcode(), To, getType());
+ Replacement = ConstantExpr::getCast(getOpcode(), To, getRawType());
} else if (getOpcode() == Instruction::Select) {
Constant *C1 = getOperand(0);
Constant *C2 = getOperand(1);
Constant *C2 = getOperand(1);
if (C1 == From) C1 = To;
if (C2 == From) C2 = To;
- Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassData);
+ Replacement = ConstantExpr::get(getOpcode(), C1, C2, SubclassOptionalData);
} else {
llvm_unreachable("Unknown ConstantExpr type!");
return;