OSDN Git Service

2008-02-21 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Feb 2008 09:38:07 +0000 (09:38 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 21 Feb 2008 09:38:07 +0000 (09:38 +0000)
* tree.def (PAREN_EXPR): New tree code.
* fold-const.c (fold_unary): Remove PAREN_EXPR around constants
and PAREN_EXPR.
* tree-pretty-print.c (dump_generic_node): Handle PAREN_EXPR.
* expr.c (expand_expr_real_1): Likewise.
* tree-inline.c (estimate_num_insns_1): Likewise.
* tree-complex.c (expand_complex_move): Likewise.
* tree-vectorizer.c (vect_is_simple_use): Treat PAREN_EXPR (x)
as plain x.

* trans-expr.c (gfc_conv_expr_op): Expand INTRINSIC_PARENTHESES
as unary PAREN_EXPR for real and complex typed expressions.
(gfc_conv_unary_op): Fold the built tree.

* gfortran.dg/reassoc_1.f90: New testcase.
* gfortran.dg/reassoc_2.f90: Likewise.
* gfortran.dg/reassoc_3.f90: Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@132515 138bc75d-0d04-0410-961f-82ee72b054a4

14 files changed:
gcc/ChangeLog
gcc/expr.c
gcc/fold-const.c
gcc/fortran/ChangeLog
gcc/fortran/trans-expr.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/reassoc_1.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/reassoc_2.f90 [new file with mode: 0644]
gcc/testsuite/gfortran.dg/reassoc_3.f90 [new file with mode: 0644]
gcc/tree-complex.c
gcc/tree-inline.c
gcc/tree-pretty-print.c
gcc/tree-vectorizer.c
gcc/tree.def

index 8c0b6eb..29576a6 100644 (file)
@@ -1,3 +1,15 @@
+2008-02-21  Richard Guenther  <rguenther@suse.de>
+
+       * tree.def (PAREN_EXPR): New tree code.
+       * fold-const.c (fold_unary): Remove PAREN_EXPR around constants
+       and PAREN_EXPR.
+       * tree-pretty-print.c (dump_generic_node): Handle PAREN_EXPR.
+       * expr.c (expand_expr_real_1): Likewise.
+       * tree-inline.c (estimate_num_insns_1): Likewise.
+       * tree-complex.c (expand_complex_move): Likewise.
+       * tree-vectorizer.c (vect_is_simple_use): Treat PAREN_EXPR (x)
+       as plain x.
+
 2008-02-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR target/35225
 2008-02-20  Kaz Kojima  <kkojima@gcc.gnu.org>
 
        PR target/35225
index ade0396..3674191 100644 (file)
@@ -8049,6 +8049,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
       }
       return expand_call (exp, target, ignore);
 
       }
       return expand_call (exp, target, ignore);
 
+    case PAREN_EXPR:
     case NON_LVALUE_EXPR:
     case NOP_EXPR:
     case CONVERT_EXPR:
     case NON_LVALUE_EXPR:
     case NOP_EXPR:
     case CONVERT_EXPR:
index 5d64c17..1ecd225 100644 (file)
@@ -8027,6 +8027,14 @@ fold_unary (enum tree_code code, tree type, tree op0)
 
   switch (code)
     {
 
   switch (code)
     {
+    case PAREN_EXPR:
+      /* Re-association barriers around constants and other re-association
+        barriers can be removed.  */
+      if (CONSTANT_CLASS_P (op0)
+         || TREE_CODE (op0) == PAREN_EXPR)
+       return fold_convert (type, op0);
+      return NULL_TREE;
+
     case NOP_EXPR:
     case FLOAT_EXPR:
     case CONVERT_EXPR:
     case NOP_EXPR:
     case FLOAT_EXPR:
     case CONVERT_EXPR:
index cdce280..43e89da 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-21  Richard Guenther  <rguenther@suse.de>
+
+       * trans-expr.c (gfc_conv_expr_op): Expand INTRINSIC_PARENTHESES
+       as unary PAREN_EXPR for real and complex typed expressions.
+       (gfc_conv_unary_op): Fold the built tree.
+
 2008-02-20  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/34997
 2008-02-20  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/34997
index 4866d8c..8d0392f 100644 (file)
@@ -607,10 +607,10 @@ gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
      All other unary operators have an equivalent GIMPLE unary operator.  */
   if (code == TRUTH_NOT_EXPR)
      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
      All other unary operators have an equivalent GIMPLE unary operator.  */
   if (code == TRUTH_NOT_EXPR)
-    se->expr = build2 (EQ_EXPR, type, operand.expr,
-                      build_int_cst (type, 0));
+    se->expr = fold_build2 (EQ_EXPR, type, operand.expr,
+                           build_int_cst (type, 0));
   else
   else
-    se->expr = build1 (code, type, operand.expr);
+    se->expr = fold_build1 (code, type, operand.expr);
 
 }
 
 
 }
 
