]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Added support for Cilk Plus SIMD-enabled function for C.
authorBalaji V. Iyer <balaji.v.iyer@intel.com>
Wed, 18 Dec 2013 19:00:21 +0000 (19:00 +0000)
committerBalaji V. Iyer <bviyer@gcc.gnu.org>
Wed, 18 Dec 2013 19:00:21 +0000 (11:00 -0800)
+++ gcc/ChangeLog
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * omp-low.c (simd_clone_clauses_extract): Replaced the string
+       "cilk simd elemental" with "cilk simd function."
+       * config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen):
+       Removed a carriage-return from a warning string.
+
+++ gcc/c-family/ChangeLog
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-common.c (c_common_attribute_table): Added "cilk simd function"
+       attribute.
+       * c-pragma.h (enum pragma_cilk_clause): Remove.
+       (enum pragma_omp_clause):  Added the following fields:
+       PRAGMA_CILK_CLAUSE_NOMASK, PRAGMA_CILK_CLAUSE_MASK,
+       PRAGMA_CILK_CLAUSE_VECTORLENGTH, PRAGMA_CILK_CLAUSE_NONE,
+       PRAGMA_CILK_CLAUSE_LINEAR, PRAGMA_CILK_CLAUSE_PRIVATE,
+       PRAGMA_CILK_CLAUSE_FIRSTPRIVATE, PRAGMA_CILK_CLAUSE_LASTPRIVATE,
+       PRAGMA_CILK_CLAUSE_UNIFORM.
+
+

+++ gcc/c/ChangeLog
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-parser.c (struct c_parser::cilk_simd_fn_tokens): Added new field.
+       (c_parser_declaration_or_fndef): Added a check if cilk_simd_fn_tokens
+       field in parser is not empty.  If not-empty, call the function
+       c_parser_finish_omp_declare_simd.
+       (c_parser_cilk_clause_vectorlength): Modified function to be shared
+       between SIMD-enabled functions and #pragma simd.  Added new parameter.
+       (c_parser_cilk_all_clauses): Modified the usage of the function
+       c_parser_cilk_clause_vectorlength as mentioned above.
+       (c_parser_cilk_simd_fn_vector_attrs): New function.
+       (c_finish_cilk_simd_fn_tokens): Likewise.
+       (is_cilkplus_vector_p): Likewise.
+       (c_parser_omp_clause_name): Added checking for "vectorlength,"
+       "nomask," and "mask" strings in clause name.
+       (c_parser_omp_all_clauses): Added 3 new case statements:
+       PRAGMA_CILK_CLAUSE_VECTORLENGTH, PRAGMA_CILK_CLAUSE_MASK and
+       PRAGMA_CILK_CLAUSE_NOMASK.
+       (c_parser_attributes): Added a cilk_simd_fn_tokens parameter.  Added a
+       check for vector attribute and if so call the function
+       c_parser_cilk_simd_fn_vector_attrs.  Also, when Cilk plus is enabled,
+       called the function c_finish_cilk_simd_fn_tokens.
+       (c_finish_omp_declare_simd): Added a check if cilk_simd_fn_tokens
in
+       parser field is non-empty.  If so, parse them as you would parse
+       the omp declare simd pragma.
+       (c_parser_omp_clause_linear): Added a new bool parm. is_cilk_simd_fn.
+       Added a check when step is a parameter and flag it as error.
+       (CILK_SIMD_FN_CLAUSE_MASK): New #define.
+       (c_parser_cilk_clause_name): Changed pragma_cilk_clause to
+       pragma_omp_clause.
+

+++ gcc/testsuite/ChangeLog
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-c++-common/cilk-plus/SE/ef_test.c: New test.
+       * c-c++-common/cilk-plus/SE/ef_test2.c: Likewise.
+       * c-c++-common/cilk-plus/SE/vlength_errors.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error2.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error3.c: Likewise.
+       * gcc.dg/cilk-plus/cilk-plus.exp: Added calls for the above tests.
+

From-SVN: r206095

17 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-pragma.h
gcc/c/ChangeLog
gcc/c/c-parser.c
gcc/config/i386/i386.c
gcc/cp/parser.c
gcc/omp-low.c
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test2.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cilk-plus/cilk-plus.exp

index b83157ff2504e432f121f1a399c168156cd1ac60..7f77d8a89805e1281eed49b3ce95f93b4ac13cc8 100644 (file)
@@ -1,3 +1,10 @@
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * omp-low.c (simd_clone_clauses_extract): Replaced the string
+       "cilk simd elemental" with "cilk simd function."
+       * config/i386/i386.c (ix86_simd_clone_compute_vecsize_and_simdlen): 
+       Removed a carriage-return from a warning string.
+       
 2013-12-18  Aldy Hernandez  <aldyh@redhat.com>
 
        * passes.c (execute_function_dump): Set graph_dump_initialized
