]> granicus.if.org Git - clang/commitdiff
Added vecreturn attribute parsing.
authorJohn Thompson <John.Thompson.JTSoftware@gmail.com>
Mon, 9 Aug 2010 21:53:52 +0000 (21:53 +0000)
committerJohn Thompson <John.Thompson.JTSoftware@gmail.com>
Mon, 9 Aug 2010 21:53:52 +0000 (21:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110609 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Parse/AttributeList.h
lib/AST/AttrImpl.cpp
lib/Parse/AttributeList.cpp
lib/Sema/SemaDeclAttr.cpp
test/Parser/cxx-altivec.cpp

index 76eb9d487871f517237d89833e7d545b188e488d..1e746c789895cde8a0a8f8a94620d7d0ddb1ac42 100644 (file)
@@ -376,6 +376,12 @@ def Visibility : Attr {
   let Args = [StringArgument<"Visibility">];
 }
 
+def VecReturn : Attr {
+  let Spellings = ["vecreturn"];
+  let Subjects = [CXXRecord];
+  let DoNotEmit = 0;
+}
+
 def WarnUnusedResult : Attr {
   let Spellings = ["warn_unused_result"];
 }
index 2b1bd1e63d7f51d187bfccb5346639c9ba7a350c..e6bf9b6cc62a34b7193ea075bf444dd823879bca 100644 (file)
@@ -111,6 +111,7 @@ public:
     AT_unavailable,
     AT_unused,
     AT_used,
+    AT_vecreturn,     // PS3 PPU-specific.
     AT_vector_size,
     AT_visibility,
     AT_warn_unused_result,
index 8992e4823d524dac39431204abc79be462c452ff..d9c0b5af437473a6f5e0bdb284ae2ea4f372852e 100644 (file)
@@ -126,6 +126,7 @@ DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
 DEF_SIMPLE_ATTR_CLONE(Unavailable)
 DEF_SIMPLE_ATTR_CLONE(Unused)
 DEF_SIMPLE_ATTR_CLONE(Used)
+DEF_SIMPLE_ATTR_CLONE(VecReturn)
 DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult)
 DEF_SIMPLE_ATTR_CLONE(Weak)
 DEF_SIMPLE_ATTR_CLONE(WeakImport)
index dc94420bef03c00d77e328a76629fdc7015b5469..8263923fe257f565f7dcb90202f44ecc0c33ee3b 100644 (file)
@@ -100,6 +100,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
     .Case("format_arg", AT_format_arg)
     .Case("gnu_inline", AT_gnu_inline)
     .Case("weak_import", AT_weak_import)
+    .Case("vecreturn", AT_vecreturn)
     .Case("vector_size", AT_vector_size)
     .Case("constructor", AT_constructor)
     .Case("unavailable", AT_unavailable)
index 2af3102ad759c64911bbdc1e2cd4bd4f48bb093a..cba5f4755dd070f0906bc1305118b2d57d746e2c 100644 (file)
@@ -687,6 +687,45 @@ static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
     d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
 }
 
+// PS3 PPU-specific.
+static void HandleVecReturnAttr(Decl *d, const AttributeList &Attr,
+                                       Sema &S) {
+/*
+  Returning a Vector Class in Registers
+  
+  According to the PPU ABI specifications, a class with a single member of vector type is returned in
+  memory when used as the return value of a function. This results in inefficient code when implementing
+  vector classes. To return the value in a single vector register, add the vecreturn attribute to the class
+  definition. This attribute is also applicable to struct types.
+  
+  Example:
+  
+  struct Vector
+  {
+    __vector float xyzw;
+  } __attribute__((vecreturn));
+  
+  Vector Add(Vector lhs, Vector rhs)
+  {
+    Vector result;
+    result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+    return result; // This will be returned in a register
+  }
+*/
+  if (!isa<CXXRecordDecl>(d)) {
+    S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
+      << Attr.getName() << 9 /*class*/;
+    return;
+  }
+
+  if (d->getAttr<VecReturnAttr>()) {
+    S.Diag(Attr.getLoc(), diag::err_repeat_attribute) << "vecreturn";
+    return;
+  }
+
+  d->addAttr(::new (S.Context) VecReturnAttr());
+}
+
 static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
   if (!isFunctionOrMethod(d) && !isa<ParmVarDecl>(d)) {
     S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type)
@@ -2181,6 +2220,7 @@ static void ProcessDeclAttribute(Scope *scope, Decl *D,
   case AttributeList::AT_noreturn:    HandleNoReturnAttr    (D, Attr, S); break;
   case AttributeList::AT_nothrow:     HandleNothrowAttr     (D, Attr, S); break;
   case AttributeList::AT_override:    HandleOverrideAttr    (D, Attr, S); break;
+  case AttributeList::AT_vecreturn:   HandleVecReturnAttr   (D, Attr, S); break;
 
   // Checker-specific.
   case AttributeList::AT_ns_returns_not_retained:
index a70eea077e7af04ddd127082fcce47512024fd91..8f463308112bdf0edc629ba3d723c29a69018fe7 100644 (file)
@@ -126,3 +126,38 @@ vector char v3 = (vector char)((vector int)('a', 'b', 'c', 'd'));
 vector int v4 = (vector int)(1, 2, 3, 4);
 vector float v5 = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
 vector char v6 = (vector char)((vector int)(1+2, -2, (int)(2.0 * 3), -(5-3)));
+
+#if 0 // Not ready yet.
+// bug 7553 - Problem with '==' and vectors
+void func() {
+  vector int v10i = (vector int)(1, 2, 3, 4);
+  vector int v11i = (vector int)(1, 2, 3, 4);
+  bool r10ieq = (v10i == v11i);
+  bool r10ine = (v10i != v11i);
+  bool r10igt = (v10i > v11i);
+  bool r10ige = (v10i >= v11i);
+  bool r10ilt = (v10i < v11i);
+  bool r10ile = (v10i <= v11i);
+  vector float v10f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  vector float v11f = (vector float)(1.0f, 2.0f, 3.0f, 4.0f);
+  bool r10feq = (v10f == v11f);
+  bool r10fne = (v10f != v11f);
+  bool r10fgt = (v10f > v11f);
+  bool r10fge = (v10f >= v11f);
+  bool r10flt = (v10f < v11f);
+  bool r10fle = (v10f <= v11f);
+}
+#endif
+
+// vecreturn attribute test
+struct Vector
+{
+       __vector float xyzw;
+} __attribute__((vecreturn));
+
+Vector Add(Vector lhs, Vector rhs)
+{
+       Vector result;
+       result.xyzw = vec_add(lhs.xyzw, rhs.xyzw);
+       return result; // This will (eventually) be returned in a register
+}