First round of extended vector support. Here is an overview...

- added ocu_vector_type attribute, Sema::HandleOCUVectorTypeAttribute(). 
- added new AST node, OCUVectorType, a subclass of VectorType.
- added ASTContext::getOCUVectorType.
- changed ASTContext::convertToVectorType() to ASTContext::getVectorType(). This is 
unrelated to extended vectors, however I was in the vicinity and it was on my todo list.
Added a FIXME to Sema::HandleVectorTypeAttribute to deal with converting complex types.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@40007 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Steve Naroff 2007-07-18 18:00:27 +00:00
Родитель 464175bba1
Коммит 7332292412
6 изменённых файлов: 142 добавлений и 30 удалений

Просмотреть файл

@ -392,19 +392,17 @@ QualType ASTContext::getArrayType(QualType EltTy,ArrayType::ArraySizeModifier AS
return QualType(New, 0);
}
/// convertToVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType can be a pointer, array,
/// function, or built-in type (i.e. _Bool, integer, or float).
QualType ASTContext::convertToVectorType(QualType vecType, unsigned NumElts) {
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) {
BuiltinType *baseType;
baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
assert(baseType != 0 &&
"convertToVectorType(): Complex vector types unimplemented");
assert(baseType != 0 && "getVectorType(): Expecting a built-in type");
// Check if we've already instantiated a vector of this type.
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts);
VectorType::Profile(ID, vecType, NumElts, Type::Vector);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
@ -413,7 +411,7 @@ QualType ASTContext::convertToVectorType(QualType vecType, unsigned NumElts) {
// so fill in the canonical type field.
QualType Canonical;
if (!vecType->isCanonical()) {
Canonical = convertToVectorType(vecType.getCanonicalType(), NumElts);
Canonical = getVectorType(vecType.getCanonicalType(), NumElts);
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
@ -425,6 +423,37 @@ QualType ASTContext::convertToVectorType(QualType vecType, unsigned NumElts) {
return QualType(New, 0);
}
/// getOCUVectorType - Return the unique reference to an OCU vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType ASTContext::getOCUVectorType(QualType vecType, unsigned NumElts) {
BuiltinType *baseType;
baseType = dyn_cast<BuiltinType>(vecType.getCanonicalType().getTypePtr());
assert(baseType != 0 && "getOCUVectorType(): Expecting a built-in type");
// Check if we've already instantiated a vector of this type.
llvm::FoldingSetNodeID ID;
VectorType::Profile(ID, vecType, NumElts, Type::OCUVector);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(VTP, 0);
// If the element type isn't canonical, this won't be a canonical type either,
// so fill in the canonical type field.
QualType Canonical;
if (!vecType->isCanonical()) {
Canonical = getOCUVectorType(vecType.getCanonicalType(), NumElts);
// Get the new insert position for the node we care about.
VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(NewIP == 0 && "Shouldn't be in the map!");
}
OCUVectorType *New = new OCUVectorType(vecType, NumElts, Canonical);
VectorTypes.InsertNode(New, InsertPos);
Types.push_back(New);
return QualType(New, 0);
}
/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
///
QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) {

Просмотреть файл

@ -153,6 +153,7 @@ private:
// for the variable, measured in bytes. If curType and rawAttr are well
// formed, this routine will return a new vector type.
QualType HandleVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
QualType HandleOCUVectorTypeAttribute(QualType curType, AttributeList *rawAttr);
//===--------------------------------------------------------------------===//
// Statement Parsing Callbacks: SemaStmt.cpp.

Просмотреть файл

@ -956,6 +956,17 @@ void Sema::HandleDeclAttribute(Decl *New, AttributeList *rawAttr) {
tDecl->setUnderlyingType(newType);
}
}
if (strcmp(rawAttr->getAttributeName()->getName(), "ocu_vector_type") == 0) {
if (TypedefDecl *tDecl = dyn_cast<TypedefDecl>(New)) {
QualType newType = HandleOCUVectorTypeAttribute(tDecl->getUnderlyingType(),
rawAttr);
if (!newType.isNull()) // install the new vector type into the decl
tDecl->setUnderlyingType(newType);
} else {
Diag(rawAttr->getAttributeLoc(),
diag::err_typecheck_ocu_vector_not_typedef);
}
}
// FIXME: add other attributes...
}
@ -971,6 +982,42 @@ void Sema::HandleDeclAttributes(Decl *New, AttributeList *declspec_prefix,
}
}
QualType Sema::HandleOCUVectorTypeAttribute(QualType curType,
AttributeList *rawAttr) {
// check the attribute arugments.
if (rawAttr->getNumArgs() != 1) {
Diag(rawAttr->getAttributeLoc(), diag::err_attribute_wrong_number_arguments,
std::string("1"));
return QualType();
}
Expr *sizeExpr = static_cast<Expr *>(rawAttr->getArg(0));
llvm::APSInt vecSize(32);
if (!sizeExpr->isIntegerConstantExpr(vecSize, Context)) {
Diag(rawAttr->getAttributeLoc(), diag::err_attribute_vector_size_not_int,
sizeExpr->getSourceRange());
return QualType();
}
// unlike gcc's vector_size attribute, we do not allow vectors to be defined
// in conjunction with complex types (pointers, arrays, functions, etc.).
Type *canonType = curType.getCanonicalType().getTypePtr();
if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
Diag(rawAttr->getAttributeLoc(), diag::err_attribute_invalid_vector_type,
curType.getCanonicalType().getAsString());
return QualType();
}
// unlike gcc's vector_size attribute, the size is specified as the
// number of elements, not the number of bytes.
unsigned vectorSize = vecSize.getZExtValue();
if (vectorSize == 0) {
Diag(rawAttr->getAttributeLoc(), diag::err_attribute_zero_size,
sizeExpr->getSourceRange());
return QualType();
}
// Instantiate the vector type, the number of elements is > 0.
return Context.getOCUVectorType(curType, vectorSize);
}
QualType Sema::HandleVectorTypeAttribute(QualType curType,
AttributeList *rawAttr) {
// check the attribute arugments.
@ -990,14 +1037,20 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType,
// vector arrays, and functions returning vectors.
Type *canonType = curType.getCanonicalType().getTypePtr();
while (canonType->isPointerType() || canonType->isArrayType() ||
canonType->isFunctionType()) {
if (PointerType *PT = dyn_cast<PointerType>(canonType))
canonType = PT->getPointeeType().getTypePtr();
else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
canonType = AT->getElementType().getTypePtr();
else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
canonType = FT->getResultType().getTypePtr();
if (canonType->isPointerType() || canonType->isArrayType() ||
canonType->isFunctionType()) {
assert(1 && "HandleVector(): Complex type construction unimplemented");
/* FIXME: rebuild the type from the inside out, vectorizing the inner type.
do {
if (PointerType *PT = dyn_cast<PointerType>(canonType))
canonType = PT->getPointeeType().getTypePtr();
else if (ArrayType *AT = dyn_cast<ArrayType>(canonType))
canonType = AT->getElementType().getTypePtr();
else if (FunctionType *FT = dyn_cast<FunctionType>(canonType))
canonType = FT->getResultType().getTypePtr();
} while (canonType->isPointerType() || canonType->isArrayType() ||
canonType->isFunctionType());
*/
}
// the base type must be integer or float.
if (!(canonType->isIntegerType() || canonType->isRealFloatingType())) {
@ -1023,6 +1076,6 @@ QualType Sema::HandleVectorTypeAttribute(QualType curType,
// Since OpenCU requires 3 element vectors (OpenCU 5.1.2), we don't restrict
// the number of elements to be a power of two (unlike GCC).
// Instantiate the vector type, the number of elements is > 0.
return Context.convertToVectorType(curType, vectorSize/typeSize);
return Context.getVectorType(curType, vectorSize/typeSize);
}

Просмотреть файл

@ -79,10 +79,13 @@ public:
QualType getArrayType(QualType EltTy, ArrayType::ArraySizeModifier ASM,
unsigned EltTypeQuals, Expr *NumElts);
/// convertToVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType can be a pointer, array,
/// function, or built-in type (i.e. _Bool, integer, or float).
QualType convertToVectorType(QualType VectorType, unsigned NumElts);
/// getVectorType - Return the unique reference to a vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getVectorType(QualType VectorType, unsigned NumElts);
/// getOCUVectorType - Return the unique reference to an OCU vector type of
/// the specified element type and size. VectorType must be a built-in type.
QualType getOCUVectorType(QualType VectorType, unsigned NumElts);
/// getFunctionTypeNoProto - Return a K&R style C function type like 'int()'.
///

Просмотреть файл

@ -182,7 +182,7 @@ namespace clang {
class Type {
public:
enum TypeClass {
Builtin, Complex, Pointer, Reference, Array, Vector,
Builtin, Complex, Pointer, Reference, Array, Vector, OCUVector,
FunctionNoProto, FunctionProto,
TypeName, Tagged
};
@ -450,17 +450,23 @@ public:
static bool classof(const ArrayType *) { return true; }
};
/// VectorType -
///
/// VectorType - GCC generic vector type. This type is created using
/// __attribute__((vector_size(n)), where "n" specifies the vector size in
/// bytes. Since the constructor takes the number of vector elements, the
/// client is responsible for converting the size into the number of elements.
class VectorType : public Type, public llvm::FoldingSetNode {
protected:
/// ElementType - The element type of the vector.
QualType ElementType;
/// NumElements - The number of elements in the vector.
unsigned NumElements;
VectorType(QualType vecType, unsigned vectorSize, QualType canonType) :
Type(Vector, canonType), ElementType(vecType), NumElements(vectorSize) {}
VectorType(QualType vecType, unsigned nElements, QualType canonType) :
Type(Vector, canonType), ElementType(vecType), NumElements(nElements) {}
VectorType(TypeClass tc, QualType vecType, unsigned nElements,
QualType canonType) : Type(tc, canonType), ElementType(vecType),
NumElements(nElements) {}
friend class ASTContext; // ASTContext creates these.
public:
@ -470,17 +476,35 @@ public:
virtual void getAsStringInternal(std::string &InnerString) const;
void Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getElementType(), getNumElements());
Profile(ID, getElementType(), getNumElements(), getTypeClass());
}
static void Profile(llvm::FoldingSetNodeID &ID,
QualType ElementType, unsigned NumElements) {
static void Profile(llvm::FoldingSetNodeID &ID, QualType ElementType,
unsigned NumElements, TypeClass TypeClass) {
ID.AddPointer(ElementType.getAsOpaquePtr());
ID.AddInteger(NumElements);
ID.AddInteger(TypeClass);
}
static bool classof(const Type *T) {
return T->getTypeClass() == Vector || T->getTypeClass() == OCUVector;
}
static bool classof(const Type *T) { return T->getTypeClass() == Vector; }
static bool classof(const VectorType *) { return true; }
};
/// OCUVectorType - Extended vector type. This type is created using
/// __attribute__((ocu_vector_type(n)), where "n" is the number of elements.
/// Unlike vector_size, ocu_vector_type is only allowed on typedef's.
/// This class will enable syntactic extensions, like C++ style initializers.
class OCUVectorType : public VectorType {
OCUVectorType(QualType vecType, unsigned nElements, QualType canonType) :
VectorType(OCUVector, vecType, nElements, canonType) {}
friend class ASTContext; // ASTContext creates these.
public:
static bool classof(const VectorType *T) {
return T->getTypeClass() == OCUVector;
}
static bool classof(const OCUVectorType *) { return true; }
};
/// FunctionType - C99 6.7.5.3 - Function Declarators. This is the common base
/// class of FunctionTypeNoProto and FunctionTypeProto.
///

Просмотреть файл

@ -441,6 +441,8 @@ DIAG(err_attribute_zero_size, ERROR,
"zero vector size")
DIAG(err_typecheck_vector_not_convertable, ERROR,
"can't convert between vector values of different size ('%0' and '%1')")
DIAG(err_typecheck_ocu_vector_not_typedef, ERROR,
"ocu_vector_type only applies to types, not variables")
// Function Parameter Semantic Analysis.
DIAG(err_void_param_with_identifier, ERROR,