index 462b4b18dd00ca9aeb85ebe180bd06bc96efb9fc..ffd8eff13242a5dbfe52fc9695e21cb2c2f57a3b 100644 (file)
@@ -1,3 +1,16 @@
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-common.c (c_common_attribute_table): Added "cilk simd function"
+       attribute.
+       * c-pragma.h (enum pragma_cilk_clause): Remove.
+       (enum pragma_omp_clause):  Added the following fields:
+       PRAGMA_CILK_CLAUSE_NOMASK, PRAGMA_CILK_CLAUSE_MASK,
+       PRAGMA_CILK_CLAUSE_VECTORLENGTH, PRAGMA_CILK_CLAUSE_NONE,
+       PRAGMA_CILK_CLAUSE_LINEAR, PRAGMA_CILK_CLAUSE_PRIVATE,
+       PRAGMA_CILK_CLAUSE_FIRSTPRIVATE, PRAGMA_CILK_CLAUSE_LASTPRIVATE,
+       PRAGMA_CILK_CLAUSE_UNIFORM.
+
+       
 2013-12-11  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
        * cilk.c (cilk_outline): Made this function non-static.
index cfaeaf09f6bcd0823f73e3712ce956ac4991e0ef..229f8fa22e89adf8c31dc0dfe5c266d6a7ed547c 100644 (file)
@@ -762,6 +762,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_returns_nonnull_attribute, false },
   { "omp declare simd",       0, -1, true,  false, false,
                              handle_omp_declare_simd_attribute, false },
+  { "cilk simd function",     0, -1, true,  false, false,
+                             handle_omp_declare_simd_attribute, false },
   { "omp declare target",     0, 0, true, false, false,
                              handle_omp_declare_target_attribute, false },
   { NULL,                     0, 0, false, false, false, NULL, false }
index 5379b9e4eb82b178060ff597c8dc11b18018d939..683b3f8aca9e46e079dd7062cbca66f1386fe372 100644 (file)
@@ -103,19 +103,20 @@ typedef enum pragma_omp_clause {
   PRAGMA_OMP_CLAUSE_THREAD_LIMIT,
   PRAGMA_OMP_CLAUSE_TO,
   PRAGMA_OMP_CLAUSE_UNIFORM,
-  PRAGMA_OMP_CLAUSE_UNTIED
-} pragma_omp_clause;
-
-/* All Cilk Plus #pragma omp clauses.  */
-typedef enum pragma_cilk_clause {
-  PRAGMA_CILK_CLAUSE_NONE = 0,
+  PRAGMA_OMP_CLAUSE_UNTIED,
+  
+  /* Clauses for Cilk Plus SIMD-enabled function.  */
+  PRAGMA_CILK_CLAUSE_NOMASK,
+  PRAGMA_CILK_CLAUSE_MASK,
   PRAGMA_CILK_CLAUSE_VECTORLENGTH,
-  PRAGMA_CILK_CLAUSE_LINEAR,
-  PRAGMA_CILK_CLAUSE_PRIVATE,
-  PRAGMA_CILK_CLAUSE_FIRSTPRIVATE,
-  PRAGMA_CILK_CLAUSE_LASTPRIVATE,
-  PRAGMA_CILK_CLAUSE_REDUCTION
-} pragma_cilk_clause;
+  PRAGMA_CILK_CLAUSE_NONE = PRAGMA_OMP_CLAUSE_NONE,
+  PRAGMA_CILK_CLAUSE_LINEAR = PRAGMA_OMP_CLAUSE_LINEAR,
+  PRAGMA_CILK_CLAUSE_PRIVATE = PRAGMA_OMP_CLAUSE_PRIVATE,
+  PRAGMA_CILK_CLAUSE_FIRSTPRIVATE = PRAGMA_OMP_CLAUSE_FIRSTPRIVATE,
+  PRAGMA_CILK_CLAUSE_LASTPRIVATE = PRAGMA_OMP_CLAUSE_LASTPRIVATE,
+  PRAGMA_CILK_CLAUSE_REDUCTION = PRAGMA_OMP_CLAUSE_REDUCTION,
+  PRAGMA_CILK_CLAUSE_UNIFORM = PRAGMA_OMP_CLAUSE_UNIFORM
+} pragma_omp_clause;
 
 extern struct cpp_reader* parse_in;
 
