2016-09-28 Nathan Sidwell c/ * c-parser.c (c_parser_omp_for_tiling): Accept tiling constructs. cp/ * parser.c (cp_parser_omp_for_loop): Deal with tile clause. Don't emit a parse error about missing for after already emitting one. Use more conventional for idiom for unbounded loop. * semantics.c (finish_omp_for): Deal with tile clause. testsuite/ * c-c++-common/goacc/tile-2.c: New. * c-c++-common/goacc/tile.c: Fix. Index: c/c-parser.c =================================================================== --- c/c-parser.c (revision 240524) +++ c/c-parser.c (working copy) @@ -14920,11 +14920,17 @@ c_parser_omp_for_loop (location_t loc, c bool fail = false, open_brace_parsed = false; int i, collapse = 1, ordered = 0, count, nbraces = 0; location_t for_loc; + bool tiling = false; vec *for_block = make_tree_vector (); for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); + else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE) + { + tiling = true; + collapse = list_length (OMP_CLAUSE_TILE_LIST (cl)); + } else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED && OMP_CLAUSE_ORDERED_EXPR (cl)) { @@ -14954,7 +14960,7 @@ c_parser_omp_for_loop (location_t loc, c pc = &OMP_CLAUSE_CHAIN (*pc); } - gcc_assert (collapse >= 1 && ordered >= 0); + gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); count = ordered ? ordered : collapse; declv = make_tree_vec (count); Index: cp/parser.c =================================================================== --- cp/parser.c (revision 240524) +++ cp/parser.c (working copy) @@ -33660,10 +33660,16 @@ cp_parser_omp_for_loop (cp_parser *parse int i, collapse = 1, ordered = 0, count, nbraces = 0; vec *for_block = make_tree_vector (); auto_vec orig_inits; + bool tiling = false; for (cl = clauses; cl; cl = OMP_CLAUSE_CHAIN (cl)) if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_COLLAPSE) collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (cl)); + else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_TILE) + { + tiling = true; + collapse = list_length (OMP_CLAUSE_TILE_LIST (cl)); + } else if (OMP_CLAUSE_CODE (cl) == OMP_CLAUSE_ORDERED && OMP_CLAUSE_ORDERED_EXPR (cl)) { @@ -33693,7 +33699,7 @@ cp_parser_omp_for_loop (cp_parser *parse pc = &OMP_CLAUSE_CHAIN (*pc); } - gcc_assert (collapse >= 1 && ordered >= 0); + gcc_assert (tiling || (collapse >= 1 && ordered >= 0)); count = ordered ? ordered : collapse; declv = make_tree_vec (count); @@ -33712,13 +33718,15 @@ cp_parser_omp_for_loop (cp_parser *parse if (code != CILK_FOR && !cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) { - cp_parser_error (parser, "for statement expected"); + if (!collapse_err) + cp_parser_error (parser, "for statement expected"); return NULL; } if (code == CILK_FOR && !cp_lexer_next_token_is_keyword (parser->lexer, RID_CILK_FOR)) { - cp_parser_error (parser, "_Cilk_for statement expected"); + if (!collapse_err) + cp_parser_error (parser, "_Cilk_for statement expected"); return NULL; } loc = cp_lexer_consume_token (parser->lexer)->location; @@ -33878,7 +33886,7 @@ cp_parser_omp_for_loop (cp_parser *parse nested. Hopefully the final version clarifies this. For now handle (multiple) {'s and empty statements. */ cp_parser_parse_tentatively (parser); - do + for (;;) { if (cp_lexer_next_token_is_keyword (parser->lexer, RID_FOR)) break; @@ -33893,14 +33901,13 @@ cp_parser_omp_for_loop (cp_parser *parse else { loc = cp_lexer_peek_token (parser->lexer)->location; - error_at (loc, "not enough collapsed for loops"); + error_at (loc, "not enough for loops to collapse"); collapse_err = true; cp_parser_abort_tentative_parse (parser); declv = NULL_TREE; break; } } - while (1); if (declv) { Index: cp/semantics.c =================================================================== --- cp/semantics.c (revision 240524) +++ cp/semantics.c (working copy) @@ -7986,11 +7986,19 @@ finish_omp_for (location_t locus, enum t gcc_assert (TREE_VEC_LENGTH (declv) == TREE_VEC_LENGTH (incrv)); if (TREE_VEC_LENGTH (declv) > 1) { - tree c = find_omp_clause (clauses, OMP_CLAUSE_COLLAPSE); + tree c; + + c = find_omp_clause (clauses, OMP_CLAUSE_TILE); if (c) - collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c)); - if (collapse != TREE_VEC_LENGTH (declv)) - ordered = TREE_VEC_LENGTH (declv); + collapse = list_length (OMP_CLAUSE_TILE_LIST (c)); + else + { + c = find_omp_clause (clauses, OMP_CLAUSE_COLLAPSE); + if (c) + collapse = tree_to_shwi (OMP_CLAUSE_COLLAPSE_EXPR (c)); + if (collapse != TREE_VEC_LENGTH (declv)) + ordered = TREE_VEC_LENGTH (declv); + } } for (i = 0; i < TREE_VEC_LENGTH (declv); i++) { Index: testsuite/c-c++-common/goacc/tile-2.c =================================================================== --- testsuite/c-c++-common/goacc/tile-2.c (nonexistent) +++ testsuite/c-c++-common/goacc/tile-2.c (working copy) @@ -0,0 +1,21 @@ +int main () +{ +#pragma acc parallel + { +#pragma acc loop tile (*,*) + for (int ix = 0; ix < 30; ix++) + ; /* { dg-error "not enough" } */ + +#pragma acc loop tile (*,*) + for (int ix = 0; ix < 30; ix++) + for (int jx = 0; jx < ix; jx++) /* { dg-error "condition expression" } */ + ; + +#pragma acc loop tile (*) + for (int ix = 0; ix < 30; ix++) + for (int jx = 0; jx < ix; jx++) /* OK */ + ; + + } + return 0; +} Index: testsuite/c-c++-common/goacc/tile.c =================================================================== --- testsuite/c-c++-common/goacc/tile.c (revision 240524) +++ testsuite/c-c++-common/goacc/tile.c (working copy) @@ -3,7 +3,7 @@ int main () { - int i, *a, b; + int i, j, k, *a, b; #pragma acc parallel loop tile (10) for (i = 0; i < 100; i++) @@ -15,11 +15,14 @@ main () #pragma acc parallel loop tile (10, *) for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; #pragma acc parallel loop tile (10, *, i) // { dg-error "" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + for (k = 0; k < 100; k++) + ; #pragma acc parallel loop tile // { dg-error "expected '\\\('" } for (i = 0; i < 100; i++) @@ -47,27 +50,34 @@ main () #pragma acc parallel loop tile (10,-3) // { dg-error "'tile' argument needs" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; #pragma acc parallel loop tile (-100,10,5) // { dg-error "'tile' argument needs" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + for (k = 0; k < 100; k++) + ; #pragma acc parallel loop tile (1,true) for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; #pragma acc parallel loop tile (*a, 1) // { dg-error "" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; #pragma acc parallel loop tile (1, b) // { dg-error "" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; #pragma acc parallel loop tile (b, 1) // { dg-error "" } for (i = 0; i < 100; i++) - ; + for (j = 0; j < 100; j++) + ; return 0; } @@ -75,7 +85,7 @@ main () void par (void) { - int i, j; + int i, j, k; #pragma acc parallel { @@ -107,12 +117,12 @@ void par (void) for (i = 1; i < 3; i++) { for (j = 4; j < 6; j++) - { } + for (k = 0; k< 100; k++); } #pragma acc loop tile(2, 2) for (i = 1; i < 5; i+=2) { - for (j = i + 1; j < 7; j+=i) + for (j = i + 1; j < 7; j+=i) // { dg-error "initializer expression" } { } } #pragma acc loop vector tile(*) @@ -171,7 +181,7 @@ void p3 (void) ; #pragma acc parallel loop tile(2, 2) for (i = 1; i < 5; i+=2) - for (j = i + 1; j < 7; j++) + for (j = i + 1; j < 7; j++) // { dg-error "initializer expression" } { } #pragma acc parallel loop vector tile(*) for (i = 0; i < 10; i++) @@ -226,7 +236,7 @@ kern (void) #pragma acc loop tile(*, 1) for (i = 0; i < 10; i++) { - for (j = 0; j < 10; i++) + for (j = 0; j < 10; i++) /* { dg-error "increment expression" } */ { } } #pragma acc loop tile(-2) // { dg-error "'tile' argument needs" } @@ -237,11 +247,12 @@ kern (void) { } #pragma acc loop tile(2, 2, 1) for (i = 2; i < 4; i++) - for (i = 4; i < 6; i++) + for (j = 4; j < 6; j++) + for (int k = 4; k < 6; k++) { } #pragma acc loop tile(2, 2) for (i = 1; i < 5; i+=2) - for (j = i+1; j < 7; i++) + for (j = i+1; j < 7; j++) /* { dg-error "initializer expression" } */ { } #pragma acc loop vector tile(*) for (i = 0; i < 10; i++) @@ -301,7 +312,7 @@ void k3 (void) #pragma acc kernels loop tile(2, 2) for (i = 1; i < 5; i++) { - for (j = i + 1; j < 7; j += i) + for (j = i + 1; j < 7; j += i) /* { dg-error "initializer expression" } */ { } } #pragma acc kernels loop vector tile(*)