[PATCH][RFC] Add PAREN_EXPR, make flag_associative_math the default for Fortran
Richard Guenther
rguenther@suse.de
Wed Jan 2 14:51:00 GMT 2008
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)
Thanks,
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.
* trans-expr.c (gfc_conv_expr_op): Expand INTRINSIC_PARENTHESES
as unary PAREN_EXPR.
* 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/trans-expr.c
===================================================================
*** gcc/fortran/trans-expr.c (revision 131256)
--- gcc/fortran/trans-expr.c (working copy)
*************** gfc_conv_expr_op (gfc_se * se, gfc_expr
*** 1066,1075 ****
switch (expr->value.op.operator)
{
case INTRINSIC_UPLUS:
- case INTRINSIC_PARENTHESES:
gfc_conv_expr (se, expr->value.op.op1);
return;
case INTRINSIC_UMINUS:
gfc_conv_unary_op (NEGATE_EXPR, se, expr);
return;
--- 1066,1078 ----
switch (expr->value.op.operator)
{
case INTRINSIC_UPLUS:
gfc_conv_expr (se, expr->value.op.op1);
return;
+ case INTRINSIC_PARENTHESES:
+ gfc_conv_unary_op (PAREN_EXPR, se, expr);
+ return;
+
case INTRINSIC_UMINUS:
gfc_conv_unary_op (NEGATE_EXPR, se, expr);
return;
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;
More information about the Fortran
mailing list