index 9db78c6baa67608c4c902c26906f9fa293069f35..58631eeea09f02a8103524d872c809a768907552 100644 (file)
@@ -1,3 +1,34 @@
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-parser.c (struct c_parser::cilk_simd_fn_tokens): Added new field.
+       (c_parser_declaration_or_fndef): Added a check if cilk_simd_fn_tokens
+       field in parser is not empty.  If not-empty, call the function
+       c_parser_finish_omp_declare_simd.
+       (c_parser_cilk_clause_vectorlength): Modified function to be shared
+       between SIMD-enabled functions and #pragma simd.  Added new parameter.
+       (c_parser_cilk_all_clauses): Modified the usage of the function
+       c_parser_cilk_clause_vectorlength as mentioned above.
+       (c_parser_cilk_simd_fn_vector_attrs): New function.
+       (c_finish_cilk_simd_fn_tokens): Likewise.
+       (is_cilkplus_vector_p): Likewise.
+       (c_parser_omp_clause_name): Added checking for "vectorlength,"
+       "nomask," and "mask" strings in clause name.
+       (c_parser_omp_all_clauses): Added 3 new case statements:
+       PRAGMA_CILK_CLAUSE_VECTORLENGTH, PRAGMA_CILK_CLAUSE_MASK and
+       PRAGMA_CILK_CLAUSE_NOMASK.
+       (c_parser_attributes): Added a cilk_simd_fn_tokens parameter.  Added a
+       check for vector attribute and if so call the function
+       c_parser_cilk_simd_fn_vector_attrs.  Also, when Cilk plus is enabled,
+       called the function c_finish_cilk_simd_fn_tokens.
+       (c_finish_omp_declare_simd): Added a check if cilk_simd_fn_tokens in
+       parser field is non-empty.  If so, parse them as you would parse
+       the omp declare simd pragma.
+       (c_parser_omp_clause_linear): Added a new bool parm. is_cilk_simd_fn.
+       Added a check when step is a parameter and flag it as error.
+       (CILK_SIMD_FN_CLAUSE_MASK): New #define.
+       (c_parser_cilk_clause_name): Changed pragma_cilk_clause to
+       pragma_omp_clause.
+
 2013-12-17  Thomas Schwinge  <thomas@codesourcery.com>
 
        * c-parser.c (c_parser_omp_parallel): Fix description.
index 28f53c166d4da3ef83afb1908024aaed85c712cc..5dd953d7a2f66884f2d1185cad7376b85fb1f56b 100644 (file)
@@ -208,6 +208,12 @@ typedef struct GTY(()) c_parser {
   /* True if we are in a context where the Objective-C "Property attribute"
      keywords are valid.  */
   BOOL_BITFIELD objc_property_attr_context : 1;
+
+  /* Cilk Plus specific parser/lexer information.  */
+
+  /* Buffer to hold all the tokens from parsing the vector attribute for the
+     SIMD-enabled functions (formerly known as elemental functions).  */
+  vec <c_token, va_gc> *cilk_simd_fn_tokens;
 } c_parser;
 
 
@@ -1245,6 +1251,7 @@ static bool c_parser_objc_diagnose_bad_element_prefix
 static void c_parser_cilk_simd (c_parser *);
 static bool c_parser_cilk_verify_simd (c_parser *, enum pragma_context);
 static tree c_parser_array_notation (location_t, c_parser *, tree, tree);