@@ -1071,8 +1071,17 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
   lop = 0;
   switch (expr->value.op.operator)
     {
   lop = 0;
   switch (expr->value.op.operator)
     {
-    case INTRINSIC_UPLUS:
     case INTRINSIC_PARENTHESES:
     case INTRINSIC_PARENTHESES:
+      if (expr->ts.type == BT_REAL
+         || expr->ts.type == BT_COMPLEX)
+       {
+         gfc_conv_unary_op (PAREN_EXPR, se, expr);
+         gcc_assert (FLOAT_TYPE_P (TREE_TYPE (se->expr)));
+         return;
+       }
+
+      /* Fallthrough.  */
+    case INTRINSIC_UPLUS:
       gfc_conv_expr (se, expr->value.op.op1);
       return;
 
       gfc_conv_expr (se, expr->value.op.op1);
       return;
 
index 91306f0..780efe8 100644 (file)
@@ -1,3 +1,9 @@
+2008-02-21  Richard Guenther  <rguenther@suse.de>
+
+       * gfortran.dg/reassoc_1.f90: New testcase.
+       * gfortran.dg/reassoc_2.f90: Likewise.
+       * gfortran.dg/reassoc_3.f90: Likewise.
+
 2008-02-20  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/34974
 2008-02-20  Jerry DeLisle  <jvdelisle@gcc.gnu.org>
 
        PR libfortran/34974
diff --git a/gcc/testsuite/gfortran.dg/reassoc_1.f90 b/gcc/testsuite/gfortran.dg/reassoc_1.f90
new file mode 100644 (file)
index 0000000..eb7d443
--- /dev/null
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-O3 -ffast-math -fdump-tree-optimized" }
+
+function test(b)
+  real a
+  a = (b + 5.) - 5.
+  test = a
+end
+
+! { dg-final { scan-tree-dump "\\\+ 5.*\\\)\\\) - 5" "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/reassoc_2.f90 b/gcc/testsuite/gfortran.dg/reassoc_2.f90
new file mode 100644 (file)
index 0000000..3e323eb
--- /dev/null
@@ -0,0 +1,15 @@
+! { dg-do compile }
+! { dg-options "-O3 -ffast-math -fdump-tree-optimized" }
+
+! Make sure that FRE does not replace c with b in d = c - 5
+
+function test(a)
+  real a, b, c, d
+  b = a + 5.
+  c = (a + 5.)
+  d = c - 5.
+  call foo(b)
+  test = d
+end
+
+! { dg-final { scan-tree-dump "- 5" "optimized" } }
diff --git a/gcc/testsuite/gfortran.dg/reassoc_3.f90 b/gcc/testsuite/gfortran.dg/reassoc_3.f90
new file mode 100644 (file)
index 0000000..c0cec0b
--- /dev/null
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-options "-O -ffast-math -fdump-tree-original -fdump-tree-optimized" }
+
+! Verify we associate properly during folding
+! Verify we propagate constants in the presence of PAREN_EXPR
+
+function test(a)
+  real b, c, d
+  c = a
+  d = 5
+  b = (c + 5 - c)
+  b = (c + d - c)
+  test = a + b - 5
+end
+
+! { dg-final { scan-tree-dump "b = 5" "original" } }
+! { dg-final { scan-tree-dump "return .a" "optimized" } }
index b9c7ebc..10fa0ae 100644 (file)
@@ -762,7 +762,8 @@ expand_complex_move (block_stmt_iterator *bsi, tree stmt, tree type,
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
          update_complex_components_on_edge (e, lhs, r, i);
        }
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
          update_complex_components_on_edge (e, lhs, r, i);
        }
-      else if (TREE_CODE (rhs) == CALL_EXPR || TREE_SIDE_EFFECTS (rhs))
+      else if (TREE_CODE (rhs) == CALL_EXPR || TREE_SIDE_EFFECTS (rhs)
+              || TREE_CODE (rhs) == PAREN_EXPR)
        {
          r = build1 (REALPART_EXPR, inner_type, lhs);
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
        {
          r = build1 (REALPART_EXPR, inner_type, lhs);
          i = build1 (IMAGPART_EXPR, inner_type, lhs);
index 201f2cf..9fb8792 100644 (file)
@@ -2222,6 +2222,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
     case COMPOUND_EXPR:
     case BIND_EXPR:
     case WITH_CLEANUP_EXPR:
     case COMPOUND_EXPR:
     case BIND_EXPR:
     case WITH_CLEANUP_EXPR:
+    case PAREN_EXPR:
     case NOP_EXPR:
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
     case NOP_EXPR:
     case CONVERT_EXPR:
     case VIEW_CONVERT_EXPR:
index 4d1f6f4..3b60b25 100644 (file)
@@ -1446,6 +1446,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
       pp_character (buffer, ')');
       break;
 
       pp_character (buffer, ')');
       break;
 
+    case PAREN_EXPR:
+      pp_string (buffer, "((");
+      dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
+      pp_string (buffer, "))");
+      break;
+
     case NON_LVALUE_EXPR:
       pp_string (buffer, "NON_LVALUE_EXPR <");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
     case NON_LVALUE_EXPR:
       pp_string (buffer, "NON_LVALUE_EXPR <");
       dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
index 0131b9a..92c46a0 100644 (file)
@@ -2002,7 +2002,13 @@ vect_is_simple_use (tree operand, loop_vec_info loop_vinfo, tree *def_stmt,
       *dt = vect_invariant_def;
       return true;
    }
       *dt = vect_invariant_def;
       return true;
    }
-    
+
+  if (TREE_CODE (operand) == PAREN_EXPR)
+    {
+      if (vect_print_dump_info (REPORT_DETAILS))
+        fprintf (vect_dump, "non-associatable copy.");
+      operand = TREE_OPERAND (operand, 0);
+    }
   if (TREE_CODE (operand) != SSA_NAME)
     {
       if (vect_print_dump_info (REPORT_DETAILS))
   if (TREE_CODE (operand) != SSA_NAME)
     {
       if (vect_print_dump_info (REPORT_DETAILS))
index 5693749..f485e4b 100644 (file)
@@ -733,6 +733,10 @@ DEFTREECODE (LTGT_EXPR, "ltgt_expr", tcc_comparison, 2)
 
 DEFTREECODE (RANGE_EXPR, "range_expr", tcc_binary, 2)
 
 
 DEFTREECODE (RANGE_EXPR, "range_expr", tcc_binary, 2)
 
+/* Represents a re-association barrier for floating point expressions
+   like explicit parenthesis in fortran.  */
+DEFTREECODE (PAREN_EXPR, "paren_expr", tcc_unary, 1)
+
 /* Represents a conversion of type of a value.
    All conversions, including implicit ones, must be
    represented by CONVERT_EXPR or NOP_EXPR nodes.  */
 /* Represents a conversion of type of a value.
    All conversions, including implicit ones, must be
    represented by CONVERT_EXPR or NOP_EXPR nodes.  */