This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Add PAREN_EXPR


On Tue, 19 Feb 2008, FX wrote:

> >         * trans-expr.c (gfc_conv_expr_op): Expand INTRINSIC_PARENTHESES
> >         as unary PAREN_EXPR for real and complex typed expressions.
> >         * options.c (gfc_init_options): Enable flag_associative_math if
> >         it isn't disabled automatically.
> >
> >         * gfortran.dg/reassoc_1.f90: New testcase.
> >         * gfortran.dg/reassoc_2.f90: Likewise.
> 
> Fortran part is OK. Thanks!

Actually setting flag_associative_math conditional on other flags
doesn't work in gfc_init_options, as the middle-end flags are not
yet processed.

So I'll leave out enabling -fassociative-math by default for Fortran.
You should think about grouping semantics somehow with maybe a tri-state
flag:

  IEEE math
  reassociation, only finite math, no signed zeros, no traps  (default)
  fast-math

or whatever would be correct by default for Fortran.

The following is what I will commit after re-testing.

Richard.

2008-02-19  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.

	* 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.
	* options.c (gfc_init_options): Enable flag_associative_math if
	it isn't disabled automatically.

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

Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/tree-pretty-print.c	2008-02-20 15:15:49.000000000 +0100
*************** dump_generic_node (pretty_printer *buffe
*** 1446,1451 ****
--- 1446,1457 ----
        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);
Index: gcc/expr.c
===================================================================
*** gcc/expr.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/expr.c	2008-02-20 15:15:49.000000000 +0100
*************** expand_expr_real_1 (tree exp, rtx target
*** 8049,8054 ****
--- 8049,8055 ----
        }
        return expand_call (exp, target, ignore);
  
+     case PAREN_EXPR:
      case NON_LVALUE_EXPR:
      case NOP_EXPR:
      case CONVERT_EXPR:
Index: gcc/tree.def
===================================================================
*** gcc/tree.def.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/tree.def	2008-02-20 15:15:49.000000000 +0100
*************** DEFTREECODE (LTGT_EXPR, "ltgt_expr", tcc
*** 733,738 ****
--- 733,742 ----
  
  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.  */
Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/tree-inline.c	2008-02-20 15:15:49.000000000 +0100
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 2222,2227 ****
--- 2222,2228 ----
      case COMPOUND_EXPR:
      case BIND_EXPR:
      case WITH_CLEANUP_EXPR:
+     case PAREN_EXPR:
      case NOP_EXPR:
      case CONVERT_EXPR:
      case VIEW_CONVERT_EXPR:
Index: gcc/fortran/options.c
===================================================================
*** gcc/fortran/options.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/fortran/options.c	2008-02-20 15:15:49.000000000 +0100
*************** gfc_init_options (unsigned int argc ATTR
*** 121,126 ****
--- 121,131 ----
  
    flag_errno_math = 0;
  
+   /* Fortran allows re-association.  Parenthesis are explicitly preserved
+      and act as re-association barrier.  */
+   if (!flag_trapping_math && !flag_signed_zeros)
+     flag_associative_math = 1;
+ 
    set_default_std_flags ();
  
    gfc_option.warn_nonstd_intrinsics = 0;
Index: gcc/tree-complex.c
===================================================================
*** gcc/tree-complex.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/tree-complex.c	2008-02-20 15:15:49.000000000 +0100
*************** expand_complex_move (block_stmt_iterator
*** 762,768 ****
  	  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))
  	{
  	  r = build1 (REALPART_EXPR, inner_type, lhs);
  	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
--- 762,769 ----
  	  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)
! 	       || TREE_CODE (rhs) == PAREN_EXPR)
  	{
  	  r = build1 (REALPART_EXPR, inner_type, lhs);
  	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
Index: gcc/fortran/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/fortran/trans-expr.c	2008-02-20 15:15:49.000000000 +0100
*************** gfc_conv_unary_op (enum tree_code code, 
*** 607,616 ****
       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));
    else
!     se->expr = build1 (code, type, operand.expr);
  
  }
  
--- 607,616 ----
       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 = fold_build2 (EQ_EXPR, type, operand.expr,
! 			    build_int_cst (type, 0));
    else
!     se->expr = fold_build1 (code, type, operand.expr);
  
  }
  
*************** gfc_conv_expr_op (gfc_se * se, gfc_expr 
*** 1071,1078 ****
    lop = 0;
    switch (expr->value.op.operator)
      {
-     case INTRINSIC_UPLUS:
      case INTRINSIC_PARENTHESES:
        gfc_conv_expr (se, expr->value.op.op1);
        return;
  
--- 1071,1087 ----
    lop = 0;
    switch (expr->value.op.operator)
      {
      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;
  
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c.orig	2008-02-20 15:13:54.000000000 +0100
--- gcc/fold-const.c	2008-02-20 15:15:49.000000000 +0100
*************** fold_unary (enum tree_code code, tree ty
*** 8027,8032 ****
--- 8027,8040 ----
  
    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:
Index: gcc/tree-vectorizer.c
===================================================================
*** gcc/tree-vectorizer.c.orig	2008-02-20 13:39:13.000000000 +0100
--- gcc/tree-vectorizer.c	2008-02-20 15:15:49.000000000 +0100
*************** vect_is_simple_use (tree operand, loop_v
*** 2002,2008 ****
        *dt = vect_invariant_def;
        return true;
     }
!     
    if (TREE_CODE (operand) != SSA_NAME)
      {
        if (vect_print_dump_info (REPORT_DETAILS))
--- 2002,2014 ----
        *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))
Index: gcc/testsuite/gfortran.dg/reassoc_1.f90
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gfortran.dg/reassoc_1.f90	2008-02-20 15:15:49.000000000 +0100
***************
*** 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" } }
Index: gcc/testsuite/gfortran.dg/reassoc_2.f90
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gfortran.dg/reassoc_2.f90	2008-02-20 15:15:49.000000000 +0100
***************
*** 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" } }
Index: gcc/testsuite/gfortran.dg/reassoc_3.f90
===================================================================
*** /dev/null	1970-01-01 00:00:00.000000000 +0000
--- gcc/testsuite/gfortran.dg/reassoc_3.f90	2008-02-20 15:31:33.000000000 +0100
***************
*** 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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]