+static tree c_parser_cilk_clause_vectorlength (c_parser *, tree, bool);
 
 /* Parse a translation unit (C90 6.7, C99 6.9).
 
@@ -1646,7 +1653,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
                                        C_DTR_NORMAL, &dummy);
       if (declarator == NULL)
        {
-         if (omp_declare_simd_clauses.exists ())
+         if (omp_declare_simd_clauses.exists ()
+             || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
            c_finish_omp_declare_simd (parser, NULL_TREE, NULL_TREE,
                                       omp_declare_simd_clauses);
          c_parser_skip_to_end_of_block_or_statement (parser);
@@ -1733,7 +1741,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
                                  chainon (postfix_attrs, all_prefix_attrs));
                  if (!d)
                    d = error_mark_node;
-                 if (omp_declare_simd_clauses.exists ())
+                 if (omp_declare_simd_clauses.exists ()
+                     || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
                    c_finish_omp_declare_simd (parser, d, NULL_TREE,
                                               omp_declare_simd_clauses);
                }
@@ -1745,7 +1754,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
                                  chainon (postfix_attrs, all_prefix_attrs));
                  if (!d)
                    d = error_mark_node;
-                 if (omp_declare_simd_clauses.exists ())
+                 if (omp_declare_simd_clauses.exists ()
+                     || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
                    c_finish_omp_declare_simd (parser, d, NULL_TREE,
                                               omp_declare_simd_clauses);
                  start_init (d, asm_name, global_bindings_p ());
@@ -1773,7 +1783,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
              tree d = start_decl (declarator, specs, false,
                                   chainon (postfix_attrs,
                                            all_prefix_attrs));
-             if (omp_declare_simd_clauses.exists ())
+             if (omp_declare_simd_clauses.exists ()
+                 || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
                {
                  tree parms = NULL_TREE;
                  if (d && TREE_CODE (d) == FUNCTION_DECL)
@@ -1901,7 +1912,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok,
        c_parser_declaration_or_fndef (parser, false, false, false,
                                       true, false, NULL, vNULL);
       store_parm_decls ();
-      if (omp_declare_simd_clauses.exists ())
+      if (omp_declare_simd_clauses.exists ()
+         || !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
        c_finish_omp_declare_simd (parser, current_function_decl, NULL_TREE,
                                   omp_declare_simd_clauses);
       DECL_STRUCT_FUNCTION (current_function_decl)->function_start_locus
@@ -3765,6 +3777,87 @@ c_parser_attribute_any_word (c_parser *parser)
   return attr_name;
 }
 
+/* Returns true of NAME is an IDENTIFIER_NODE with identiifer "vector,"
+   "__vector" or "__vector__."  */
+
+static inline bool
+is_cilkplus_vector_p (tree name)
+{ 
+  if (flag_enable_cilkplus && is_attribute_p ("vector", name)) 
+    return true;
+  return false;
+}
+
+#define CILK_SIMD_FN_CLAUSE_MASK                                 \
+       ((OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_VECTORLENGTH)   \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_LINEAR)       \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_UNIFORM)      \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_MASK)         \
+        | (OMP_CLAUSE_MASK_1 << PRAGMA_CILK_CLAUSE_NOMASK))
+
+/* Parses the vector attribute of SIMD enabled functions in Cilk Plus.
+   VEC_TOKEN is the "vector" token that is replaced with "simd" and
+   pushed into the token list. 
+   Syntax:
+   vector
+   vector (<vector attributes>).  */
+
+static void
+c_parser_cilk_simd_fn_vector_attrs (c_parser *parser, c_token vec_token)
+{
+  gcc_assert (is_cilkplus_vector_p (vec_token.value));
+  
+  int paren_scope = 0;
+  vec_safe_push (parser->cilk_simd_fn_tokens, vec_token);
+  /* Consume the "vector" token.  */
+  c_parser_consume_token (parser);
+
+  if (c_parser_next_token_is (parser, CPP_OPEN_PAREN))
+    {
+      c_parser_consume_token (parser);
+      paren_scope++;
+    }
+  while (paren_scope > 0)
+    {
+      c_token *token = c_parser_peek_token (parser);
+      if (token->type == CPP_OPEN_PAREN)
+        paren_scope++;
+      else if (token->type == CPP_CLOSE_PAREN)
+        paren_scope--;
+      /* Do not push the last ')' since we are not pushing the '('.  */
+      if (!(token->type == CPP_CLOSE_PAREN && paren_scope == 0))
+       vec_safe_push (parser->cilk_simd_fn_tokens, *token);
+      c_parser_consume_token (parser);
+    }
+  
+  /* Since we are converting an attribute to a pragma, we need to end the
+     attribute with PRAGMA_EOL.  */
+  c_token eol_token;
+  memset (&eol_token, 0, sizeof (eol_token));
+  eol_token.type = CPP_PRAGMA_EOL;
+  vec_safe_push (parser->cilk_simd_fn_tokens, eol_token);
+}
+
+/* Add 2 CPP_EOF at the end of PARSER->ELEM_FN_TOKENS vector.  */
+
+static void
+c_finish_cilk_simd_fn_tokens (c_parser *parser)
+{
+  c_token last_token = parser->cilk_simd_fn_tokens->last ();
+
+  /* c_parser_attributes is called in several places, so if these EOF
+     tokens are already inserted, then don't do them again.  */
+  if (last_token.type == CPP_EOF)
+    return;
+  
+  /* Two CPP_EOF token are added as a safety net since the normal C
+     front-end has two token look-ahead.  */
+  c_token eof_token;
+  eof_token.type = CPP_EOF;
+  vec_safe_push (parser->cilk_simd_fn_tokens, eof_token);
+  vec_safe_push (parser->cilk_simd_fn_tokens, eof_token);
+}
+
 /* Parse (possibly empty) attributes.  This is a GNU extension.
 
    attributes:
@@ -3829,6 +3922,12 @@ c_parser_attributes (c_parser *parser)
          attr_name = c_parser_attribute_any_word (parser);
          if (attr_name == NULL)
            break;
+         if (is_cilkplus_vector_p (attr_name))           
+           {
+             c_token *v_token = c_parser_peek_token (parser);
+             c_parser_cilk_simd_fn_vector_attrs (parser, *v_token);
+             continue;
+           }
          c_parser_consume_token (parser);
          if (c_parser_next_token_is_not (parser, CPP_OPEN_PAREN))
            {
@@ -3909,6 +4008,9 @@ c_parser_attributes (c_parser *parser)
        }
       parser->lex_untranslated_string = false;
     }
+
+  if (flag_enable_cilkplus && !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
+    c_finish_cilk_simd_fn_tokens (parser);
   return attrs;
 }
 
@@ -9524,6 +9626,8 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_MAP;
          else if (!strcmp ("mergeable", p))
            result = PRAGMA_OMP_CLAUSE_MERGEABLE;
+         else if (flag_enable_cilkplus && !strcmp ("mask", p))
+           result = PRAGMA_CILK_CLAUSE_MASK;
          break;
        case 'n':
          if (!strcmp ("notinbranch", p))
@@ -9534,6 +9638,8 @@ c_parser_omp_clause_name (c_parser *parser)
            result = PRAGMA_OMP_CLAUSE_NUM_TEAMS;
          else if (!strcmp ("num_threads", p))
            result = PRAGMA_OMP_CLAUSE_NUM_THREADS;
+         else if (flag_enable_cilkplus && !strcmp ("nomask", p))
+           result = PRAGMA_CILK_CLAUSE_NOMASK;
          break;
        case 'o':
          if (!strcmp ("ordered", p))
@@ -9577,6 +9683,10 @@ c_parser_omp_clause_name (c_parser *parser)
          else if (!strcmp ("untied", p))
            result = PRAGMA_OMP_CLAUSE_UNTIED;
          break;
+       case 'v':
+         if (flag_enable_cilkplus && !strcmp ("vectorlength", p))
+           result = PRAGMA_CILK_CLAUSE_VECTORLENGTH;
+         break;
        }
     }
 
@@ -10393,7 +10503,7 @@ c_parser_omp_clause_aligned (c_parser *parser, tree list)
    linear ( variable-list : expression ) */
 
 static tree
