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
This commit is contained in:
Tobias Burnus 2013-10-30 19:53:42 +01:00 committed by Tobias Burnus
parent 1079f7a198
commit c5028d807f
13 changed files with 172 additions and 32 deletions

View File

@ -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

View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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:

View File

@ -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));
}

View File

@ -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

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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" } } */

View File

@ -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);