summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2013-04-19 09:34:06 -0500
committerAldy Hernandez <aldyh@redhat.com>2013-04-19 09:34:06 -0500
commit671052dfdbf19efddf1ba7c1378048b80eba7f72 (patch)
treeb25a02e144b5530d75bebf8477adf67284410a01
parentcd7cb45fc78ae9a62968372eae37da08444da8ca (diff)
downloadgcc-aldyh/cilkplus-simd-rewrite.tar.gz
New tests for vectorlength and linear clauses, and corresponding codealdyh/cilkplus-simd-rewrite
to match.
-rw-r--r--gcc/c/c-parser.c99
-rw-r--r--gcc/c/c-typeck.c5
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses1.c84
-rw-r--r--gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses2.c19
4 files changed, 158 insertions, 49 deletions
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 855e3979c99..33f89d5b0ef 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -11043,20 +11043,20 @@ c_parser_simd_clause_vectorlength (c_parser *parser, tree clauses)
while (true)
{
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");
+ else
{
- error_at (loc, "vectorlength must be an integral constant");
- return clauses;
+ tree u = build_omp_clause (loc, OMP_SIMD_CLAUSE_VECTORLENGTH);
+ OMP_CLAUSE_VECLENGTH_EXPR (u) = expr;
+ OMP_CLAUSE_CHAIN (u) = clauses;
+ clauses = u;
}
- tree u = build_omp_clause (loc, OMP_SIMD_CLAUSE_VECTORLENGTH);
- OMP_CLAUSE_VECLENGTH_EXPR (u) = expr;
- OMP_CLAUSE_CHAIN (u) = clauses;
- clauses = u;
-
if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
{
c_parser_consume_token (parser);
@@ -11090,66 +11090,62 @@ c_parser_simd_clause_linear (c_parser *parser, tree clauses)
return clauses;
location_t loc = c_parser_peek_token (parser)->location;
- while (true)
- {
- if (c_parser_next_token_is_not (parser, CPP_NAME))
- {
- c_parser_error (parser, "expected variable");
- return clauses;
- }
+ if (c_parser_next_token_is_not (parser, CPP_NAME)
+ || c_parser_peek_token (parser)->id_kind != C_ID_ID)
+ c_parser_error (parser, "expected identifier");
+
+ while (c_parser_next_token_is (parser, CPP_NAME)
+ && c_parser_peek_token (parser)->id_kind == C_ID_ID)
+ {
tree var = lookup_name (c_parser_peek_token (parser)->value);
if (var == NULL)
- undeclared_variable (c_parser_peek_token (parser)->location,
- c_parser_peek_token (parser)->value);
+ {
+ undeclared_variable (c_parser_peek_token (parser)->location,
+ c_parser_peek_token (parser)->value);
+ c_parser_consume_token (parser);
+ }
else if (var == error_mark_node)
- ;
+ c_parser_consume_token (parser);
else
{
- tree step;
- tree u = build_omp_clause (loc, OMP_SIMD_CLAUSE_LINEAR);
- OMP_CLAUSE_LINEAR_VAR (u) = var;
+ tree step = integer_one_node;
/* Parse the linear step if present. */
- if (c_parser_next_token_is (parser, CPP_COLON))
+ if (c_parser_peek_2nd_token (parser)->type == CPP_COLON)
{
c_parser_consume_token (parser);
- // FIXME: This is wrong. The spec says that we should
- // expect a conditional-expression here and that it
- // shall either satisfy the requirements of an integer
- // constant expression, or be a reference to a variable
- // with integer type. Use whatever we did for the
- // vectorlength clause.
- if (c_parser_next_token_is_not (parser, CPP_NUMBER))
- {
- c_parser_error (parser, "expected step-size");
- return clauses;
- }
+ c_parser_consume_token (parser);
+
+ tree expr = c_parser_expr_no_commas (parser, NULL).value;
+ expr = c_fully_fold (expr, false, NULL);
- step = c_parser_peek_token (parser)->value;
+ if (!TREE_TYPE (expr)
+ || !TREE_CONSTANT (expr)
+ || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
+ c_parser_error (parser, "step size must be an integer constant");
+ else
+ step = expr;
}
- else if (c_parser_next_token_is (parser, CPP_COMMA)
- || c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- step = integer_one_node;
else
- {
- c_parser_error (parser,
- "expected ',' or ')' after variable name");
- return clauses;
- }
+ c_parser_consume_token (parser);
+
+ tree u = build_omp_clause (loc, OMP_SIMD_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_VAR (u) = var;
OMP_CLAUSE_LINEAR_STEP (u) = step;
+ OMP_CLAUSE_CHAIN (u) = clauses;
clauses = u;
+ }
- if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
- {
- c_parser_consume_token (parser);
- return clauses;
- }
+ if (c_parser_next_token_is_not (parser, CPP_COMMA))
+ break;
- c_parser_consume_token (parser);
- }
+ c_parser_consume_token (parser);
}
+
+ c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>");
+
return clauses;
}
@@ -11162,7 +11158,12 @@ static pragma_simd_clause
c_parser_simd_clause_name (c_parser *parser)
{
pragma_simd_clause result;
- const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ c_token *token = c_parser_peek_token (parser);
+
+ if (!token->value || token->type != CPP_NAME)
+ return PRAGMA_SIMD_CLAUSE_NONE;
+
+ const char *p = IDENTIFIER_POINTER (token->value);
if (!strcmp (p, "noassert"))
result = PRAGMA_SIMD_CLAUSE_NOASSERT;
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index b3881ce716c..ae607a5f252 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -10987,6 +10987,8 @@ c_build_va_arg (location_t loc, tree expr, tree type)
return build_va_arg (loc, expr, type);
}
+// FIXME: Move all these Cilk Plus functions to cilk.c or something.
+
/* Helper function for c_check_cilk_loop.
Validate the increment in a _Cilk_for construct or a <#pragma simd>
@@ -11259,6 +11261,9 @@ c_finish_cilk_loop (location_t loc, tree decl, tree cond, tree incr,
tree
c_finish_simd_clauses (tree clauses)
{
+ // FIXME: "...no variable shall be the subject of more than one
+ // linear clause". Verify and check for this.
+
return clauses;
}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses1.c b/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses1.c
new file mode 100644
index 00000000000..ba822cda4f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses1.c
@@ -0,0 +1,84 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c99 -fcilkplus -fopenmp" } */
+
+volatile int *a, *b;
+
+void foo()
+{
+ int i, j, k;
+
+#pragma simd assert aoeu /* { dg-error "expected '#pragma simd' clause" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd noassert aoeu /* { dg-error "expected '#pragma simd' clause" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd assert noassert /* { dg-error "too many 'assert' clauses" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength /* { dg-error "expected '\\('" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength /* { dg-error "expected '\\('" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(sizeof (a) == sizeof (float) ? 4 : 8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(4,8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd vectorlength(i) /* { dg-error "vectorlength must be an integer" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(35) /* { dg-error "expected identifier" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(blah) /* { dg-error "'blah' undeclared" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(blah2, 36)
+ /* { dg-error "'blah2' undeclared" "undeclared" { target *-*-* } 50 } */
+ /* { dg-error "expected '\\)'" "expected" { target *-*-* } 50 } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(j, 36, k) /* { dg-error "expected '\\)'" } */
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i, j)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i : 4)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(i : 2, j : 4, k)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+#pragma simd linear(j : sizeof (a) == sizeof (float) ? 4 : 8)
+ for (int i=0; i < 1000; ++i)
+ a[i] = b[j];
+
+ // And now everyone in unison!
+#pragma simd assert linear(i : 4, j) vectorlength(4)
+ for (i=0; i < 1000; ++i)
+ a[i] = b[j];
+}
diff --git a/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses2.c b/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses2.c
new file mode 100644
index 00000000000..083f99891f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cilk-plus/pragma_simd_tests/compile/clauses2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -std=c99 -fcilkplus -fopenmp -fdump-tree-gimple" } */
+
+volatile int *a, *b;
+
+void foo()
+{
+ int i, j;
+
+#pragma simd assert linear(i : 4, j) vectorlength(4)
+ for (i=0; i < 1000; ++i)
+ a[i] = b[j];
+}
+
+/* { dg-final { scan-tree-dump-times "simd_linear\\(j : 1\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "simd_linear\\(i : 4\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "simd_vectorlength\\(4\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "simd_assert" 1 "gimple" } } */
+/* { dg-final { cleanup-tree-dump "gimple" } } */