//
//===----------------------------------------------------------------------===//
//
-// This file implements the Constant* classes...
+// This file implements the Constant* classes.
//
//===----------------------------------------------------------------------===//
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/System/Mutex.h"
-#include "llvm/System/RWMutex.h"
-#include "llvm/System/Threading.h"
+#include "llvm/Support/GetElementPtrTypeIterator.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));
// 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 (use_const_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();
+
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;
}
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);
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;
}
+ConstantFP *ConstantFP::getInfinity(const Type *Ty, bool Negative) {
+ const fltSemantics &Semantics = *TypeToFloatSemantics(Ty);
+ return ConstantFP::get(Ty->getContext(),
+ APFloat::getInf(Semantics, Negative));
+}
+
ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
: Constant(Ty, ConstantFPVal, 0, 0), Val(V) {
assert(&V.getSemantics() == TypeToFloatSemantics(Ty) &&
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
Constant *C = *I;
- assert((C->getType() == T->getElementType() ||
- (T->isAbstract() &&
- C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
+ assert(C->getType() == T->getElementType() &&
"Initializer for array element doesn't match array element type!");
*OL = C;
}
Constant *ConstantArray::get(const ArrayType *Ty,
const std::vector<Constant*> &V) {
+ for (unsigned i = 0, e = V.size(); i != e; ++i) {
+ assert(V[i]->getType() == Ty->getElementType() &&
+ "Wrong type in array element initializer");
+ }
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
// 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;
for (unsigned i = 0; i < Str.size(); ++i)
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
Constant *C = *I;
- assert((C->getType() == T->getElementType(I-V.begin()) ||
- ((T->getElementType(I-V.begin())->isAbstract() ||
- C->getType()->isAbstract()) &&
- T->getElementType(I-V.begin())->getTypeID() ==
- C->getType()->getTypeID())) &&
+ assert(C->getType() == T->getElementType(I-V.begin()) &&
"Initializer for struct element doesn't match struct element type!");
*OL = C;
}
// 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);
for (std::vector<Constant*>::const_iterator I = V.begin(), E = V.end();
I != E; ++I, ++OL) {
Constant *C = *I;
- assert((C->getType() == T->getElementType() ||
- (T->isAbstract() &&
- C->getType()->getTypeID() == T->getElementType()->getTypeID())) &&
+ assert(C->getType() == T->getElementType() &&
"Initializer for vector element doesn't match vector element type!");
*OL = C;
}
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()->isIntOrIntVector() &&
+ "Cannot NEG a nonintegral value!");
+ return getNSWSub(ConstantFP::getZeroValueForNegation(C->getType()), C);
+}
+
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::getNSWSub(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Sub, C1, C2,
+ OverflowingBinaryOperator::NoSignedWrap);
+}
+
+Constant* ConstantExpr::getNSWMul(Constant* C1, Constant* C2) {
+ return getTy(C1->getType(), Instruction::Mul, 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
return getOpcode() == Instruction::ICmp || getOpcode() == Instruction::FCmp;
}
+bool ConstantExpr::isGEPWithNoNotionalOverIndexing() const {
+ 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());
+
+ // Skip the first index, as it has no static limit.
+ ++GEPI;
+ ++OI;
+
+ // The remaining indices must be compile-time known integers within the
+ // bounds of the corresponding notional static array types.
+ for (; GEPI != E; ++GEPI, ++OI) {
+ ConstantInt *CI = dyn_cast<ConstantInt>(*OI);
+ if (!CI) return false;
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(*GEPI))
+ if (CI->getValue().getActiveBits() > 64 ||
+ CI->getZExtValue() >= ATy->getNumElements())
+ return false;
+ }
+
+ // All the indices checked out.
+ return true;
+}
+
bool ConstantExpr::hasIndices() const {
return getOpcode() == Instruction::ExtractValue ||
getOpcode() == Instruction::InsertValue;
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, SubclassOptionalData);
}
}
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], SubclassOptionalData);
}
}
//===----------------------------------------------------------------------===//
// Factory Function Implementation
-static char getValType(ConstantAggregateZero *CPZ) { return 0; }
-
ConstantAggregateZero* ConstantAggregateZero::get(const Type* Ty) {
assert((isa<StructType>(Ty) || isa<ArrayType>(Ty) || isa<VectorType>(Ty)) &&
"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);
destroyConstantImpl();
}
/// destroyConstant - Remove the constant from the constant table...
///
void ConstantArray::destroyConstant() {
- // Implicitly locked.
getType()->getContext().pImpl->ArrayConstants.remove(this);
destroyConstantImpl();
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantStruct::destroyConstant() {
- // Implicitly locked.
getType()->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);
destroyConstantImpl();
}
return Elt;
}
-//---- ConstantPointerNull::get() implementation...
+//---- ConstantPointerNull::get() implementation.
//
-static char getValType(ConstantPointerNull *) {
- return 0;
-}
-
-
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);
destroyConstantImpl();
}
-//---- UndefValue::get() implementation...
+//---- UndefValue::get() implementation.
//
-static char getValType(UndefValue *) {
- return 0;
-}
-
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);
destroyConstantImpl();
}
-//---- ConstantExpr::get() implementations...
+//---- 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()->getType()->getContext().pImpl
+ ->BlockAddresses.erase(std::make_pair(getFunction(), getBasicBlock()));
+ getBasicBlock()->AdjustBlockAddressRefCount(-1);
+ destroyConstantImpl();
+}
+
+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;
+ }
-static ExprMapKeyType getValType(ConstantExpr *CE) {
- std::vector<Constant*> Operands;
- 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,
- CE->isCompare() ? CE->getPredicate() : 0,
- CE->hasIndices() ?
- CE->getIndices() : SmallVector<unsigned, 4>());
+ // 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
/// cast in the ExprConstants map. It is used by the various get* methods below.
static inline Constant *getFoldedCast(
std::vector<Constant*> argVec(1, C);
ExprMapKeyType Key(opc, argVec);
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(Ty, Key);
}
}
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 &&
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;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
}
}
-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;
}
#endif
- return getTy(C1->getType(), Opcode, C1, C2);
+ return getTy(C1->getType(), Opcode, C1, C2, Flags);
}
Constant* ConstantExpr::getSizeOf(const Type* Ty) {
ExprMapKeyType Key(Instruction::Select, argVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
"GEP indices invalid!");
if (Constant *FC = ConstantFoldGetElementPtr(
- ReqTy->getContext(), C, (Constant**)Idxs, NumIdx))
+ ReqTy->getContext(), C, /*inBounds=*/false,
+ (Constant**)Idxs, NumIdx))
return FC; // Fold a few common cases...
assert(isa<PointerType>(C->getType()) &&
const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
+ 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, /*inBounds=*/true,
+ (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);
- // Implicitly locked.
+ LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
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,
const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
-
- // Implicitly locked.
return
pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
}
const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
LLVMContextImpl *pImpl = LHS->getType()->getContext().pImpl;
-
- // Implicitly locked.
return
pImpl->ExprConstants.getOrCreate(Type::getInt1Ty(LHS->getContext()), Key);
}
Constant *Idx) {
if (Constant *FC = ConstantFoldExtractElementInstruction(
ReqTy->getContext(), Val, Idx))
- return FC; // Fold a few common cases...
+ 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 *Elt, Constant *Idx) {
if (Constant *FC = ConstantFoldInsertElementInstruction(
ReqTy->getContext(), Val, Elt, Idx))
- return FC; // Fold a few common cases...
+ 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);
}
const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
LLVMContextImpl *pImpl = ReqTy->getContext().pImpl;
-
- // Implicitly locked.
return pImpl->ExprConstants.getOrCreate(ReqTy, Key);
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantExpr::destroyConstant() {
- // Implicitly locked.
- LLVMContextImpl *pImpl = getType()->getContext().pImpl;
- pImpl->ExprConstants.remove(this);
+ getType()->getContext().pImpl->ExprConstants.remove(this);
destroyConstantImpl();
}
/// 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.
-
-static std::vector<Constant*> getValType(ConstantArray *CA) {
- std::vector<Constant*> Elements;
- Elements.reserve(CA->getNumOperands());
- for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
- Elements.push_back(cast<Constant>(CA->getOperand(i)));
- return Elements;
-}
-
-
+///
void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
LLVMContext &Context = getType()->getContext();
LLVMContextImpl *pImpl = Context.pImpl;
- std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, Constant*> Lookup;
+ std::pair<LLVMContextImpl::ArrayConstantsTy::MapKey, ConstantArray*> Lookup;
Lookup.first.first = getType();
Lookup.second = this;
Replacement = ConstantAggregateZero::get(getType());
} 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);
destroyConstant();
}
-static std::vector<Constant*> getValType(ConstantStruct *CS) {
- std::vector<Constant*> Elements;
- Elements.reserve(CS->getNumOperands());
- for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i)
- Elements.push_back(cast<Constant>(CS->getOperand(i)));
- return Elements;
-}
-
void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
unsigned OperandToUpdate = U-OperandList;
assert(getOperand(OperandToUpdate) == From && "ReplaceAllUsesWith broken!");
- std::pair<LLVMContextImpl::StructConstantsTy::MapKey, Constant*> Lookup;
+ std::pair<LLVMContextImpl::StructConstantsTy::MapKey, ConstantStruct*> Lookup;
Lookup.first.first = getType();
Lookup.second = this;
std::vector<Constant*> &Values = Lookup.first.second;
Replacement = ConstantAggregateZero::get(getType());
} else {
// Check to see if we have this array type already.
- sys::SmartScopedWriter<true> Writer(pImpl->ConstantsLock);
bool Exists;
LLVMContextImpl::StructConstantsTy::MapTy::iterator I =
pImpl->StructConstants.InsertOrGetItem(Lookup, Exists);
destroyConstant();
}
-static std::vector<Constant*> getValType(ConstantVector *CP) {
- std::vector<Constant*> Elements;
- Elements.reserve(CP->getNumOperands());
- for (unsigned i = 0, e = CP->getNumOperands(); i != e; ++i)
- Elements.push_back(CP->getOperand(i));
- return Elements;
-}
-
void ConstantVector::replaceUsesOfWithOnConstant(Value *From, Value *To,
Use *U) {
assert(isa<Constant>(To) && "Cannot make Constant refer to non-constant!");
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, SubclassOptionalData);
} else {
llvm_unreachable("Unknown ConstantExpr type!");
return;
// Delete the old constant!
destroyConstant();
}
-