#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 <algorithm>
#include <cstdarg>
AbstractTypeUser::~AbstractTypeUser() {}
+void AbstractTypeUser::setType(Value *V, const Type *NewTy) {
+ V->VTy = NewTy;
+}
//===----------------------------------------------------------------------===//
// Type Class Implementation
operator delete(const_cast<Type *>(this));
return;
+ } else if (const OpaqueType *opaque_this = dyn_cast<OpaqueType>(this)) {
+ LLVMContextImpl *pImpl = this->getContext().pImpl;
+ pImpl->OpaqueTypes.erase(opaque_this);
}
// For all the other type subclasses, there is either no contained types or
return &C.pImpl->Int64Ty;
}
+const PointerType *Type::getFloatPtrTy(LLVMContext &C, unsigned AS) {
+ return getFloatTy(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getDoublePtrTy(LLVMContext &C, unsigned AS) {
+ return getDoubleTy(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getX86_FP80PtrTy(LLVMContext &C, unsigned AS) {
+ return getX86_FP80Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getFP128PtrTy(LLVMContext &C, unsigned AS) {
+ return getFP128Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getPPC_FP128PtrTy(LLVMContext &C, unsigned AS) {
+ return getPPC_FP128Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getInt1PtrTy(LLVMContext &C, unsigned AS) {
+ return getInt1Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getInt8PtrTy(LLVMContext &C, unsigned AS) {
+ return getInt8Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getInt16PtrTy(LLVMContext &C, unsigned AS) {
+ return getInt16Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getInt32PtrTy(LLVMContext &C, unsigned AS) {
+ return getInt32Ty(C)->getPointerTo(AS);
+}
+
+const PointerType *Type::getInt64PtrTy(LLVMContext &C, unsigned AS) {
+ return getInt64Ty(C)->getPointerTo(AS);
+}
+
//===----------------------------------------------------------------------===//
// Derived Type Constructors
//===----------------------------------------------------------------------===//
/// isValidReturnType - Return true if the specified type is valid as a return
/// type.
bool FunctionType::isValidReturnType(const Type *RetTy) {
- if (RetTy->isFirstClassType()) {
- if (const PointerType *PTy = dyn_cast<PointerType>(RetTy))
- return PTy->getElementType() != Type::getMetadataTy(RetTy->getContext());
- return true;
- }
- if (RetTy == Type::getVoidTy(RetTy->getContext()) ||
- RetTy == Type::getMetadataTy(RetTy->getContext()) ||
- isa<OpaqueType>(RetTy))
- return true;
-
- // If this is a multiple return case, verify that each return is a first class
- // value and that there is at least one value.
- const StructType *SRetTy = dyn_cast<StructType>(RetTy);
- if (SRetTy == 0 || SRetTy->getNumElements() == 0)
- return false;
-
- for (unsigned i = 0, e = SRetTy->getNumElements(); i != e; ++i)
- if (!SRetTy->getElementType(i)->isFirstClassType())
- return false;
- return true;
+ return RetTy->getTypeID() != LabelTyID &&
+ RetTy->getTypeID() != MetadataTyID;
}
/// isValidArgumentType - Return true if the specified type is valid as an
/// argument type.
bool FunctionType::isValidArgumentType(const Type *ArgTy) {
- if ((!ArgTy->isFirstClassType() && !isa<OpaqueType>(ArgTy)) ||
- (isa<PointerType>(ArgTy) &&
- cast<PointerType>(ArgTy)->getElementType() ==
- Type::getMetadataTy(ArgTy->getContext())))
- return false;
-
- return true;
+ return ArgTy->isFirstClassType() || isa<OpaqueType>(ArgTy);
}
FunctionType::FunctionType(const Type *Result,
// pick so long as it doesn't point back to this type. We choose something
// concrete to avoid overhead for adding to AbstractTypeUser lists and
// stuff.
+ const Type *ConcreteTy = Type::getInt32Ty(getContext());
for (unsigned i = 1, e = NumContainedTys; i != e; ++i)
- ContainedTys[i] = Type::getInt32Ty(getContext());
+ ContainedTys[i] = ConcreteTy;
}
}
}
}
+namespace llvm { // in namespace llvm so findable by ADL
static bool TypesEqual(const Type *Ty, const Type *Ty2) {
std::map<const Type *, const Type *> EqTypes;
- return TypesEqual(Ty, Ty2, EqTypes);
+ return ::TypesEqual(Ty, Ty2, EqTypes);
+}
}
// AbstractTypeHasCycleThrough - Return true there is a path from CurTy to
return false;
}
-/// TypeHasCycleThroughItself - Return true if the specified type has a cycle
-/// back to itself.
+/// TypeHasCycleThroughItself - Return true if the specified type has
+/// a cycle back to itself.
+
+namespace llvm { // in namespace llvm so it's findable by ADL
static bool TypeHasCycleThroughItself(const Type *Ty) {
SmallPtrSet<const Type*, 128> VisitedTypes;
}
return false;
}
+}
//===----------------------------------------------------------------------===//
// Function Type Factory and Value Class...
// First, see if the type is already in the table, for which
// a reader lock suffices.
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
ITy = pImpl->IntegerTypes.get(IVT);
if (!ITy) {
LLVMContextImpl *pImpl = ReturnType->getContext().pImpl;
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
FT = pImpl->FunctionTypes.get(VT);
if (!FT) {
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
AT = pImpl->ArrayTypes.get(AVT);
if (!AT) {
}
bool ArrayType::isValidElementType(const Type *ElemTy) {
- if (ElemTy == Type::getVoidTy(ElemTy->getContext()) ||
- ElemTy == Type::getLabelTy(ElemTy->getContext()) ||
- ElemTy == Type::getMetadataTy(ElemTy->getContext()))
- return false;
-
- if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
- if (PTy->getElementType() == Type::getMetadataTy(ElemTy->getContext()))
- return false;
-
- return true;
+ return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID &&
+ ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy);
}
VectorType *VectorType::get(const Type *ElementType, unsigned NumElements) {
LLVMContextImpl *pImpl = ElementType->getContext().pImpl;
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
PT = pImpl->VectorTypes.get(PVT);
if (!PT) {
}
bool VectorType::isValidElementType(const Type *ElemTy) {
- if (ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
- isa<OpaqueType>(ElemTy))
- return true;
-
- return false;
+ return ElemTy->isInteger() || ElemTy->isFloatingPoint() ||
+ isa<OpaqueType>(ElemTy);
}
//===----------------------------------------------------------------------===//
LLVMContextImpl *pImpl = Context.pImpl;
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
ST = pImpl->StructTypes.get(STV);
if (!ST) {
}
bool StructType::isValidElementType(const Type *ElemTy) {
- if (ElemTy == Type::getVoidTy(ElemTy->getContext()) ||
- ElemTy == Type::getLabelTy(ElemTy->getContext()) ||
- ElemTy == Type::getMetadataTy(ElemTy->getContext()))
- return false;
-
- if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
- if (PTy->getElementType() == Type::getMetadataTy(ElemTy->getContext()))
- return false;
-
- return true;
+ return ElemTy->getTypeID() != VoidTyID && ElemTy->getTypeID() != LabelTyID &&
+ ElemTy->getTypeID() != MetadataTyID && !isa<FunctionType>(ElemTy);
}
PointerType *PointerType::get(const Type *ValueType, unsigned AddressSpace) {
assert(ValueType && "Can't get a pointer to <null> type!");
- assert(ValueType != Type::getVoidTy(ValueType->getContext()) &&
+ assert(ValueType->getTypeID() != VoidTyID &&
"Pointer to void is not valid, use i8* instead!");
assert(isValidElementType(ValueType) && "Invalid type for pointer element!");
PointerValType PVT(ValueType, AddressSpace);
LLVMContextImpl *pImpl = ValueType->getContext().pImpl;
- sys::SmartScopedLock<true> L(pImpl->TypeMapLock);
PT = pImpl->PointerTypes.get(PVT);
if (!PT) {
return PT;
}
-PointerType *Type::getPointerTo(unsigned addrs) const {
+const PointerType *Type::getPointerTo(unsigned addrs) const {
return PointerType::get(this, addrs);
}
bool PointerType::isValidElementType(const Type *ElemTy) {
- if (ElemTy == Type::getVoidTy(ElemTy->getContext()) ||
- ElemTy == Type::getLabelTy(ElemTy->getContext()))
- return false;
+ return ElemTy->getTypeID() != VoidTyID &&
+ ElemTy->getTypeID() != LabelTyID &&
+ ElemTy->getTypeID() != MetadataTyID;
+}
- if (const PointerType *PTy = dyn_cast<PointerType>(ElemTy))
- if (PTy->getElementType() == Type::getMetadataTy(ElemTy->getContext()))
- return false;
- return true;
+//===----------------------------------------------------------------------===//
+// Opaque Type Factory...
+//
+
+OpaqueType *OpaqueType::get(LLVMContext &C) {
+ OpaqueType *OT = new OpaqueType(C); // All opaque types are distinct
+
+ LLVMContextImpl *pImpl = C.pImpl;
+ pImpl->OpaqueTypes.insert(OT);
+ return OT;
}
+
//===----------------------------------------------------------------------===//
// Derived Type Refinement Functions
//===----------------------------------------------------------------------===//
// it. This function is called primarily by the PATypeHandle class.
void Type::addAbstractTypeUser(AbstractTypeUser *U) const {
assert(isAbstract() && "addAbstractTypeUser: Current type not abstract!");
- LLVMContextImpl *pImpl = getContext().pImpl;
- pImpl->AbstractTypeUsersLock.acquire();
AbstractTypeUsers.push_back(U);
- pImpl->AbstractTypeUsersLock.release();
}
// is annihilated, because there is no way to get a reference to it ever again.
//
void Type::removeAbstractTypeUser(AbstractTypeUser *U) const {
- LLVMContextImpl *pImpl = getContext().pImpl;
- pImpl->AbstractTypeUsersLock.acquire();
// Search from back to front because we will notify users from back to
// front. Also, it is likely that there will be a stack like behavior to
this->destroy();
}
- pImpl->AbstractTypeUsersLock.release();
}
// unlockedRefineAbstractTypeTo - This function is used when it is discovered
// will not cause users to drop off of the use list. If we resolve to ourself
// we succeed!
//
- pImpl->AbstractTypeUsersLock.acquire();
while (!AbstractTypeUsers.empty() && NewTy != this) {
AbstractTypeUser *User = AbstractTypeUsers.back();
assert(AbstractTypeUsers.size() != OldSize &&
"AbsTyUser did not remove self from user list!");
}
- pImpl->AbstractTypeUsersLock.release();
// If we were successful removing all users from the type, 'this' will be
// deleted when the last PATypeHolder is destroyed or updated from this type.
void DerivedType::refineAbstractTypeTo(const Type *NewType) {
// All recursive calls will go through unlockedRefineAbstractTypeTo,
// to avoid deadlock problems.
- sys::SmartScopedLock<true> L(NewType->getContext().pImpl->TypeMapLock);
unlockedRefineAbstractTypeTo(NewType);
}
DEBUG(errs() << "typeIsREFINED type: " << (void*)this << " " << *this <<"\n");
#endif
- LLVMContextImpl *pImpl = getContext().pImpl;
-
- pImpl->AbstractTypeUsersLock.acquire();
unsigned OldSize = AbstractTypeUsers.size(); OldSize=OldSize;
while (!AbstractTypeUsers.empty()) {
AbstractTypeUser *ATU = AbstractTypeUsers.back();
assert(AbstractTypeUsers.size() < OldSize-- &&
"AbstractTypeUser did not remove itself from the use list!");
}
- pImpl->AbstractTypeUsersLock.release();
}
// refineAbstractType - Called when a contained type is found to be more