[cfe-commits] [PATCH] AltiVec vector support - stage 1
Douglas Gregor
dgregor at apple.com
Fri Dec 18 14:05:45 PST 2009
Hi John,
On Dec 16, 2009, at 11:45 AM, John Thompson wrote:
> Nudge nudge...
>
> I know I need to do an error message checking test too. This is
> just a start, to avoid too much change at once, and to make sure I'm
> on the right track. Please review it before it gets too stale.
>
> -John
>
> On Fri, Dec 11, 2009 at 8:03 PM, John Thompson <john.thompson.jtsoftware at gmail.com
> > wrote:
> Here's a stab a the first stage of adding AltiVec vector support,
> supporting the AltiVec types __vector, vector, __pixel, pixel, and
> bool. I've also enclosed a couple of tests for it for the test/
> Parser directory.
>
> Some of it might be iffy, but I hope you can help me get it into
> shape with your feedback.
>
> I added a couple of flags to the DeclSpec class to help me know when
> the types are used, TypeAltiVecVector and TypeAltiVecPixel. The
> AltiVec standard doesn't say much about pixel, other than it is used
> as "__vector __pixel", and that it represents 8 unsigned shorts.
> Therefore, instead of making a new TST, I made it more like an alias
> via the TypeAltiVecPixel flag.
>
> I also added two corresponding flags to the VectorType class (and
> the getVectorType function). Currently, these mainly just help with
> printing, but maybe there will be a need to distinguish down the
> road. This is kind of an iffy part, because there were a couple of
> places where I don't know if the vector involved is an AltiVec
> vector, and the flags are used in the type look up.
>
> Per the previous conversation, I made __vector and __pixel true
> keywords if -faltivec is used, and vector and pixel are context-
> sensitive keywords. The AltiVec standard also specifies that bool
> is a keyword in C, so I diddled the token flags a bit for that too.
>
> I put the Token patching code in inline functions, so I hope the
> performance impact is not too bad.
> There's probably some holes in the testing, i.e. sizeof. But,
> because I'm piggy-backing on the existing vectors, I'm hoping most
> things will still just work.
>
> I'm not sure what the next stage should be, the built-in functions?
>
> Thanks.
>
> -John
+def err_invalid_pixel_decl_spec_combination : Error<
+ "\"__pixel\" must be preceeded by \"__vector\". '%0' declaration
specifier not allowed here">;
Typo "preceeded".
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h (revision 91204)
+++ include/clang/AST/Type.h (working copy)
@@ -1576,7 +1576,8 @@
/// 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
+/// bytes; or from an Altivec __vector or vector declaration.
+/// 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:
@@ -1586,13 +1587,21 @@
/// NumElements - The number of elements in the vector.
unsigned NumElements;
- VectorType(QualType vecType, unsigned nElements, QualType
canonType) :
+ /// AltiVec - True if this is for an Altivec vector.
+ bool AltiVec;
+
+ /// Pixel - True if this is for an Altivec vector pixel.
+ bool Pixel;
+
I think this is right, but I want to check: are AltiVec vectors more
like GCC's vectors (handled by VectorType) or more like OpenCL's
vectors (handled by ExtVectorType)? OpenCL vectors are mainly GCC's
vectors + the swizzling syntax like "myvec.xy".
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h (revision 91204)
+++ include/clang/Parse/Parser.h (working copy)
@@ -320,6 +320,80 @@
/// annotated.
bool TryAnnotateCXXScopeToken(bool EnteringContext = false);
+ /// TryAltiVecToken - Check for context-sensitive AltiVec
identifier tokens,
+ /// replacing them with the non-context-sensitive keywords. This
returns
+ /// true if the token was replaced.
+ bool TryAltiVecToken(DeclSpec &DS) {
+ if (getLang().AltiVec) {
+ if (Tok.getIdentifierInfo()->isStr<7>("vector")) {
It would be more efficient just to keep the IdentiferInfo * for the
identifiers "vector" and "pixel" in the parser (only when AltiVec is
enabled, of course), then do a pointer comparison rather than a string
comparison.
+ const Token &nextToken = NextToken();
Tokens are small; it's best to just copy them, e.g.,
Token nextToken = NextToken();
+ switch (nextToken.getKind()) {
+ case tok::kw_short:
+ case tok::kw_long:
+ case tok::kw_signed:
+ case tok::kw_unsigned:
+ case tok::kw_void:
+ case tok::kw_char:
+ case tok::kw_int:
+ case tok::kw_float:
+ case tok::kw_double:
+ case tok::kw_bool:
+ case tok::kw___pixel:
+ Tok.setKind(tok::kw___vector);
+ return true;
+ case tok::identifier:
+ if (nextToken.getIdentifierInfo()->isStr<6>("pixel")) {
+ Tok.setKind(tok::kw___vector);
+ return true;
+ }
By changing the current token, we lose track of whether we saw
"vector" or "__vector"; I guess it doesn't really matter. Still,
wouldn't it be easier just to update the DeclSpec at this point?
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp (revision 91204)
+++ lib/Sema/SemaType.cpp (working copy)
@@ -339,6 +339,11 @@
if (TheSema.getLangOptions().Freestanding)
TheSema.Diag(DS.getTypeSpecComplexLoc(),
diag::ext_freestanding_complex);
Result = Context.getComplexType(Result);
+ } else if (DS.isTypeAltiVecVector()) {
+ unsigned typeSize = static_cast<unsigned>(Context.getTypeSize
(Result));
+ assert(typeSize > 0 && "type size for vector must be greater than
0 bits");
+ Result = Context.getVectorType(Result, 128/typeSize, true,
+ DS.isTypeAltiVecPixel());
}
At some point, we'll need more semantic checking here, e.g., to ignore
"long long" and complain about the deprecation of "long", if I'm to
believe
http://publib.boulder.ibm.com/infocenter/macxhelp/v6v81/index.jsp?topic=/com.ibm.vacpp6m.doc/language/ref/clrc03altivec_types.htm
Or perhaps there's some actual AltiVec specification I could use to
help understand this stuff better?
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp (revision 91204)
+++ lib/AST/TypePrinter.cpp (working copy)
@@ -240,15 +240,24 @@
}
void TypePrinter::PrintVector(const VectorType *T, std::string &S) {
- // FIXME: We prefer to print the size directly here, but have no way
- // to get the size of the type.
- Print(T->getElementType(), S);
- std::string V = "__attribute__((__vector_size__(";
- V += llvm::utostr_32(T->getNumElements()); // convert back to bytes.
- std::string ET;
- Print(T->getElementType(), ET);
- V += " * sizeof(" + ET + ")))) ";
- S = V + S;
+ if (T->isAltiVec()) {
+ if (T->isPixel())
+ S = "vector pixel " + S;
+ else {
+ Print(T->getElementType(), S);
+ S = "vector " + S;
+ }
It would probably be better to print with "__vector" and "__pixel",
since those keywords are always available.
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h (revision 91204)
+++ include/clang/AST/ASTContext.h (working copy)
@@ -498,7 +498,8 @@
/// 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);
+ QualType getVectorType(QualType VectorType, unsigned NumElts,
+ bool AltiVec, bool IsPixel);
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp (revision 91204)
+++ lib/AST/ASTContext.cpp (working copy)
@@ -1590,7 +1590,8 @@
/// 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) {
+QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts,
+ bool IsAltiVec, bool IsPixel) {
BuiltinType *baseType;
baseType = dyn_cast<BuiltinType>(getCanonicalType
(vecType).getTypePtr());
@@ -1598,7 +1599,8 @@
// Check if we've already instantiated a vector of this type.
llvm::FoldingSetNodeID ID;
- VectorType::Profile(ID, vecType, NumElts, Type::Vector);
+ VectorType::Profile(ID, vecType, NumElts, Type::Vector,
+ IsAltiVec, IsPixel);
void *InsertPos = 0;
if (VectorType *VTP = VectorTypes.FindNodeOrInsertPos(ID,
InsertPos))
return QualType(VTP, 0);
@@ -1607,14 +1609,15 @@
// so fill in the canonical type field.
QualType Canonical;
if (!vecType.isCanonical()) {
- Canonical = getVectorType(getCanonicalType(vecType), NumElts);
+ Canonical = getVectorType(getCanonicalType(vecType),
+ NumElts, IsAltiVec, IsPixel);
This makes it so that AltiVec vectors are completely distinct types
from equivalently-sized vectors (as declared with __attribute__
((vector_size(blah))). If we want to be able to cast between AltiVec
vectors and GCC-style vectors, we'll need to add type-compatibility
logic (for C) and type-conversion logic (for C++). I don't know which
way is correct... how does GCC handle compatibility between the
various kinds of vectors? We'll need to follow its lead.
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp (revision 91204)
+++ lib/Parse/ParseDecl.cpp (working copy)
@@ -393,6 +393,12 @@
}
if (AllowFunctionDefinitions && D.isFunctionDeclarator()) {
+ // If attributes are present, parse them now.
+ if (Tok.is(tok::kw___attribute)) {
+ SourceLocation Loc;
+ AttributeList *AttrList = ParseGNUAttributes(&Loc);
+ D.AddAttributes(AttrList, Loc);
+ }
This seems totally unrelated to AltiVec vectors?
+bool DeclSpec::SetTypeAltiVecPixel(bool isAltiVecPixel,
SourceLocation Loc,
+ const char *&PrevSpec, unsigned &DiagID) {
+ if (!TypeAltiVecVector || (TypeSpecType != TST_unspecified)) {
+ PrevSpec = DeclSpec::getSpecifierName((TST) TypeSpecType);
+ DiagID = diag::err_invalid_pixel_decl_spec_combination;
+ return true;
+ }
+ TypeSpecType = TST_int;
+ TypeSpecSign = TSS_unsigned;
+ TypeSpecWidth = TSW_short;
+ TypeAltiVecPixel = isAltiVecPixel;
+ TSTLoc = Loc;
+ return false;
+}
+
pixel is an unsigned short? Weird.
Thanks for working on this!
- Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20091218/54a72ec0/attachment.html>
More information about the cfe-commits
mailing list