зеркало из https://github.com/microsoft/clang.git
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:
Родитель
464175bba1
Коммит
7332292412
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче