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]

[PATCH] PR30391: GIMPLE_MODIFY_STMT vs. middle-end


The following patch is my proposed solution to PRs 30391, 30412 and 30672,
which are various ICEs (aborts and segmentation faults) caused by the
merge of the tuples branch.  The underlying cause is that we're
constructing special GIMPLE_MODIFY_STMT nodes (which don't have a type and
don't use the regular TREE_OPERAND mechanism) and allowing them to be used
as operands in middle-end expressions.  Unfortunately, the tree expression
handling mechanism in much of the middle-end assumes all nodes are fairly
regular, and use TREE_CODE, TREE_TYPE, TREE_OPERAND etc... to inspect
them.  Alas when the new minimal GIMPLE_MODIFY_STMTs creep into such
expressions, we run into a world of pain.

The perhaps controversial solution proposed below is to accept that the
middle-end needs to manipulate to forms of assignments, one for use in
expressions, the other for use in statements.  The statement form should
never be used in an expression context, and the expression form should
never be used in a statement context.  Indeed in Computer Science terms we
might denote one as "=" and the other as ":=".

This ideological separation is maintained by the programmer based upon
context.  Previously, the tuples branch prohibited the construction of
MODIFY_EXPR nodes outside of the front-ends once the function was in
gimple form.  Unfortunately, there are legitimate temporary uses of
MODIFY_EXPR in fold-const.c/builtins.c and expr.c that are independent of
the tree-ssa/gimple form, for example where the assignment requires a
result type, or needs to be embedded in a COMPOUND_EXPR node.  Indeed the
results of these functions are known to be non-gimple, and are
re-gimplified before being appended/inserted/updated in the statement
stream.

Following this distinction further, I think using the existing build2
interfaces for constructing non-expression trees, is potentially
confusing.  For example, these uses can't be replaced by fold_build2, they
ignore the return type, and can't be used in contexts other than
stmt_iterators etc.  Indeed there's probably very little reason for them
to be "trees" in the accepted sense.  It turns out that there's only one
tree node defined with class tcc_gimple_stmt and that's GIMPLE_MODIFY_STMT
hence the proposal below is to rename build2_gimple to instead be
build_gimple_stmt which implicitly builds a GIMPLE_MODIFY_STMT and need
only take an RHS and a LHS.

One nice middle-end aspect of this separation, is that we can continue to
tighten up the middle-end's type system.  Assignments that are constructed
via build_gimple_stmt need only have to match to within
useless_type_conversion, whereas regular expression trees built via build2
(and friends) can require stricter type equivalence.  c.f. PR 22368.


Whilst I agree with the original goal of the tuples design to completely
obsolete MODIFY_EXPR once we'd entered the late middle-end, unfortunately
there remains a need to create sequences of assignments and treat them as
single trees (using MODIFY_EXPR and COMPOUND_EXPR) much like we use
sequences in the RTL optimizers, without affecting the main get_insns
stream or the CFG.  For example, during RTL expansion we may need to
temporarily create assignments to be expanded, and there's no strong
reason for these to use the same doubly linked data structure that we use
for representing functions.


The following patch has been tested on i686-pc-linux-gnu, with a full
"make bootstrap", all default languages including Ada, and regression
tested with a top-level "make -k check" with no new failures.  This patch
is effectively the first of another transition, where all existing uses of
"build2 (GIMPLE_MODIFY_STMT, ..." are either transformed into
"build_gimple_stmt" or "{fold_}build2 (MODIFY_EXPR, ..." depending upon
context.

Aldy what do you think?  Ok for mainline?


2007-02-04  Roger Sayle  <roger@eyesopen.com>

        * tree.c (expr_align): Handle MODIFY_EXPR.  GIMPLE_MODIFY_STMT
        should be unreachable.
        (build2_stat): Allow construction of MODIFY_EXPR at any time.
        For the time being redirect GIMPLE_MODIFY_STMT to the new
        (renamed) build_gimple_stmt_stat.
        (build2_gimple_stat): Rename to...
        (build_gimple_stmt_stat): No longer take a CODE argument.
        Always build a GIMPLE_MODIFY_STMT node.
        * tree.h (build2_gimple, build2_gimple_stat): Delete.
        (build_gimple_stmt, build_gimple_stmt_stat): New declarations.

        * tree-cfg (factor_computed_gotos, tree_merge_blocks,
        gimplify_val): Use build_gimple_stmt instead of build2_gimple.
        * tree-complex.c (set_component_ssa_name, expand_complex_move,
        expand_complex_div_wide): Likewise.
        * tree-ssa-dom.c (record_equivalences_from_stmt): Likewise.
        * tree-ssa-loop-im.c (schedule_sm): Likewise.
        * tree-ssa-loop-ivopts.c (rewrite_use_nonlinear_expr): Likewise.
        * tree-ssa-loop-manip.c (create_iv): Likewise.
        * tree-ssa-phiopt.c (conditional_replacement, minmax_replacement,
        abs_replacement): Likewise.

        * builtins.c (std_expand_builtin_va_start): Build a MODIFY_EXPR
        node rather than a GIMPLE_MODIFY_STMT node.
        (std_gimpify_va_arg_expr, expand_builtin_va_copy,
        fold_builtin_memset, fold_builtin_memory_op, do_mpfr_sincos):
        Likewise.
        (integer_valued_real_p): Handle MODIFY_EXPR, not GIMPLE_MODIFY_STMT.
        * expr.c (expand_expr_real_1): Handle both MODIFY_EXPR and
        GIMPLE_MODIFY_STMT.

        * gfortran.dg/pr30391-1.f90: New test case.

Roger
--

Attachment: patchg.txt
Description: Text document

Attachment: pr30391-1.f90
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]