This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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][RFC] Add PAREN_EXPR, make flag_associative_math the default for Fortran


On Wed, 2 Jan 2008, Tobias Schlüter wrote:

> Richard Guenther wrote:
> > This adds a middle-end PAREN_EXPR tree code that acts as re-association
> > barrier for floating point expressions.  This allows to model the Fortran
> > semantics that allow re-association for expressions that are not
> > explicitly wrapped inside parentheses.
> > 
> > This simple patch (not tested yet) for example preserves a + (b - a)
> > if you build with -ffast-math.
> > 
> > function testarray (a, b)
> >    implicit none
> >    real*8 :: a, b, testarray
> > 
> >    testarray = a + (b - a)
> > end
> > 
> > eventually this allows expansion of rounding functions on the tree
> > level (those rely on us preserving stuff like (x + 1e-52) - 1e52 and
> > not constant fold it).
> > 
> > The way the patch 'works' is that nothing handles (looks through)
> > PAREN_EXPR at the moment, so it is a conservative implementation.  On
> > the RTL level it just relies on the fact that we do not re-associate
> > floating point expressions there (we rely on that fact now anyway).
> > 
> > Any thoughts?  (Yes, I thought on using a flag on operands or variants
> > of the associative tree operators, but these either don't work do not
> > model the semantics close enough)
> 
> This matches the original intent when INTRINSIC_PARENTHESES were introduced in
> the Fortran FE.  We also use it to mimic call-by-value semantics (CALL f((X))
> instead of CALL f(X) causes f to receive a pointer to a copy of X, instead of
> X itself), but I don't think this will interfere with your patch.
> 
> Thanks for doing this!

And this version of the patch actually survives bootstrap and
regtest on x86_64-unknown-linux-gnu.  Two (additional?) failures for
gfortran are

FAIL: gfortran.dg/vect/pr32377.f90  -O  scan-tree-dump-times vect 
"vectorized 2 
loops" 1
FAIL: gfortran.dg/vect/no-vfa-pr32377.f90 scan-tree-dump-times vect 
"vectorized 
2 loops" 1

at least I see

/space/rguenther/trunk/gcc/testsuite/gfortran.dg/vect/pr32377.f90:9: note: 
not vectorized: relevant stmt not supported: D.935_94 = ((D.934_93))

so probably PAREN_EXPR needs to be ignored in some places, in this case
it needs to be handled like a simple copy.  Another case where it can
be possibly ignored is operand_equal_p, as ((a + b)) is equal to a + b,
though if we use this equality to substitute either for the other we
need to be careful.

Richard.


2008-01-02  Richard Guenther  <rguenther@suse.de>

	* tree.def (PAREN_EXPR): New tree code.
	* 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.

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

Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c	(revision 131256)
--- gcc/tree-pretty-print.c	(working copy)
*************** 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	(revision 131256)
--- gcc/expr.c	(working copy)
*************** expand_expr_real_1 (tree exp, rtx target
*** 8043,8048 ****
--- 8043,8049 ----
        }
        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	(revision 131256)
--- gcc/tree.def	(working copy)
*************** 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	(revision 131256)
--- gcc/tree-inline.c	(working copy)
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 2135,2140 ****
--- 2135,2141 ----
      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	(revision 131256)
--- gcc/fortran/options.c	(working copy)
*************** 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	(revision 131260)
--- gcc/tree-complex.c	(working copy)
*************** expand_complex_move (block_stmt_iterator
*** 763,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))
  	{
  	  r = build1 (REALPART_EXPR, inner_type, lhs);
  	  i = build1 (IMAGPART_EXPR, inner_type, lhs);
--- 763,770 ----
  	  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	(revision 131260)
--- gcc/fortran/trans-expr.c	(working copy)
*************** gfc_conv_expr_op (gfc_se * se, gfc_expr 
*** 1065,1072 ****
    lop = 0;
    switch (expr->value.op.operator)
      {
-     case INTRINSIC_UPLUS:
      case INTRINSIC_PARENTHESES:
        gfc_conv_expr (se, expr->value.op.op1);
        return;
  
--- 1065,1081 ----
    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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]