summaryrefslogtreecommitdiff
path: root/lib/VMCore/Constants.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/VMCore/Constants.cpp')
-rw-r--r--lib/VMCore/Constants.cpp330
1 files changed, 246 insertions, 84 deletions
diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp
index 69c503dff9568..c164a3b0c2cae 100644
--- a/lib/VMCore/Constants.cpp
+++ b/lib/VMCore/Constants.cpp
@@ -25,6 +25,9 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.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>
@@ -35,6 +38,9 @@ using namespace llvm;
// Constant Class
//===----------------------------------------------------------------------===//
+// Becomes a no-op when multithreading is disabled.
+ManagedStatic<sys::SmartRWMutex<true> > ConstantsLock;
+
void Constant::destroyConstantImpl() {
// When a Constant is destroyed, there may be lingering
// references to the constant by other constants in the constant pool. These
@@ -269,9 +275,20 @@ typedef DenseMap<DenseMapAPIntKeyInfo::KeyTy, ConstantInt*,
DenseMapAPIntKeyInfo> IntMapTy;
static ManagedStatic<IntMapTy> IntConstants;
-ConstantInt *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
- const IntegerType *ITy = cast<IntegerType>(Ty);
- return get(APInt(ITy->getBitWidth(), V, isSigned));
+ConstantInt *ConstantInt::get(const IntegerType *Ty,
+ uint64_t V, bool isSigned) {
+ return get(APInt(Ty->getBitWidth(), V, isSigned));
+}
+
+Constant *ConstantInt::get(const Type *Ty, uint64_t V, bool isSigned) {
+ Constant *C = get(cast<IntegerType>(Ty->getScalarType()), V, isSigned);
+
+ // For vectors, broadcast the value.
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return
+ ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
+
+ return C;
}
// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap
@@ -284,12 +301,35 @@ ConstantInt *ConstantInt::get(const APInt& V) {
const IntegerType *ITy = IntegerType::get(V.getBitWidth());
// get an existing value or the insertion position
DenseMapAPIntKeyInfo::KeyTy Key(V, ITy);
+
+ ConstantsLock->reader_acquire();
ConstantInt *&Slot = (*IntConstants)[Key];
- // if it exists, return it.
- if (Slot)
+ ConstantsLock->reader_release();
+
+ if (!Slot) {
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
+ ConstantInt *&NewSlot = (*IntConstants)[Key];
+ if (!Slot) {
+ NewSlot = new ConstantInt(ITy, V);
+ }
+
+ return NewSlot;
+ } else {
return Slot;
- // otherwise create a new one, insert it, and return it.
- return Slot = new ConstantInt(ITy, V);
+ }
+}
+
+Constant *ConstantInt::get(const Type *Ty, const APInt &V) {
+ ConstantInt *C = ConstantInt::get(V);
+ assert(C->getType() == Ty->getScalarType() &&
+ "ConstantInt type doesn't match the type implied by its value!");
+
+ // For vectors, broadcast the value.
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return
+ ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
+
+ return C;
}
//===----------------------------------------------------------------------===//
@@ -368,34 +408,54 @@ static ManagedStatic<FPMapTy> FPConstants;
ConstantFP *ConstantFP::get(const APFloat &V) {
DenseMapAPFloatKeyInfo::KeyTy Key(V);
- ConstantFP *&Slot = (*FPConstants)[Key];
- if (Slot) return Slot;
- const Type *Ty;
- if (&V.getSemantics() == &APFloat::IEEEsingle)
- Ty = Type::FloatTy;
- else if (&V.getSemantics() == &APFloat::IEEEdouble)
- Ty = Type::DoubleTy;
- else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
- Ty = Type::X86_FP80Ty;
- else if (&V.getSemantics() == &APFloat::IEEEquad)
- Ty = Type::FP128Ty;
- else {
- assert(&V.getSemantics() == &APFloat::PPCDoubleDouble&&"Unknown FP format");
- Ty = Type::PPC_FP128Ty;
+ ConstantsLock->reader_acquire();
+ ConstantFP *&Slot = (*FPConstants)[Key];
+ ConstantsLock->reader_release();
+
+ if (!Slot) {
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
+ ConstantFP *&NewSlot = (*FPConstants)[Key];
+ if (!NewSlot) {
+ const Type *Ty;
+ if (&V.getSemantics() == &APFloat::IEEEsingle)
+ Ty = Type::FloatTy;
+ else if (&V.getSemantics() == &APFloat::IEEEdouble)
+ Ty = Type::DoubleTy;
+ else if (&V.getSemantics() == &APFloat::x87DoubleExtended)
+ Ty = Type::X86_FP80Ty;
+ else if (&V.getSemantics() == &APFloat::IEEEquad)
+ Ty = Type::FP128Ty;
+ else {
+ assert(&V.getSemantics() == &APFloat::PPCDoubleDouble &&
+ "Unknown FP format");
+ Ty = Type::PPC_FP128Ty;
+ }
+ NewSlot = new ConstantFP(Ty, V);
+ }
+
+ return NewSlot;
}
- return Slot = new ConstantFP(Ty, V);
+ return Slot;
}
/// get() - This returns a constant fp for the specified value in the
/// specified type. This should only be used for simple constant values like
/// 2.0/1.0 etc, that are known-valid both as double and as the target format.
-ConstantFP *ConstantFP::get(const Type *Ty, double V) {
+Constant *ConstantFP::get(const Type *Ty, double V) {
APFloat FV(V);
bool ignored;
- FV.convert(*TypeToFloatSemantics(Ty), APFloat::rmNearestTiesToEven, &ignored);
- return get(FV);
+ FV.convert(*TypeToFloatSemantics(Ty->getScalarType()),
+ APFloat::rmNearestTiesToEven, &ignored);
+ Constant *C = get(FV);
+
+ // For vectors, broadcast the value.
+ if (const VectorType *VTy = dyn_cast<VectorType>(Ty))
+ return
+ ConstantVector::get(std::vector<Constant *>(VTy->getNumElements(), C));
+
+ return C;
}
//===----------------------------------------------------------------------===//
@@ -1093,8 +1153,13 @@ namespace llvm {
/// AbstractTypeMap - Map for abstract type constants.
///
AbstractTypeMapTy AbstractTypeMap;
+
+ /// ValueMapLock - Mutex for this map.
+ sys::SmartMutex<true> ValueMapLock;
public:
+ // NOTE: This function is not locked. It is the caller's responsibility
+ // to enforce proper synchronization.
typename MapTy::iterator map_end() { return Map.end(); }
/// InsertOrGetItem - Return an iterator for the specified element.
@@ -1102,6 +1167,8 @@ namespace llvm {
/// entry and Exists=true. If not, the iterator points to the newly
/// inserted entry and returns Exists=false. Newly inserted entries have
/// I->second == 0, and should be filled in.
+ /// NOTE: This function is not locked. It is the caller's responsibility
+ // to enforce proper synchronization.
typename MapTy::iterator InsertOrGetItem(std::pair<MapKey, Constant *>
&InsertVal,
bool &Exists) {
@@ -1131,19 +1198,10 @@ private:
}
return I;
}
-public:
- /// getOrCreate - Return the specified constant from the map, creating it if
- /// necessary.
- ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
- MapKey Lookup(Ty, V);
- typename MapTy::iterator I = Map.find(Lookup);
- // Is it in the map?
- if (I != Map.end())
- return static_cast<ConstantClass *>(I->second);
-
- // If no preexisting value, create one now...
- ConstantClass *Result =
+ ConstantClass* Create(const TypeClass *Ty, const ValType &V,
+ typename MapTy::iterator I) {
+ ConstantClass* Result =
ConstantCreator<ConstantClass,TypeClass,ValType>::create(Ty, V);
assert(Result->getType() == Ty && "Type specified is not correct!");
@@ -1151,11 +1209,12 @@ public:
if (HasLargeKey) // Remember the reverse mapping if needed.
InverseMap.insert(std::make_pair(Result, I));
-
- // If the type of the constant is abstract, make sure that an entry exists
- // for it in the AbstractTypeMap.
+
+ // If the type of the constant is abstract, make sure that an entry
+ // exists for it in the AbstractTypeMap.
if (Ty->isAbstract()) {
- typename AbstractTypeMapTy::iterator TI = AbstractTypeMap.find(Ty);
+ typename AbstractTypeMapTy::iterator TI =
+ AbstractTypeMap.find(Ty);
if (TI == AbstractTypeMap.end()) {
// Add ourselves to the ATU list of the type.
@@ -1164,10 +1223,33 @@ public:
AbstractTypeMap.insert(TI, std::make_pair(Ty, I));
}
}
+
+ return Result;
+ }
+public:
+
+ /// getOrCreate - Return the specified constant from the map, creating it if
+ /// necessary.
+ ConstantClass *getOrCreate(const TypeClass *Ty, const ValType &V) {
+ sys::SmartScopedLock<true> Lock(&ValueMapLock);
+ MapKey Lookup(Ty, V);
+ ConstantClass* Result = 0;
+
+ typename MapTy::iterator I = Map.find(Lookup);
+ // Is it in the map?
+ if (I != Map.end())
+ Result = static_cast<ConstantClass *>(I->second);
+
+ if (!Result) {
+ // If no preexisting value, create one now...
+ Result = Create(Ty, V, I);
+ }
+
return Result;
}
void remove(ConstantClass *CP) {
+ sys::SmartScopedLock<true> Lock(&ValueMapLock);
typename MapTy::iterator I = FindExistingElement(CP);
assert(I != Map.end() && "Constant not found in constant table!");
assert(I->second == CP && "Didn't find correct element?");
@@ -1221,6 +1303,8 @@ public:
/// MoveConstantToNewSlot - If we are about to change C to be the element
/// specified by I, update our internal data structures to reflect this
/// fact.
+ /// NOTE: This function is not locked. It is the responsibility of the
+ /// caller to enforce proper synchronization if using this method.
void MoveConstantToNewSlot(ConstantClass *C, typename MapTy::iterator I) {
// First, remove the old location of the specified constant in the map.
typename MapTy::iterator OldI = FindExistingElement(C);
@@ -1250,6 +1334,7 @@ public:
}
void refineAbstractType(const DerivedType *OldTy, const Type *NewTy) {
+ sys::SmartScopedLock<true> Lock(&ValueMapLock);
typename AbstractTypeMapTy::iterator I =
AbstractTypeMap.find(cast<Type>(OldTy));
@@ -1314,12 +1399,15 @@ 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!");
+
+ // Implicitly locked.
return AggZeroConstants->getOrCreate(Ty, 0);
}
/// destroyConstant - Remove the constant from the constant table...
///
void ConstantAggregateZero::destroyConstant() {
+ // Implicitly locked.
AggZeroConstants->remove(this);
destroyConstantImpl();
}
@@ -1359,18 +1447,24 @@ Constant *ConstantArray::get(const ArrayType *Ty,
// If this is an all-zero array, return a ConstantAggregateZero object
if (!V.empty()) {
Constant *C = V[0];
- if (!C->isNullValue())
+ if (!C->isNullValue()) {
+ // Implicitly locked.
return ArrayConstants->getOrCreate(Ty, V);
+ }
for (unsigned i = 1, e = V.size(); i != e; ++i)
- if (V[i] != C)
+ if (V[i] != C) {
+ // Implicitly locked.
return ArrayConstants->getOrCreate(Ty, V);
+ }
}
+
return ConstantAggregateZero::get(Ty);
}
/// destroyConstant - Remove the constant from the constant table...
///
void ConstantArray::destroyConstant() {
+ // Implicitly locked.
ArrayConstants->remove(this);
destroyConstantImpl();
}
@@ -1482,6 +1576,7 @@ Constant *ConstantStruct::get(const StructType *Ty,
// 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 StructConstants->getOrCreate(Ty, V);
return ConstantAggregateZero::get(Ty);
@@ -1498,6 +1593,7 @@ Constant *ConstantStruct::get(const std::vector<Constant*> &V, bool packed) {
// destroyConstant - Remove the constant from the constant table...
//
void ConstantStruct::destroyConstant() {
+ // Implicitly locked.
StructConstants->remove(this);
destroyConstantImpl();
}
@@ -1552,6 +1648,8 @@ Constant *ConstantVector::get(const VectorType *Ty,
return ConstantAggregateZero::get(Ty);
if (isUndef)
return UndefValue::get(Ty);
+
+ // Implicitly locked.
return VectorConstants->getOrCreate(Ty, V);
}
@@ -1563,6 +1661,7 @@ Constant *ConstantVector::get(const std::vector<Constant*> &V) {
// destroyConstant - Remove the constant from the constant table...
//
void ConstantVector::destroyConstant() {
+ // Implicitly locked.
VectorConstants->remove(this);
destroyConstantImpl();
}
@@ -1627,12 +1726,14 @@ static char getValType(ConstantPointerNull *) {
ConstantPointerNull *ConstantPointerNull::get(const PointerType *Ty) {
+ // Implicitly locked.
return NullPtrConstants->getOrCreate(Ty, 0);
}
// destroyConstant - Remove the constant from the constant table...
//
void ConstantPointerNull::destroyConstant() {
+ // Implicitly locked.
NullPtrConstants->remove(this);
destroyConstantImpl();
}
@@ -1670,12 +1771,14 @@ static char getValType(UndefValue *) {
UndefValue *UndefValue::get(const Type *Ty) {
+ // Implicitly locked.
return UndefValueConstants->getOrCreate(Ty, 0);
}
// destroyConstant - Remove the constant from the constant table.
//
void UndefValue::destroyConstant() {
+ // Implicitly locked.
UndefValueConstants->remove(this);
destroyConstantImpl();
}
@@ -1690,15 +1793,18 @@ MDString::MDString(const char *begin, const char *end)
static ManagedStatic<StringMap<MDString*> > MDStringCache;
MDString *MDString::get(const char *StrBegin, const char *StrEnd) {
- StringMapEntry<MDString *> &Entry = MDStringCache->GetOrCreateValue(StrBegin,
- StrEnd);
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
+ StringMapEntry<MDString *> &Entry = MDStringCache->GetOrCreateValue(
+ StrBegin, StrEnd);
MDString *&S = Entry.getValue();
if (!S) S = new MDString(Entry.getKeyData(),
Entry.getKeyData() + Entry.getKeyLength());
+
return S;
}
void MDString::destroyConstant() {
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
MDStringCache->erase(MDStringCache->find(StrBegin, StrEnd));
destroyConstantImpl();
}
@@ -1724,18 +1830,27 @@ MDNode *MDNode::get(Value*const* Vals, unsigned NumVals) {
for (unsigned i = 0; i != NumVals; ++i)
ID.AddPointer(Vals[i]);
+ ConstantsLock->reader_acquire();
void *InsertPoint;
- if (MDNode *N = MDNodeSet->FindNodeOrInsertPos(ID, InsertPoint))
- return N;
-
- // InsertPoint will have been set by the FindNodeOrInsertPos call.
- MDNode *N = new(0) MDNode(Vals, NumVals);
- MDNodeSet->InsertNode(N, InsertPoint);
+ MDNode *N = MDNodeSet->FindNodeOrInsertPos(ID, InsertPoint);
+ ConstantsLock->reader_release();
+
+ if (!N) {
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
+ N = MDNodeSet->FindNodeOrInsertPos(ID, InsertPoint);
+ if (!N) {
+ // InsertPoint will have been set by the FindNodeOrInsertPos call.
+ N = new(0) MDNode(Vals, NumVals);
+ MDNodeSet->InsertNode(N, InsertPoint);
+ }
+ }
return N;
}
void MDNode::destroyConstant() {
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
MDNodeSet->RemoveNode(this);
+
destroyConstantImpl();
}
@@ -1902,6 +2017,8 @@ static inline Constant *getFoldedCast(
// Look up the constant in the table first to ensure uniqueness
std::vector<Constant*> argVec(1, C);
ExprMapKeyType Key(opc, argVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(Ty, Key);
}
@@ -1932,19 +2049,19 @@ Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
}
Constant *ConstantExpr::getZExtOrBitCast(Constant *C, const Type *Ty) {
- if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return getCast(Instruction::BitCast, C, Ty);
return getCast(Instruction::ZExt, C, Ty);
}
Constant *ConstantExpr::getSExtOrBitCast(Constant *C, const Type *Ty) {
- if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return getCast(Instruction::BitCast, C, Ty);
return getCast(Instruction::SExt, C, Ty);
}
Constant *ConstantExpr::getTruncOrBitCast(Constant *C, const Type *Ty) {
- if (C->getType()->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ if (C->getType()->getScalarSizeInBits() == Ty->getScalarSizeInBits())
return getCast(Instruction::BitCast, C, Ty);
return getCast(Instruction::Trunc, C, Ty);
}
@@ -1960,9 +2077,10 @@ Constant *ConstantExpr::getPointerCast(Constant *S, const Type *Ty) {
Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
bool isSigned) {
- assert(C->getType()->isInteger() && Ty->isInteger() && "Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ assert(C->getType()->isIntOrIntVector() &&
+ Ty->isIntOrIntVector() && "Invalid cast");
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
Instruction::CastOps opcode =
(SrcBits == DstBits ? Instruction::BitCast :
(SrcBits > DstBits ? Instruction::Trunc :
@@ -1971,10 +2089,10 @@ Constant *ConstantExpr::getIntegerCast(Constant *C, const Type *Ty,
}
Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
"Invalid cast");
- unsigned SrcBits = C->getType()->getPrimitiveSizeInBits();
- unsigned DstBits = Ty->getPrimitiveSizeInBits();
+ unsigned SrcBits = C->getType()->getScalarSizeInBits();
+ unsigned DstBits = Ty->getScalarSizeInBits();
if (SrcBits == DstBits)
return C; // Avoid a useless cast
Instruction::CastOps opcode =
@@ -1983,42 +2101,67 @@ Constant *ConstantExpr::getFPCast(Constant *C, const Type *Ty) {
}
Constant *ConstantExpr::getTrunc(Constant *C, const Type *Ty) {
- assert(C->getType()->isInteger() && "Trunc operand must be integer");
- assert(Ty->isInteger() && "Trunc produces only integral");
- assert(C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
+#ifndef NDEBUG
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ 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()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"SrcTy must be larger than DestTy for Trunc!");
return getFoldedCast(Instruction::Trunc, C, Ty);
}
Constant *ConstantExpr::getSExt(Constant *C, const Type *Ty) {
- assert(C->getType()->isInteger() && "SEXt operand must be integral");
- assert(Ty->isInteger() && "SExt produces only integer");
- assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+#ifndef NDEBUG
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ 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()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for SExt!");
return getFoldedCast(Instruction::SExt, C, Ty);
}
Constant *ConstantExpr::getZExt(Constant *C, const Type *Ty) {
- assert(C->getType()->isInteger() && "ZEXt operand must be integral");
- assert(Ty->isInteger() && "ZExt produces only integer");
- assert(C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+#ifndef NDEBUG
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ 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()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"SrcTy must be smaller than DestTy for ZExt!");
return getFoldedCast(Instruction::ZExt, C, Ty);
}
Constant *ConstantExpr::getFPTrunc(Constant *C, const Type *Ty) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
- C->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()&&
+#ifndef NDEBUG
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ C->getType()->getScalarSizeInBits() > Ty->getScalarSizeInBits()&&
"This is an illegal floating point truncation!");
return getFoldedCast(Instruction::FPTrunc, C, Ty);
}
Constant *ConstantExpr::getFPExtend(Constant *C, const Type *Ty) {
- assert(C->getType()->isFloatingPoint() && Ty->isFloatingPoint() &&
- C->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()&&
+#ifndef NDEBUG
+ bool fromVec = C->getType()->getTypeID() == Type::VectorTyID;
+ bool toVec = Ty->getTypeID() == Type::VectorTyID;
+#endif
+ assert((fromVec == toVec) && "Cannot convert from scalar to/from vector");
+ assert(C->getType()->isFPOrFPVector() && Ty->isFPOrFPVector() &&
+ C->getType()->getScalarSizeInBits() < Ty->getScalarSizeInBits()&&
"This is an illegal floating point extension!");
return getFoldedCast(Instruction::FPExt, C, Ty);
}
@@ -2136,6 +2279,8 @@ Constant *ConstantExpr::getTy(const Type *ReqTy, unsigned Opcode,
std::vector<Constant*> argVec(1, C1); argVec.push_back(C2);
ExprMapKeyType Key(Opcode, argVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2188,34 +2333,30 @@ Constant *ConstantExpr::get(unsigned Opcode, Constant *C1, Constant *C2) {
case Instruction::UDiv:
case Instruction::SDiv:
assert(C1->getType() == C2->getType() && "Op types should be identical!");
- assert((C1->getType()->isInteger() || (isa<VectorType>(C1->getType()) &&
- cast<VectorType>(C1->getType())->getElementType()->isInteger())) &&
+ assert(C1->getType()->isIntOrIntVector() &&
"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()->isFloatingPoint() || (isa<VectorType>(C1->getType())
- && cast<VectorType>(C1->getType())->getElementType()->isFloatingPoint()))
- && "Tried to create an arithmetic operation on a non-arithmetic type!");
+ assert(C1->getType()->isFPOrFPVector() &&
+ "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()->isInteger() || (isa<VectorType>(C1->getType()) &&
- cast<VectorType>(C1->getType())->getElementType()->isInteger())) &&
+ assert(C1->getType()->isIntOrIntVector() &&
"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()->isFloatingPoint() || (isa<VectorType>(C1->getType())
- && cast<VectorType>(C1->getType())->getElementType()->isFloatingPoint()))
- && "Tried to create an arithmetic operation on a non-arithmetic type!");
+ assert(C1->getType()->isFPOrFPVector() &&
+ "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()->isInteger() || isa<VectorType>(C1->getType())) &&
+ assert(C1->getType()->isIntOrIntVector() &&
"Tried to create a logical operation on a non-integral type!");
break;
case Instruction::Shl:
@@ -2251,6 +2392,8 @@ Constant *ConstantExpr::getSelectTy(const Type *ReqTy, Constant *C,
argVec[1] = V1;
argVec[2] = V2;
ExprMapKeyType Key(Instruction::Select, argVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2274,6 +2417,8 @@ Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
for (unsigned i = 0; i != NumIdx; ++i)
ArgVec.push_back(cast<Constant>(Idxs[i]));
const ExprMapKeyType Key(Instruction::GetElementPtr, ArgVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2308,6 +2453,8 @@ ConstantExpr::getICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::ICmp, ArgVec, pred);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(Type::Int1Ty, Key);
}
@@ -2325,6 +2472,8 @@ ConstantExpr::getFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::FCmp, ArgVec, pred);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(Type::Int1Ty, Key);
}
@@ -2370,6 +2519,8 @@ ConstantExpr::getVICmp(unsigned short pred, Constant* LHS, Constant* RHS) {
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::VICmp, ArgVec, pred);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(LHS->getType(), Key);
}
@@ -2417,6 +2568,8 @@ ConstantExpr::getVFCmp(unsigned short pred, Constant* LHS, Constant* RHS) {
ArgVec.push_back(RHS);
// Get the key type with both the opcode and predicate
const ExprMapKeyType Key(Instruction::VFCmp, ArgVec, pred);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ResultTy, Key);
}
@@ -2428,6 +2581,8 @@ Constant *ConstantExpr::getExtractElementTy(const Type *ReqTy, Constant *Val,
std::vector<Constant*> ArgVec(1, Val);
ArgVec.push_back(Idx);
const ExprMapKeyType Key(Instruction::ExtractElement,ArgVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2449,6 +2604,8 @@ Constant *ConstantExpr::getInsertElementTy(const Type *ReqTy, Constant *Val,
ArgVec.push_back(Elt);
ArgVec.push_back(Idx);
const ExprMapKeyType Key(Instruction::InsertElement,ArgVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2472,6 +2629,8 @@ Constant *ConstantExpr::getShuffleVectorTy(const Type *ReqTy, Constant *V1,
ArgVec.push_back(V2);
ArgVec.push_back(Mask);
const ExprMapKeyType Key(Instruction::ShuffleVector,ArgVec);
+
+ // Implicitly locked.
return ExprConstants->getOrCreate(ReqTy, Key);
}
@@ -2555,6 +2714,7 @@ Constant *ConstantExpr::getZeroValueForNegationExpr(const Type *Ty) {
// destroyConstant - Remove the constant from the constant table...
//
void ConstantExpr::destroyConstant() {
+ // Implicitly locked.
ExprConstants->remove(this);
destroyConstantImpl();
}
@@ -2619,6 +2779,7 @@ void ConstantArray::replaceUsesOfWithOnConstant(Value *From, Value *To,
Replacement = ConstantAggregateZero::get(getType());
} else {
// Check to see if we have this array type already.
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
bool Exists;
ArrayConstantsTy::MapTy::iterator I =
ArrayConstants->InsertOrGetItem(Lookup, Exists);
@@ -2694,6 +2855,7 @@ void ConstantStruct::replaceUsesOfWithOnConstant(Value *From, Value *To,
Replacement = ConstantAggregateZero::get(getType());
} else {
// Check to see if we have this array type already.
+ sys::SmartScopedWriter<true> Writer(&*ConstantsLock);
bool Exists;
StructConstantsTy::MapTy::iterator I =
StructConstants->InsertOrGetItem(Lookup, Exists);