re PR other/33426 (Support of #pragma ivdep)
authorTobias Burnus <burnus@net-b.de>
Wed, 30 Oct 2013 18:53:42 +0000 (19:53 +0100)
committerTobias Burnus <burnus@gcc.gnu.org>
Wed, 30 Oct 2013 18:53:42 +0000 (19:53 +0100)
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

13 files changed:
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/cp-array-notation.c
gcc/cp/cp-tree.h
gcc/cp/init.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/vect/pr33426-ivdep-2.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/pr33426-ivdep-3.cc [new file with mode: 0644]
gcc/testsuite/g++.dg/vect/pr33426-ivdep-4.cc [new file with mode: 0644]
gcc/tree-cfg.c

index 9907608a15092092ed361e0fcdc08798c75de5d4..ef40a4372e2f8549a75973ad54c813591980472b 100644 (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
index da1d7f945cf0d4129bb6b7e31c84a8637025ae5f..97e95f41107c2c8aa0ba103d700439de8af17cba 100644 (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.
index c700f58f69fe8373f3efc44346114eee3417f14a..e1fb0ee99ad9c847730a5f1ef873f097c6dcf7e3 100644 (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);
index 507b3897aee3fa342e9207599436cf0377ba7a8c..fd79adbd3573fd26bb0b6f0ad5b3f4831905b0d0 100644 (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);
index 78ea986a0d6b97b40a7d374a20c0e6e69608b7f5..bfd91521050b4d6923dc1454432dcc64ecf84354 100644 (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)
index 8deffc35df28014f856449d4121f1091a9f638ab..9e28cedd0e7521d3dd7737a4ea3e3d67059f5086 100644 (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);
index 224be8b988d015a2d272256e85d6d3cf5975ebf7..db08d1dd99e29bec037e4687e583131862361841 100644 (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:
index 052746c15b79460b0283139debd4709b3e552956..e616196f7dcb39e8d34e1ef5486cf3a1306ab2f5 100644 (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));
 }
 
index 3fd4591b2093c99bf5b44b8a6ebfb61b11215341..fdc9ed0feadca8ebecd2cc10760ffa5e1e1f47d2 100644 (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
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 (file)
index 0000000..3d04230
--- /dev/null
@@ -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 (file)
index 0000000..35de3b2
--- /dev/null
@@ -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 (file)
index 0000000..8850505
--- /dev/null
@@ -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" } } */
index cf8200a9f355b212bbafc9827c92b0c2ef30e849..d70565735355de987027fc0fe09dac26db3a6435 100644 (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);