diff options
author | Tobias Burnus <burnus@net-b.de> | 2013-10-30 19:53:42 +0100 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2013-10-30 19:53:42 +0100 |
commit | c5028d807fd315cfeb2f1d44e5ffb1c6ca470aff (patch) | |
tree | 7d8909733bc9f939a4e8f741e8c10d5e7814c0e5 | |
parent | 1079f7a198ba7e1114d8dce44f72a00cf9abb8eb (diff) | |
download | gcc-c5028d807fd315cfeb2f1d44e5ffb1c6ca470aff.zip gcc-c5028d807fd315cfeb2f1d44e5ffb1c6ca470aff.tar.gz gcc-c5028d807fd315cfeb2f1d44e5ffb1c6ca470aff.tar.bz2 |
re PR other/33426 (Support of #pragma ivdep)
2013-10-30 Tobias Burnus <burnus@net-b.de>
gcc/cp/
PR other/33426
* cp-tree.h (RANGE_FOR_IVDEP): Define.
(cp_convert_range_for, finish_while_stmt_cond, finish_do_stmt,
finish_for_cond): Take 'bool ivdep' parameter.
* cp-array-notation.c (create_an_loop): Update call.
* init.c (build_vec_init): Ditto.
* pt.c (tsubst_expr): Ditto.
* parser.c (cp_parser_iteration_statement, cp_parser_for,
cp_parser_range_for, cp_convert_range_for): Update calls.
(cp_parser_pragma): Accept GCC ivdep for 'while' and 'do'.
* semantics.c (finish_while_stmt_cond, finish_do_stmt,
finish_for_cond): Optionally build ivdep annotation.
gcc/testsuite/
PR other/33426
* g++.dg/vect/pr33426-ivdep-2.cc: New.
* g++.dg/vect/pr33426-ivdep-3.cc: New.
* g++.dg/vect/pr33426-ivdep-4.cc: New.
gcc/
PR other/33426
* gcc/tree-cfg.c (replace_loop_annotate): Replace warning by
warning_at.
From-SVN: r204223
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/cp/cp-array-notation.c | 2 | ||||
-rw-r--r-- | gcc/cp/cp-tree.h | 10 | ||||
-rw-r--r-- | gcc/cp/init.c | 2 | ||||
-rw-r--r-- | gcc/cp/parser.c | 36 | ||||
-rw-r--r-- | gcc/cp/pt.c | 8 | ||||
-rw-r--r-- | gcc/cp/semantics.c | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/pr33426-ivdep-2.cc | 39 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/pr33426-ivdep-3.cc | 25 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/vect/pr33426-ivdep-4.cc | 30 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 3 |
13 files changed, 172 insertions, 32 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9907608..ef40a43 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-10-30 Tobias Burnus <burnus@net-b.de> + + PR other/33426 + * gcc/tree-cfg.c (replace_loop_annotate): Replace warning by + warning_at. + 2013-10-30 Jason Merrill <jason@redhat.com> * configure.ac (loose_warn): Add -Wno-format if diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index da1d7f9..97e95f4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,18 @@ +2013-10-30 Tobias Burnus <burnus@net-b.de> + + PR other/33426 + * cp-tree.h (RANGE_FOR_IVDEP): Define. + (cp_convert_range_for, finish_while_stmt_cond, finish_do_stmt, + finish_for_cond): Take 'bool ivdep' parameter. + * cp-array-notation.c (create_an_loop): Update call. + * init.c (build_vec_init): Ditto. + * pt.c (tsubst_expr): Ditto. + * parser.c (cp_parser_iteration_statement, cp_parser_for, + cp_parser_range_for, cp_convert_range_for): Update calls. + (cp_parser_pragma): Accept GCC ivdep for 'while' and 'do'. + * semantics.c (finish_while_stmt_cond, finish_do_stmt, + finish_for_cond): Optionally build ivdep annotation. + 2013-10-30 Jason Merrill <jason@redhat.com> * decl.c (cp_finish_decl): Never throw for VLA bound == 0. diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c index c700f58..e1fb0ee 100644 --- a/gcc/cp/cp-array-notation.c +++ b/gcc/cp/cp-array-notation.c @@ -71,7 +71,7 @@ create_an_loop (tree init, tree cond, tree incr, tree body) finish_expr_stmt (init); for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE); finish_for_init_stmt (for_stmt); - finish_for_cond (cond, for_stmt); + finish_for_cond (cond, for_stmt, false); finish_for_expr (incr, for_stmt); finish_expr_stmt (body); finish_for_stmt (for_stmt); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 507b389..fd79adb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -116,6 +116,7 @@ c-common.h, not after. 6: IDENTIFIER_REPO_CHOSEN (in IDENTIFIER_NODE) DECL_CONSTRUCTION_VTABLE_P (in VAR_DECL) TYPE_MARKED_P (in _TYPE) + RANGE_FOR_IVDEP (in RANGE_FOR_STMT) Usage of TYPE_LANG_FLAG_?: 0: TYPE_DEPENDENT_P @@ -4088,6 +4089,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) #define RANGE_FOR_EXPR(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 1) #define RANGE_FOR_BODY(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 2) #define RANGE_FOR_SCOPE(NODE) TREE_OPERAND (RANGE_FOR_STMT_CHECK (NODE), 3) +#define RANGE_FOR_IVDEP(NODE) TREE_LANG_FLAG_6 (RANGE_FOR_STMT_CHECK (NODE)) #define SWITCH_STMT_COND(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 0) #define SWITCH_STMT_BODY(NODE) TREE_OPERAND (SWITCH_STMT_CHECK (NODE), 1) @@ -4321,7 +4323,7 @@ extern int comparing_specializations; sizeof can be nested. */ extern int cp_unevaluated_operand; -extern tree cp_convert_range_for (tree, tree, tree); +extern tree cp_convert_range_for (tree, tree, tree, bool); extern bool parsing_nsdmi (void); /* in pt.c */ @@ -5671,16 +5673,16 @@ extern void begin_else_clause (tree); extern void finish_else_clause (tree); extern void finish_if_stmt (tree); extern tree begin_while_stmt (void); -extern void finish_while_stmt_cond (tree, tree); +extern void finish_while_stmt_cond (tree, tree, bool); extern void finish_while_stmt (tree); extern tree begin_do_stmt (void); extern void finish_do_body (tree); -extern void finish_do_stmt (tree, tree); +extern void finish_do_stmt (tree, tree, bool); extern tree finish_return_stmt (tree); extern tree begin_for_scope (tree *); extern tree begin_for_stmt (tree, tree); extern void finish_for_init_stmt (tree); -extern void finish_for_cond (tree, tree); +extern void finish_for_cond (tree, tree, bool); extern void finish_for_expr (tree, tree); extern void finish_for_stmt (tree); extern tree begin_range_for_stmt (tree, tree); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 78ea986..bfd9152 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -3667,7 +3667,7 @@ build_vec_init (tree base, tree maxindex, tree init, finish_for_init_stmt (for_stmt); finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator, build_int_cst (TREE_TYPE (iterator), -1)), - for_stmt); + for_stmt, false); elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0, complain); if (elt_init == error_mark_node) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8deffc3..9e28ced 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -1978,7 +1978,7 @@ static tree cp_parser_for static tree cp_parser_c_for (cp_parser *, tree, tree, bool); static tree cp_parser_range_for - (cp_parser *, tree, tree, tree); + (cp_parser *, tree, tree, tree, bool); static void do_range_for_auto_deduction (tree, tree); static tree cp_parser_perform_range_for_lookup @@ -9904,7 +9904,7 @@ cp_parser_for (cp_parser *parser, bool ivdep) is_range_for = cp_parser_for_init_statement (parser, &decl); if (is_range_for) - return cp_parser_range_for (parser, scope, init, decl); + return cp_parser_range_for (parser, scope, init, decl, ivdep); else return cp_parser_c_for (parser, scope, init, ivdep); } @@ -9924,20 +9924,14 @@ cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep) /* If there's a condition, process it. */ if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON)) - { - condition = cp_parser_condition (parser); - if (ivdep) - condition = build2 (ANNOTATE_EXPR, TREE_TYPE (condition), condition, - build_int_cst (integer_type_node, - annot_expr_ivdep_kind)); - } + condition = cp_parser_condition (parser); else if (ivdep) { cp_parser_error (parser, "missing loop condition in loop with " "%<GCC ivdep%> pragma"); condition = error_mark_node; } - finish_for_cond (condition, stmt); + finish_for_cond (condition, stmt, ivdep); /* Look for the `;'. */ cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON); @@ -9960,7 +9954,8 @@ cp_parser_c_for (cp_parser *parser, tree scope, tree init, bool ivdep) regular FOR_STMT. */ static tree -cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl) +cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl, + bool ivdep) { tree stmt, range_expr; @@ -9979,6 +9974,8 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl) if (check_for_bare_parameter_packs (range_expr)) range_expr = error_mark_node; stmt = begin_range_for_stmt (scope, init); + if (ivdep) + RANGE_FOR_IVDEP (stmt) = 1; finish_range_for_decl (stmt, range_decl, range_expr); if (!type_dependent_expression_p (range_expr) /* do_auto_deduction doesn't mess with template init-lists. */ @@ -9988,7 +9985,7 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl) else { stmt = begin_for_stmt (scope, init); - stmt = cp_convert_range_for (stmt, range_decl, range_expr); + stmt = cp_convert_range_for (stmt, range_decl, range_expr, ivdep); } return stmt; } @@ -10079,7 +10076,8 @@ do_range_for_auto_deduction (tree decl, tree range_expr) namespace. */ tree -cp_convert_range_for (tree statement, tree range_decl, tree range_expr) +cp_convert_range_for (tree statement, tree range_decl, tree range_expr, + bool ivdep) { tree begin, end; tree iter_type, begin_expr, end_expr; @@ -10136,7 +10134,7 @@ cp_convert_range_for (tree statement, tree range_decl, tree range_expr) begin, ERROR_MARK, end, ERROR_MARK, NULL, tf_warning_or_error); - finish_for_cond (condition, statement); + finish_for_cond (condition, statement, ivdep); /* The new increment expression. */ expression = finish_unary_op_expr (input_location, @@ -10329,7 +10327,7 @@ cp_parser_iteration_statement (cp_parser* parser, bool ivdep) cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN); /* Parse the condition. */ condition = cp_parser_condition (parser); - finish_while_stmt_cond (condition, statement); + finish_while_stmt_cond (condition, statement, ivdep); /* Look for the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Parse the dependent statement. */ @@ -10359,7 +10357,7 @@ cp_parser_iteration_statement (cp_parser* parser, bool ivdep) /* Parse the expression. */ expression = cp_parser_expression (parser, /*cast_p=*/false, NULL); /* We're done with the do-statement. */ - finish_do_stmt (expression, statement); + finish_do_stmt (expression, statement, ivdep); /* Look for the `)'. */ cp_parser_require (parser, CPP_CLOSE_PAREN, RT_CLOSE_PAREN); /* Look for the `;'. */ @@ -30926,9 +30924,11 @@ cp_parser_pragma (cp_parser *parser, enum pragma_context context) cp_parser_skip_to_pragma_eol (parser, pragma_tok); cp_token *tok; tok = cp_lexer_peek_token (the_parser->lexer); - if (tok->type != CPP_KEYWORD || tok->keyword != RID_FOR) + if (tok->type != CPP_KEYWORD + || (tok->keyword != RID_FOR && tok->keyword != RID_WHILE + && tok->keyword != RID_DO)) { - cp_parser_error (parser, "for statement expected"); + cp_parser_error (parser, "for, while or do statement expected"); return false; } cp_parser_iteration_statement (parser, true); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 224be8b..db08d1d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -13318,7 +13318,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, RECUR (FOR_INIT_STMT (t)); finish_for_init_stmt (stmt); tmp = RECUR (FOR_COND (t)); - finish_for_cond (tmp, stmt); + finish_for_cond (tmp, stmt, false); tmp = RECUR (FOR_EXPR (t)); finish_for_expr (tmp, stmt); RECUR (FOR_BODY (t)); @@ -13333,7 +13333,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, decl = tsubst (decl, args, complain, in_decl); maybe_push_decl (decl); expr = RECUR (RANGE_FOR_EXPR (t)); - stmt = cp_convert_range_for (stmt, decl, expr); + stmt = cp_convert_range_for (stmt, decl, expr, RANGE_FOR_IVDEP (t)); RECUR (RANGE_FOR_BODY (t)); finish_for_stmt (stmt); } @@ -13342,7 +13342,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, case WHILE_STMT: stmt = begin_while_stmt (); tmp = RECUR (WHILE_COND (t)); - finish_while_stmt_cond (tmp, stmt); + finish_while_stmt_cond (tmp, stmt, false); RECUR (WHILE_BODY (t)); finish_while_stmt (stmt); break; @@ -13352,7 +13352,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl, RECUR (DO_BODY (t)); finish_do_body (stmt); tmp = RECUR (DO_COND (t)); - finish_do_stmt (tmp, stmt); + finish_do_stmt (tmp, stmt, false); break; case IF_STMT: diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 052746c..e616196 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -726,9 +726,15 @@ begin_while_stmt (void) WHILE_STMT. */ void -finish_while_stmt_cond (tree cond, tree while_stmt) +finish_while_stmt_cond (tree cond, tree while_stmt, bool ivdep) { finish_cond (&WHILE_COND (while_stmt), maybe_convert_cond (cond)); + if (ivdep && cond != error_mark_node) + WHILE_COND (while_stmt) = build2 (ANNOTATE_EXPR, + TREE_TYPE (WHILE_COND (while_stmt)), + WHILE_COND (while_stmt), + build_int_cst (integer_type_node, + annot_expr_ivdep_kind)); simplify_loop_decl_cond (&WHILE_COND (while_stmt), WHILE_BODY (while_stmt)); } @@ -771,9 +777,12 @@ finish_do_body (tree do_stmt) COND is as indicated. */ void -finish_do_stmt (tree cond, tree do_stmt) +finish_do_stmt (tree cond, tree do_stmt, bool ivdep) { cond = maybe_convert_cond (cond); + if (ivdep && cond != error_mark_node) + cond = build2 (ANNOTATE_EXPR, TREE_TYPE (cond), cond, + build_int_cst (integer_type_node, annot_expr_ivdep_kind)); DO_COND (do_stmt) = cond; } @@ -876,9 +885,15 @@ finish_for_init_stmt (tree for_stmt) FOR_STMT. */ void -finish_for_cond (tree cond, tree for_stmt) +finish_for_cond (tree cond, tree for_stmt, bool ivdep) { finish_cond (&FOR_COND (for_stmt), maybe_convert_cond (cond)); + if (ivdep && cond != error_mark_node) + FOR_COND (for_stmt) = build2 (ANNOTATE_EXPR, + TREE_TYPE (FOR_COND (for_stmt)), + FOR_COND (for_stmt), + build_int_cst (integer_type_node, + annot_expr_ivdep_kind)); simplify_loop_decl_cond (&FOR_COND (for_stmt), FOR_BODY (for_stmt)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3fd4591..fdc9ed0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2013-10-30 Tobias Burnus <burnus@net-b.de> + + PR other/33426 + * g++.dg/vect/pr33426-ivdep-2.cc: New. + * g++.dg/vect/pr33426-ivdep-3.cc: New. + * g++.dg/vect/pr33426-ivdep-4.cc: New. + 2013-10-30 Vladimir Makarov <vmakarov@redhat.com> PR target/58784 diff --git a/gcc/testsuite/g++.dg/vect/pr33426-ivdep-2.cc b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-2.cc new file mode 100644 index 0000000..3d04230 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-2.cc @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-O3 -fopt-info-vec-optimized -fdump-tree-original -fdump-tree-gimple" } */ + +/* PR other/33426 */ +/* Testing whether #pragma ivdep is working. */ + +void foo(int n, int *a, int *b, int *c) { + int i; + i = 0; +#pragma GCC ivdep + while(i < n) + { + a[i] = b[i] + c[i]; + ++i; + } +} + +void bar(int n, int *a, int *b, int *c) { + int i; + i = 0; +#pragma GCC ivdep + do + { + a[i] = b[i] + c[i]; + ++i; + } + while(i < n); +} + +/* { dg-message "loop vectorized" "" { target *-*-* } 0 } */ +/* { dg-bogus " version" "" { target *-*-* } 0 } */ +/* { dg-bogus " alias" "" { target *-*-* } 0 } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + +/* { dg-final { scan-tree-dump-times "ANNOTATE_EXPR " 2 "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */ +/* { dg-final { scan-tree-dump-times "ANNOTATE " 2 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/vect/pr33426-ivdep-3.cc b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-3.cc new file mode 100644 index 0000000..35de3b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-3.cc @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-std=c++11 -O3 -fopt-info-vec-optimized -fdump-tree-original -fdump-tree-gimple" } */ + +/* PR other/33426 */ +/* Testing whether #pragma ivdep is working. */ + +int ar[100]; + +void foo(int *a) { +#pragma GCC ivdep + for (auto &i : ar) { + i *= *a; + } +} + +/* { dg-message "loop vectorized" "" { target *-*-* } 0 } */ +/* { dg-bogus " version" "" { target *-*-* } 0 } */ +/* { dg-bogus " alias" "" { target *-*-* } 0 } */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + +/* { dg-final { scan-tree-dump-times "ANNOTATE_EXPR " 1 "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */ +/* { dg-final { scan-tree-dump-times "ANNOTATE " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/testsuite/g++.dg/vect/pr33426-ivdep-4.cc b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-4.cc new file mode 100644 index 0000000..8850505 --- /dev/null +++ b/gcc/testsuite/g++.dg/vect/pr33426-ivdep-4.cc @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-additional-options "-std=c++11 -O3 -fopt-info-vec-optimized -fdump-tree-original -fdump-tree-gimple" } */ + +/* PR other/33426 */ +/* Testing whether #pragma ivdep is working. */ + +#include <vector> + +template<class T, class T2> +void Loop(T *b, T2 c) { +#pragma GCC ivdep + for (auto &i : *b) { + i *= *c; + } +} + +void foo(std::vector<int> *ar, int *b) { + Loop<std::vector<int>, int*>(ar, b); +} + +/* { dg-message "loop vectorized" "" { target *-*-* } 0 } */ +/* FIXME: dg-bogus " version" "" { target *-*-* } 0 */ +/* FIXME: dg-bogus " alias" "" { target *-*-* } 0 */ +/* { dg-final { cleanup-tree-dump "vect" } } */ + +/* { dg-final { scan-tree-dump-times "ANNOTATE_EXPR " 1 "original" } } */ +/* { dg-final { cleanup-tree-dump "original" } } */ +/* { dg-final { scan-tree-dump-times "ANNOTATE " 1 "gimple" } } */ +/* { dg-final { cleanup-tree-dump "gimple" } } */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index cf8200a..d705657 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -307,7 +307,8 @@ replace_loop_annotate () if ((annot_expr_kind) tree_low_cst (gimple_call_arg (stmt, 1), 0) != annot_expr_ivdep_kind) continue; - warning (0, "ignoring %<GCC ivdep%> annotation"); + warning_at (gimple_location (stmt), 0, "ignoring %<GCC ivdep%> " + "annotation"); stmt = gimple_build_assign (gimple_call_lhs (stmt), gimple_call_arg (stmt, 0)); gsi_replace (&gsi, stmt, true); |