[PATCH] Add PAREN_EXPR
Richard Guenther
rguenther@suse.de
Tue Feb 19 18:47:00 GMT 2008
This adds PAREN_EXPR as explained in
http://gcc.gnu.org/ml/fortran/2008-01/msg00008.html
Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for mainline?
Thanks,
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.
* 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.
Index: gcc/tree-pretty-print.c
===================================================================
*** gcc/tree-pretty-print.c.orig 2008-02-11 09:23:23.000000000 +0100
--- gcc/tree-pretty-print.c 2008-02-19 15:54:51.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-11 09:23:23.000000000 +0100
--- gcc/expr.c 2008-02-19 15:54:51.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-11 09:23:23.000000000 +0100
--- gcc/tree.def 2008-02-19 15:54:51.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-11 09:23:24.000000000 +0100
--- gcc/tree-inline.c 2008-02-19 15:54:51.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-01-03 11:22:28.000000000 +0100
--- gcc/fortran/options.c 2008-02-19 15:54:51.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-18 11:08:18.000000000 +0100
--- gcc/tree-complex.c 2008-02-19 15:54:51.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-16 19:25:10.000000000 +0100
--- gcc/fortran/trans-expr.c 2008-02-19 15:54:51.000000000 +0100
*************** 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-13 11:07:32.000000000 +0100
--- gcc/fold-const.c 2008-02-19 16:31:34.000000000 +0100
*************** fold_unary (enum tree_code code, tree ty
*** 8028,8033 ****
--- 8028,8041 ----
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 2007-12-11 12:52:38.000000000 +0100
--- gcc/tree-vectorizer.c 2008-02-19 16:11:54.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
===================================================================
*** gcc/testsuite/gfortran.dg/reassoc_1.f90 (revision 0)
--- gcc/testsuite/gfortran.dg/reassoc_1.f90 (revision 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" } }
Index: gcc/testsuite/gfortran.dg/reassoc_2.f90
===================================================================
*** gcc/testsuite/gfortran.dg/reassoc_2.f90 (revision 0)
--- gcc/testsuite/gfortran.dg/reassoc_2.f90 (revision 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.*\\\)\\\) - 5" "optimized" } }
More information about the Gcc-patches
mailing list