-c_parser_omp_clause_linear (c_parser *parser, tree list)
+c_parser_omp_clause_linear (c_parser *parser, tree list, bool is_cilk_simd_fn)
 {
   location_t clause_loc = c_parser_peek_token (parser)->location;
   tree nl, c, step;
@@ -10410,6 +10520,11 @@ c_parser_omp_clause_linear (c_parser *parser, tree list)
       step = c_parser_expression (parser).value;
       mark_exp_read (step);
       step = c_fully_fold (step, false, NULL);
+      if (is_cilk_simd_fn && TREE_CODE (step) == PARM_DECL)
+       {
+         sorry ("using parameters for %<linear%> step is not supported yet");
+         step = integer_one_node;
+       }
       if (!INTEGRAL_TYPE_P (TREE_TYPE (step)))
        {
          error_at (clause_loc, "%<linear%> clause step expression must "
@@ -10768,7 +10883,7 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
                          const char *where, bool finish_p = true)
 {
   tree clauses = NULL;
-  bool first = true;
+  bool first = true, cilk_simd_fn = false;
 
   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
     {
@@ -10854,11 +10969,13 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          c_name = "untied";
          break;
        case PRAGMA_OMP_CLAUSE_INBRANCH:
+       case PRAGMA_CILK_CLAUSE_MASK:
          clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_INBRANCH,
                                                clauses);
          c_name = "inbranch";
          break;
        case PRAGMA_OMP_CLAUSE_NOTINBRANCH:
+       case PRAGMA_CILK_CLAUSE_NOMASK:
          clauses = c_parser_omp_clause_branch (parser, OMP_CLAUSE_NOTINBRANCH,
                                                clauses);
          c_name = "notinbranch";
@@ -10924,8 +11041,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          clauses = c_parser_omp_clause_aligned (parser, clauses);
          c_name = "aligned";
          break;
-       case PRAGMA_OMP_CLAUSE_LINEAR:
-         clauses = c_parser_omp_clause_linear (parser, clauses);
+       case PRAGMA_OMP_CLAUSE_LINEAR: 
+         if (((mask >> PRAGMA_CILK_CLAUSE_VECTORLENGTH) & 1) != 0)
+          cilk_simd_fn = true; 
+         clauses = c_parser_omp_clause_linear (parser, clauses, cilk_simd_fn); 
          c_name = "linear";
          break;
        case PRAGMA_OMP_CLAUSE_DEPEND:
@@ -10952,6 +11071,10 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
          clauses = c_parser_omp_clause_safelen (parser, clauses);
          c_name = "safelen";
          break;
+       case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
+         clauses = c_parser_cilk_clause_vectorlength (parser, clauses, true);
+         c_name = "simdlen";
+         break;
        case PRAGMA_OMP_CLAUSE_SIMDLEN:
          clauses = c_parser_omp_clause_simdlen (parser, clauses);
          c_name = "simdlen";
@@ -12727,10 +12850,19 @@ static void
 c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
                           vec<c_token> clauses)
 {
+  if (flag_enable_cilkplus
+      && clauses.exists () && !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
+    {
+      error ("%<#pragma omp declare simd%> cannot be used in the same "
+            "function marked as a Cilk Plus SIMD-enabled function");
+      vec_free (parser->cilk_simd_fn_tokens);
+      return;
+    }
+  
   /* Normally first token is CPP_NAME "simd".  CPP_EOF there indicates
      error has been reported and CPP_PRAGMA that c_finish_omp_declare_simd
      has already processed the tokens.  */
-  if (clauses[0].type == CPP_EOF)
+  if (clauses.exists () && clauses[0].type == CPP_EOF)
     return;
   if (fndecl == NULL_TREE || TREE_CODE (fndecl) != FUNCTION_DECL)
     {
@@ -12739,7 +12871,7 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
       clauses[0].type = CPP_EOF;
       return;
     }
-  if (clauses[0].type != CPP_NAME)
+  if (clauses.exists () && clauses[0].type != CPP_NAME)
     {
       error_at (DECL_SOURCE_LOCATION (fndecl),
                "%<#pragma omp declare simd%> not immediately followed by "
@@ -12753,23 +12885,49 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
 
   unsigned int tokens_avail = parser->tokens_avail;
   gcc_assert (parser->tokens == &parser->tokens_buf[0]);
-  parser->tokens = clauses.address ();
-  parser->tokens_avail = clauses.length ();
-
+  bool is_cilkplus_cilk_simd_fn = false;
+  
+  if (flag_enable_cilkplus && !vec_safe_is_empty (parser->cilk_simd_fn_tokens))
+    {
+      parser->tokens = parser->cilk_simd_fn_tokens->address ();
+      parser->tokens_avail = vec_safe_length (parser->cilk_simd_fn_tokens);
+      is_cilkplus_cilk_simd_fn = true;
+    }
+  else
+    {
+      parser->tokens = clauses.address ();
+      parser->tokens_avail = clauses.length ();
+    }
+  
   /* c_parser_omp_declare_simd pushed 2 extra CPP_EOF tokens at the end.  */
   while (parser->tokens_avail > 3)
     {
       c_token *token = c_parser_peek_token (parser);
-      gcc_assert (token->type == CPP_NAME
-                 && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0);
+      if (!is_cilkplus_cilk_simd_fn) 
+       gcc_assert (token->type == CPP_NAME 
+                   && strcmp (IDENTIFIER_POINTER (token->value), "simd") == 0);
+      else
+       gcc_assert (token->type == CPP_NAME
+                   && is_cilkplus_vector_p (token->value));
       c_parser_consume_token (parser);
       parser->in_pragma = true;
 
-      tree c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
-                                        "#pragma omp declare simd");
+      tree c = NULL_TREE;
+      if (is_cilkplus_cilk_simd_fn) 
+       c = c_parser_omp_all_clauses (parser, CILK_SIMD_FN_CLAUSE_MASK,
+                                     "SIMD-enabled functions attribute");
+      else 
+       c = c_parser_omp_all_clauses (parser, OMP_DECLARE_SIMD_CLAUSE_MASK,
+                                     "#pragma omp declare simd");
       c = c_omp_declare_simd_clauses_to_numbers (parms, c);
       if (c != NULL_TREE)
        c = tree_cons (NULL_TREE, c, NULL_TREE);
+      if (is_cilkplus_cilk_simd_fn) 
+       { 
+         tree k = build_tree_list (get_identifier ("cilk simd function"), c);
+         TREE_CHAIN (k) = DECL_ATTRIBUTES (fndecl);
+         DECL_ATTRIBUTES (fndecl) = k;
+       } 
       c = build_tree_list (get_identifier ("omp declare simd"), c);
       TREE_CHAIN (c) = DECL_ATTRIBUTES (fndecl);
       DECL_ATTRIBUTES (fndecl) = c;
@@ -12777,7 +12935,11 @@ c_finish_omp_declare_simd (c_parser *parser, tree fndecl, tree parms,
 
   parser->tokens = &parser->tokens_buf[0];
   parser->tokens_avail = tokens_avail;
-  clauses[0].type = CPP_PRAGMA;
+  if (clauses.exists ())
+    clauses[0].type = CPP_PRAGMA;
+
+  if (!vec_safe_is_empty (parser->cilk_simd_fn_tokens))
+    vec_free (parser->cilk_simd_fn_tokens);
 }
 
 
@@ -13370,14 +13532,26 @@ c_parser_cilk_verify_simd (c_parser *parser,
 }
 
 /* Cilk Plus:
-   vectorlength ( constant-expression ) */
+   This function is shared by SIMD-enabled functions and #pragma simd.  
+   If IS_SIMD_FN is true then it is parsing a SIMD-enabled function and 
+   CLAUSES is unused.  The main purpose of this function is to parse a
+   vectorlength attribute or clause and check for parse errors.
+   When IS_SIMD_FN is true then the function is merely caching the tokens
+   in PARSER->CILK_SIMD_FN_TOKENS.  If errors are found then the token
+   cache is cleared since there is no reason to continue.
+   Syntax:
+   vectorlength ( constant-expression )  */
 
 static tree
-c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses)
+c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses, 
+                                  bool is_simd_fn)
 {
+  if (is_simd_fn)
+    check_no_duplicate_clause (clauses, OMP_CLAUSE_SIMDLEN, "vectorlength");
+  else
   /* The vectorlength clause behaves exactly like OpenMP's safelen
      clause.  Represent it in OpenMP terms.  */
-  check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength");
+    check_no_duplicate_clause (clauses, OMP_CLAUSE_SAFELEN, "vectorlength");
 
   if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
     return clauses;
@@ -13386,18 +13560,33 @@ c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses)
   tree expr = c_parser_expr_no_commas (parser, NULL).value;
   expr = c_fully_fold (expr, false, NULL);
 
-  if (!TREE_TYPE (expr)
-      || !TREE_CONSTANT (expr)
-      || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
-    error_at (loc, "vectorlength must be an integer constant");
+  /* If expr is an error_mark_node then the above function would have
+     emitted an error.  No reason to do it twice.  */
+  if (expr == error_mark_node)
+    ;
+  else if (!TREE_TYPE (expr)
+          || !TREE_CONSTANT (expr)
+          || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+  
+    error_at (loc, "vectorlength must be an integer constant");  
   else if (exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
     error_at (loc, "vectorlength must be a power of 2");
   else
     {
-      tree u = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
-      OMP_CLAUSE_SAFELEN_EXPR (u) = expr;
-      OMP_CLAUSE_CHAIN (u) = clauses;
-      clauses = u;
+      if (is_simd_fn)
+       {
+         tree u = build_omp_clause (loc, OMP_CLAUSE_SIMDLEN);
+         OMP_CLAUSE_SIMDLEN_EXPR (u) = expr;
+         OMP_CLAUSE_CHAIN (u) = clauses;
+         clauses = u;
+       }
+      else
+       {
+         tree u = build_omp_clause (loc, OMP_CLAUSE_SAFELEN);
+         OMP_CLAUSE_SAFELEN_EXPR (u) = expr;
+         OMP_CLAUSE_CHAIN (u) = clauses;
+         clauses = u;
+       }
     }
 
   c_parser_require (parser, CPP_CLOSE_PAREN, "expected %<)%>");
@@ -13494,10 +13683,10 @@ c_parser_cilk_clause_linear (c_parser *parser, tree clauses)
    not consumed.  Otherwise, the appropriate pragma_simd_clause is
    returned and the token is consumed.  */
 
-static pragma_cilk_clause
+static pragma_omp_clause
 c_parser_cilk_clause_name (c_parser *parser)
 {
-  pragma_cilk_clause result;
+  pragma_omp_clause result;
   c_token *token = c_parser_peek_token (parser);
 
   if (!token->value || token->type != CPP_NAME)
@@ -13534,14 +13723,14 @@ c_parser_cilk_all_clauses (c_parser *parser)
 
   while (c_parser_next_token_is_not (parser, CPP_PRAGMA_EOL))
     {
-      pragma_cilk_clause c_kind;
+      pragma_omp_clause c_kind;
 
       c_kind = c_parser_cilk_clause_name (parser);
 
       switch (c_kind)
        {
        case PRAGMA_CILK_CLAUSE_VECTORLENGTH:
-         clauses = c_parser_cilk_clause_vectorlength (parser, clauses);
+         clauses = c_parser_cilk_clause_vectorlength (parser, clauses, false);
          break;
        case PRAGMA_CILK_CLAUSE_LINEAR:
          clauses = c_parser_cilk_clause_linear (parser, clauses);
index ecf5e0b1bc001d30fbe27f2ae945dd4884f72a58..0be671da3902918e645a898692e6b691c95ca385 100644 (file)
@@ -43860,7 +43860,7 @@ ix86_simd_clone_compute_vecsize_and_simdlen (struct cgraph_node *node,
          || (clonei->simdlen & (clonei->simdlen - 1)) != 0))
     {
       warning_at (DECL_SOURCE_LOCATION (node->decl), 0,
-                 "unsupported simdlen %d\n", clonei->simdlen);
+                 "unsupported simdlen %d", clonei->simdlen);
       return 0;
     }
 
index 9f8ad39dfe1328063c9a48cdb6337bc78d626eff..2a2cbf0f0610715d2afdadb40c7bbf29fa753ab8 100644 (file)
@@ -31478,10 +31478,10 @@ cp_parser_cilk_simd_linear (cp_parser *parser, tree clauses)
    token is not consumed.  Otherwise, the appropriate enum from the
    pragma_simd_clause is returned and the token is consumed.  */
 
-static pragma_cilk_clause
+static pragma_omp_clause
 cp_parser_cilk_simd_clause_name (cp_parser *parser)
 {
-  pragma_cilk_clause clause_type;
+  pragma_omp_clause clause_type;
   cp_token *token = cp_lexer_peek_token (parser->lexer);
 
   if (token->keyword == RID_PRIVATE)
@@ -31515,7 +31515,7 @@ cp_parser_cilk_simd_all_clauses (cp_parser *parser, cp_token *pragma_token)
   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL)
         && clauses != error_mark_node)
     {
-      pragma_cilk_clause c_kind;
+      pragma_omp_clause c_kind;
       c_kind = cp_parser_cilk_simd_clause_name (parser);
       if (c_kind == PRAGMA_CILK_CLAUSE_VECTORLENGTH)
        clauses = cp_parser_cilk_simd_vectorlength (parser, clauses);
index 2398a96c0ea4478f4c741da7288087e478d4c2ec..aacee3872b2bb5e68659b4f9fbe83bb2f6c190d8 100644 (file)
@@ -10688,7 +10688,7 @@ simd_clone_clauses_extract (struct cgraph_node *node, tree clauses,
      declare simd".  */
   bool cilk_clone
     = (flag_enable_cilkplus
-       && lookup_attribute ("cilk plus elemental",
+       && lookup_attribute ("cilk simd function",
                            DECL_ATTRIBUTES (node->decl)));
 
   /* Allocate one more than needed just in case this is an in-branch
index 20a1bc59c4ff81898d4ad75a86cffdef580e1c04..f4e055fdc89caf45e2382f19aa317b391623ed9e 100644 (file)
@@ -1,3 +1,13 @@
+2013-12-18  Balaji V. Iyer  <balaji.v.iyer@intel.com>
+
+       * c-c++-common/cilk-plus/SE/ef_test.c: New test.
+       * c-c++-common/cilk-plus/SE/ef_test2.c: Likewise.
+       * c-c++-common/cilk-plus/SE/vlength_errors.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error2.c: Likewise.
+       * c-c++-common/cilk-plus/SE/ef_error3.c: Likewise.
+       * gcc.dg/cilk-plus/cilk-plus.exp: Added calls for the above tests.
+       
 2013-12-18  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/59539
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error.c
new file mode 100644 (file)
index 0000000..6a4b4a4
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -fopenmp" } */
+
+#pragma omp declare simd linear(y:1) simdlen(4) 
+__attribute__((vector (linear (y:1), vectorlength(4))))
+int func (int x, int y) { /* { dg-error "cannot be used in the same function marked as a Cilk Plus SIMD-enabled" } */ 
+  return (x+y);
+}
+__attribute__((vector (linear (y:1), private (x)))) /* { dg-error "is not valid for" } */
+int func2 (int x, int y) {
+  return (x+y);
+}
+
+__attribute__((vector (linear (y:1), simdlen (4)))) /* { dg-error "is not valid for" } */
+int func2_1 (int x, int y) {
+  return (x+y);
+}
+
+__attribute__((vector (linear (y:1), inbranch))) /* { dg-error "is not valid for" } */
+int func2_3 (int x, int y) {
+  return (x+y);
+}
+
+__attribute__((vector (notinbranch, vectorlength (4)))) /* { dg-error "is not valid for" } */
+int func2_2 (int x, int y) {
+  return (x+y);
+}
+
+int main (void)
+{
+  return (func (5,6));
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error2.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error2.c
new file mode 100644 (file)
index 0000000..518d640
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus -Wall" } */
+
+__attribute__((vector (vectorlength(32)))) 
+//#pragma omp simd simdlen (32)
+int func2 (int x, int y)  /* { dg-warning "unsupported simdlen" } */
+{
+  return (x+y);
+}
+
+int main (void)
+{
+  return (func2 (5,6));
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_error3.c
new file mode 100644 (file)
index 0000000..ab55fae
--- /dev/null
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-fcilkplus -Wall" } */
+
+__attribute__((vector (linear (x:y))))
+int func2 (int x, int y) 
+{ /* { dg-message "using parameters for" } */
+  return (x+y);
+}
+
+int main (void)
+{
+  return (func2 (5,6));
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test.c
new file mode 100644 (file)
index 0000000..e606aca
--- /dev/null
@@ -0,0 +1,78 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -Wunknown-pragmas" } */
+
+/* Tests the clauses in several combinations put in different locations.  */
+/* This is mostly a parser test.  */
+#define Q 4
+
+int z = Q;
+
+ __attribute__ ((vector (uniform(x), linear (y:1), vectorlength (4) )))
+int func (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+ __attribute__ ((__vector__ (uniform(x), vectorlength (2), linear (y:1) )))
+int func2 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(y), linear (x), vectorlength (4) )))
+int func3 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), mask)))
+int func4 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), nomask)))
+int func5 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), mask, linear (y:1)))) 
+int func6 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform (x), mask, linear (y:1)), vector))
+int func7 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform (x), mask, linear (y:1)), vector (uniform (y), mask)))
+int func8 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector, vector (uniform (y), mask)))
+int func9 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+int main (int argc, char *argv[])
+{
+  int ii = 0, q = 5;
+  for (ii = 0; ii < 10; ii++)
+    q += func (argc, ii);
+  return q;
+}
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test2.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/ef_test2.c
new file mode 100644 (file)
index 0000000..7ec0578
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus" } */
+void func (int x, int y) __attribute__((vector(linear(x:1), uniform (y)),
+                                       vector));
+
+int q;
+int main (void)
+{
+  int ii = 0;
+  q = 5; 
+  for (ii = 0; ii < 100; ii++) 
+    func (ii, q);
+
+  return 0;
+}
+
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c b/gcc/testsuite/c-c++-common/cilk-plus/SE/vlength_errors.c
new file mode 100644 (file)
index 0000000..38d610a
--- /dev/null
@@ -0,0 +1,56 @@
+/* { dg-do compile } */
+/* { dg-options "-fcilkplus -Wunknown-pragmas" } */
+
+#define Q 4
+
+int z = Q;
+
+__attribute__ ((vector (uniform(x), vectorlength (), linear (y:1) ))) /* { dg-error "expected expression" } */
+int func2 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (4.5) ))) /* { dg-error "vectorlength must be an integer" } */
+int func3 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (z) ))) /* { dg-error "vectorlength must be an integer" } */
+int func4 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (Q) ))) /* This is OK!  */
+int func5 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), vectorlength (z), linear (y:1)))) /* { dg-error "vectorlength must be an integer" } */
+int func6 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+__attribute__ ((vector (uniform(x), linear (y:1), vectorlength (sizeof (int)) ))) /* This is OK too!  */
+int func7 (int x, int y)
+{
+  int zq = 5;
+  return x + (y*zq);
+}
+
+int main (void)
+{
+  int ii = 0, q = 5;
+  for (ii = 0; ii < 10; ii++)
+    q += func2 (z, ii);
+  return q;
+}
index 39abbba3fbc52c6ca581a921f453c7f6d5628cc2..51c715df2e162eb43cec0d5bc81a82b056b47d07 100644 (file)
@@ -60,6 +60,10 @@ if { [check_effective_target_lto] } {
     dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/CK/*.c]] " -O3 -flto -g -fcilkplus" " "
 }
 
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] " -g" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] " -O3 -std=c99" " "
+dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/cilk-plus/SE/*.c]] " -O3 -g" " "
+
 dg-finish
 
 unset TEST_EXTRA_LIBS