From a32b97a20d6638f3cee28919f4e6bd7b1d9b39e8 Mon Sep 17 00:00:00 2001 From: Brian Booth Date: Thu, 10 Jun 2004 21:41:08 +0000 Subject: [PATCH] tree-ssa.texi: Remove references to VDEF and add descriptions of V_MAY_DEF and V_MUST_DEF. * doc/tree-ssa.texi: Remove references to VDEF and add descriptions of V_MAY_DEF and V_MUST_DEF. * tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename num_vdefs to num_v_may_defs. (compute_immediate_uses_for_stmt): Rename occurences of vdef to v_may_def. (redirect_immediate_uses): Ditto. (dump_dfa_stats): Ditto. Also added code to dump num_v_must_defs. (collect_dfa_stats_r): Rename occurences of vdef to v_may_def. Also add code to sum up the number of v_must_defs. (vdefs_disappeared_p): Replace with... (v_may_defs_disappeared_p): This. (v_must_defs_disappeared_p): New function. (mark_new_vars_to_rename): Rename occurences of vdef to v_may_def. Also add code to mark new variables found in V_MUST_DEFs for renameing. * tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace vdef_ops to v_may_def_ops. (get_vdef_ops): Replace with... (get_v_may_def_ops): This. * tree-flow-inline.h (get_vdef_ops): Replace with... (get_v_may_def_ops): This. (get_v_must_def_ops): New function. (get_vdef_result_ptr): Replace with... (get_v_may_def_result_ptr): This. (get_vdef_op_ptr): Ditto with... (get_v_may_def_op_ptr); This. (get_v_must_def_op_ptr): New function. * tree-into-ssa.c (mark_def_sites): Rename occurences of vdef to v_may_def. Also add code to mark statements with V_MUST_DEFs as definition sites. (rewrite_stmt): Rename occurences of vdef to v_may_def. Also add code to register new V_MUST_DEFs made by the statement. * tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments. (check_replaceable): Rename occurences of vdef to v_may_def. Also add check for V_MUST_DEFs. (find_replaceable_in_bb): Ditto. * tree-pretty-print.c (dump_vops): Rename occurences of vdef to v_may_def. Also add code to dump V_MUST_DEFs. * tree-sra.c (mark_all_vdefs): Replace with... (mark_all_v_may_defs): This. (mark_all_v_must_defs): New function. (create_scalar_copies): Replace call to mark_all_vdefs with calls to mark_all_v_may_defs and mark_all_v_must_defs. (scalarize_structures): Rename occurences of vdef to v_may_def. Also add a check for V_MUST_DEFs. (scalarize_modify_expr): Rename occurences of vdef to v_may_def. * tree-ssa-alias.c (global_var): Update comment. (compute_may_aliases): Ditto. (compute_points_to_and_addr_escape): Rename occurences of vdef to v_may_def. Also add code to mark variables in V_MUST_DEF operands as being written to. (group_aliases): Update comment. (maybe_create_global_var): Ditto. * tree-ssa.c (verify_ssa): Rename occurences of vdef to v_may_def. Also add a check for V_MUST_DEFs on GIMPLE registers. (replace_immediate_uses): Rename occurences of vdef to v_may_def. * tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef to v_may_def. Also add code to mark all V_MUST_DEF operands VARYING. (initialize): Ditto. (set_rhs): Rename occurences of vdef to v_may_def. Also add code to update SSA_NAMEs in V_MUST_DEFs. * tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef to v_may_def. * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename occurences of vdef to v_may_def. Also add code to mark statements with V_MUST_DEFs as necessary. (propagate_necessity): Rename occurences of vdef to v_may_def. * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename occurences of vdef to v_may_def. Also add code to mark operands in V_MUST_DEFs for renaming. (eliminate_redundant_computations): Rename occurences of vdef to v_may_def. (record_equivalences_from_stmt): Rename occurences of vdef to v_may_def. Also add code to record VUSEs for V_MUST_DEFs. (optimize_stmt): Remove unnesessary variable vdefs. Update comment. (register_definitions_for_stmt): Rename occurences of vdef to v_may_def. Also add code to register definitions made with V_MUST_DEFs. * tree-ssa-dse.c (fix_stmt_vdefs): Replace with... (fix_stmt_v_may_defs): This. (fix_phi_uses): Rename occurences of vdef to v_may_def. (dse_optimize_stmt): Ditto. * tree-ssa-live.c (create_ssa_var_map): Rename occurences of vdef to v_may_def. Also add code to mark V_MUST_DEF operands as being used in virtual operators. * tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of vdef to v_may_def. Also add code to mark V_MUST_DEF operands for renaming. * tree-ssa-operands.c (opf_kill_def): New flag for killing definitions. (build_vdefs): Renamed to... (build_v_may_defs): This. (build_v_must_defs): New variable. (voperands_d): Add v_must_def_ops and replace vdef_ops with v_may_def_ops. (append_vdef): Replace with... (append_v_may_def): This. (append_v_must_def): New function. (NUM_FREE): Increment for V_MUST_DEF (optype_freelist): Increment its size for V_MUST_DEF (allocate_vdef_optype): Replace with... (allocate_v_may_def_optype): This. (allocate_v_must_def_optype): New function. (free_vdefs): Replace with... (free_v_may_defs): This. (free_v_must_defs): New function. (remove_vdefs): Replace with... (remove_v_may_defs): This. (remove_v_must_defs): New function. (init_ssa_operands): Rename occurences of vdef to v_may_def. Also add code to initialize build_v_must_defs. (finalize_ssa_vdefs): Replace with... (finalize_ssa_v_may_defs): This. (finalize_ssa_vuses): Rename occurences of vdef to v_may_def. (finalize_ssa_v_must_defs): New function. (finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs with calls to finalize_ssa_v_may_defs and finalize_ssa_v_must_defs. (verify_start_operands): Rename occurences of vdef to v_may_def. Also add check for build_v_must_defs. (get_stmt_operands): Rename occurences of vdef to v_may_def. Also add code to handle V_MUST_DEFs and to use opf_kill_def for killing definitions. (get_expr_operands): Update comment and use opf_kill_def for killing definitions. (add_stmt_operand): Replace code that appends VDEFs with code that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs otherwise. (add_call_clobber_ops): Update comments. * tree-ssa-operands.h (vdef_optype_d): Replace with... (v_may_def_optype_d): This. (v_must_def_optype_d): New structure. (VDEF_OPS): Replace with... (V_MAY_DEF_OPS): This. (STMT_VDEF_OPS): Same with... (STMT_V_MAY_DEF_OPS): This. (NUM_VDEFS): And... (NUM_V_MAY_DEFS): This. (VDEF_RESULT_PTR): As well as... (V_MAY_DEF_RESULT_PTR): This. (VDEF_RESULT): Same goes for... (V_MAY_DEF_RESULT): This. (VDEF_OP_PTR): And... (V_MAY_DEF_OP_PTR): This. (VDEF_OP): And... (V_MAY_DEF_OP): This. (V_MUST_DEF_OPS): New macro. (STMT_V_MUST_DEF_OPS): Ditto. (NUM_V_MUST_DEFS): Ditto. (V_MUST_DEF_OP_PTR): Ditto. (V_MUST_DEF_OP): Ditto. (remove_vdefs): Replace signature with... (remove_v_may_defs): This. (remove_v_must_defs): New function signature. * tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs with calls to remove_v_may_defs and remove_v_must_defs. (process_left_occs_and_kills): Rename occurences of vdef to v_may_def. Also add code that marks left occurences of operands in V_MUST_DEFs. * tree-tailcall.c (find_tail_calls): Rename occurences of vdef to v_may_def. Also add check for V_MUST_DEFs. (eliminate_tail_call):Rename occurences of vdef to v_may_def. testsuite: * gcc.dg/tree-ssa/20031015-1.c: Scan for V_MAY_DEF instead of VDEF. * gcc.dg/tree-ssa/20040517-1.c: Ditto. From-SVN: r82947 --- gcc/ChangeLog | 166 +++++++++++ gcc/doc/tree-ssa.texi | 48 ++-- gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c | 2 +- gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c | 2 +- gcc/tree-dfa.c | 108 +++++-- gcc/tree-flow-inline.h | 34 ++- gcc/tree-flow.h | 7 +- gcc/tree-into-ssa.c | 65 +++-- gcc/tree-outof-ssa.c | 22 +- gcc/tree-pretty-print.c | 22 +- gcc/tree-sra.c | 55 ++-- gcc/tree-ssa-alias.c | 44 +-- gcc/tree-ssa-ccp.c | 53 +++- gcc/tree-ssa-copy.c | 14 +- gcc/tree-ssa-dce.c | 39 ++- gcc/tree-ssa-dom.c | 63 +++-- gcc/tree-ssa-dse.c | 67 ++--- gcc/tree-ssa-live.c | 19 +- gcc/tree-ssa-loop.c | 18 +- gcc/tree-ssa-operands.c | 309 ++++++++++++++++----- gcc/tree-ssa-operands.h | 41 ++- gcc/tree-ssa-pre.c | 41 ++- gcc/tree-ssa.c | 49 ++-- gcc/tree-tailcall.c | 13 +- 25 files changed, 972 insertions(+), 335 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6a1b4db0d09..0075059953b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,169 @@ +2004-06-10 Brian Booth + + * doc/tree-ssa.texi: Remove references to VDEF and add descriptions + of V_MAY_DEF and V_MUST_DEF. + * tree-dfa.c (dfa_stats_d): Add num_v_must_defs and rename + num_vdefs to num_v_may_defs. + (compute_immediate_uses_for_stmt): Rename occurences of vdef + to v_may_def. + (redirect_immediate_uses): Ditto. + (dump_dfa_stats): Ditto. Also added code to dump num_v_must_defs. + (collect_dfa_stats_r): Rename occurences of vdef to v_may_def. + Also add code to sum up the number of v_must_defs. + (vdefs_disappeared_p): Replace with... + (v_may_defs_disappeared_p): This. + (v_must_defs_disappeared_p): New function. + (mark_new_vars_to_rename): Rename occurences of vdef to v_may_def. + Also add code to mark new variables found in V_MUST_DEFs for + renameing. + * tree-flow.h (stmt_ann_d): Add v_must_def_ops and replace + vdef_ops to v_may_def_ops. + (get_vdef_ops): Replace with... + (get_v_may_def_ops): This. + * tree-flow-inline.h (get_vdef_ops): Replace with... + (get_v_may_def_ops): This. + (get_v_must_def_ops): New function. + (get_vdef_result_ptr): Replace with... + (get_v_may_def_result_ptr): This. + (get_vdef_op_ptr): Ditto with... + (get_v_may_def_op_ptr); This. + (get_v_must_def_op_ptr): New function. + * tree-into-ssa.c (mark_def_sites): Rename occurences of vdef + to v_may_def. Also add code to mark statements with + V_MUST_DEFs as definition sites. + (rewrite_stmt): Rename occurences of vdef to v_may_def. Also + add code to register new V_MUST_DEFs made by the statement. + * tree-outof-ssa.c (VIRTUAL_PARTITION): Update comments. + (check_replaceable): Rename occurences of vdef to v_may_def. Also + add check for V_MUST_DEFs. + (find_replaceable_in_bb): Ditto. + * tree-pretty-print.c (dump_vops): Rename occurences of vdef + to v_may_def. Also add code to dump V_MUST_DEFs. + * tree-sra.c (mark_all_vdefs): Replace with... + (mark_all_v_may_defs): This. + (mark_all_v_must_defs): New function. + (create_scalar_copies): Replace call to mark_all_vdefs with + calls to mark_all_v_may_defs and mark_all_v_must_defs. + (scalarize_structures): Rename occurences of vdef to v_may_def. + Also add a check for V_MUST_DEFs. + (scalarize_modify_expr): Rename occurences of vdef to v_may_def. + * tree-ssa-alias.c (global_var): Update comment. + (compute_may_aliases): Ditto. + (compute_points_to_and_addr_escape): Rename occurences of vdef + to v_may_def. Also add code to mark variables in V_MUST_DEF + operands as being written to. + (group_aliases): Update comment. + (maybe_create_global_var): Ditto. + * tree-ssa.c (verify_ssa): Rename occurences of vdef to v_may_def. + Also add a check for V_MUST_DEFs on GIMPLE registers. + (replace_immediate_uses): Rename occurences of vdef to v_may_def. + * tree-ssa-ccp.c (visit_stmt): Rename occurences of vdef + to v_may_def. Also add code to mark all V_MUST_DEF operands + VARYING. + (initialize): Ditto. + (set_rhs): Rename occurences of vdef to v_may_def. Also add + code to update SSA_NAMEs in V_MUST_DEFs. + * tree-ssa-copy.c (cprop_into_stmt): Rename occurences of vdef + to v_may_def. + * tree-ssa-dce.c (mark_stmt_if_obviously_necessary): Rename + occurences of vdef to v_may_def. Also add code to mark statements + with V_MUST_DEFs as necessary. + (propagate_necessity): Rename occurences of vdef to v_may_def. + * tree-ssa-dom.c (redirect_edges_and_update_ssa_graph): Rename + occurences of vdef to v_may_def. Also add code to mark operands + in V_MUST_DEFs for renaming. + (eliminate_redundant_computations): Rename occurences of vdef + to v_may_def. + (record_equivalences_from_stmt): Rename occurences of vdef + to v_may_def. Also add code to record VUSEs for V_MUST_DEFs. + (optimize_stmt): Remove unnesessary variable vdefs. Update + comment. + (register_definitions_for_stmt): Rename occurences of vdef + to v_may_def. Also add code to register definitions made with + V_MUST_DEFs. + * tree-ssa-dse.c (fix_stmt_vdefs): Replace with... + (fix_stmt_v_may_defs): This. + (fix_phi_uses): Rename occurences of vdef to v_may_def. + (dse_optimize_stmt): Ditto. + * tree-ssa-live.c (create_ssa_var_map): Rename occurences of vdef + to v_may_def. Also add code to mark V_MUST_DEF operands as being + used in virtual operators. + * tree-ssa-loop.c (mark_defs_for_rewrite): Rename occurences of + vdef to v_may_def. Also add code to mark V_MUST_DEF operands for + renaming. + * tree-ssa-operands.c (opf_kill_def): New flag for killing + definitions. + (build_vdefs): Renamed to... + (build_v_may_defs): This. + (build_v_must_defs): New variable. + (voperands_d): Add v_must_def_ops and replace vdef_ops with + v_may_def_ops. + (append_vdef): Replace with... + (append_v_may_def): This. + (append_v_must_def): New function. + (NUM_FREE): Increment for V_MUST_DEF + (optype_freelist): Increment its size for V_MUST_DEF + (allocate_vdef_optype): Replace with... + (allocate_v_may_def_optype): This. + (allocate_v_must_def_optype): New function. + (free_vdefs): Replace with... + (free_v_may_defs): This. + (free_v_must_defs): New function. + (remove_vdefs): Replace with... + (remove_v_may_defs): This. + (remove_v_must_defs): New function. + (init_ssa_operands): Rename occurences of vdef to v_may_def. Also + add code to initialize build_v_must_defs. + (finalize_ssa_vdefs): Replace with... + (finalize_ssa_v_may_defs): This. + (finalize_ssa_vuses): Rename occurences of vdef to v_may_def. + (finalize_ssa_v_must_defs): New function. + (finalize_ssa_stmt_operands): Replace call to finalize_ssa_vdefs + with calls to finalize_ssa_v_may_defs and finalize_ssa_v_must_defs. + (verify_start_operands): Rename occurences of vdef to v_may_def. + Also add check for build_v_must_defs. + (get_stmt_operands): Rename occurences of vdef to v_may_def. + Also add code to handle V_MUST_DEFs and to use opf_kill_def for + killing definitions. + (get_expr_operands): Update comment and use opf_kill_def for + killing definitions. + (add_stmt_operand): Replace code that appends VDEFs with code + that appends V_MUST_DEFs when opf_kill_def is set and V_MAY_DEFs + otherwise. + (add_call_clobber_ops): Update comments. + * tree-ssa-operands.h (vdef_optype_d): Replace with... + (v_may_def_optype_d): This. + (v_must_def_optype_d): New structure. + (VDEF_OPS): Replace with... + (V_MAY_DEF_OPS): This. + (STMT_VDEF_OPS): Same with... + (STMT_V_MAY_DEF_OPS): This. + (NUM_VDEFS): And... + (NUM_V_MAY_DEFS): This. + (VDEF_RESULT_PTR): As well as... + (V_MAY_DEF_RESULT_PTR): This. + (VDEF_RESULT): Same goes for... + (V_MAY_DEF_RESULT): This. + (VDEF_OP_PTR): And... + (V_MAY_DEF_OP_PTR): This. + (VDEF_OP): And... + (V_MAY_DEF_OP): This. + (V_MUST_DEF_OPS): New macro. + (STMT_V_MUST_DEF_OPS): Ditto. + (NUM_V_MUST_DEFS): Ditto. + (V_MUST_DEF_OP_PTR): Ditto. + (V_MUST_DEF_OP): Ditto. + (remove_vdefs): Replace signature with... + (remove_v_may_defs): This. + (remove_v_must_defs): New function signature. + * tree-ssa-pre.c (subst_phis): Replace call to remove_vdefs + with calls to remove_v_may_defs and remove_v_must_defs. + (process_left_occs_and_kills): Rename occurences of vdef to v_may_def. + Also add code that marks left occurences of operands in V_MUST_DEFs. + * tree-tailcall.c (find_tail_calls): Rename occurences of vdef + to v_may_def. Also add check for V_MUST_DEFs. + (eliminate_tail_call):Rename occurences of vdef to v_may_def. + 2004-06-10 Vladimir Makarov PR target/15653 diff --git a/gcc/doc/tree-ssa.texi b/gcc/doc/tree-ssa.texi index 56ccd6109c2..a22b4948f3b 100644 --- a/gcc/doc/tree-ssa.texi +++ b/gcc/doc/tree-ssa.texi @@ -697,8 +697,17 @@ variable @code{b} is completely modified with the contents of variable @code{a}. Real definition are also known as @dfn{killing definitions}. Similarly, the use of @code{a} reads all its bits. -In contrast, virtual operands represent partial or ambiguous -references to a variable. For instance, given +In contrast, virtual operands are used with variables that can have +a partial or ambiguous reference. This includes structures, arrays, +globals, and aliased variables. In these cases, we have two types of +definitions. For globals, structures, and arrays, we can determine from +a statement whether a variable of these types has a killing definition. +If the variable does, then the statement is marked as having a +@dfn{must definition} of that variable. However, if a statement is only +defining a part of the variable (ie. a field in a structure), or if we +know that a statement might define the variable but we cannot say for sure, +then we mark that statement as having a @dfn{may definition}. For +instance, given @smallexample @{ @@ -730,8 +739,8 @@ operands, use the @option{-vops} option to @option{-fdump-tree}: p = &a; else p = &b; - # a = VDEF - # b = VDEF + # a = V_MAY_DEF + # b = V_MAY_DEF *p = 5; # VUSE @@ -740,21 +749,21 @@ operands, use the @option{-vops} option to @option{-fdump-tree}: @} @end smallexample -Notice that @code{VDEF} operands have two copies of the referenced +Notice that @code{V_MAY_DEF} operands have two copies of the referenced variable. This indicates that this is not a killing definition of that variable. In this case we refer to it as a @dfn{may definition} or @dfn{aliased store}. The presence of the second copy of the -variable in the @code{VDEF} operand will become important when the +variable in the @code{V_MAY_DEF} operand will become important when the function is converted into SSA form. This will be used to link all the non-killing definitions to prevent optimizations from making incorrect assumptions about them. Operands are collected by @file{tree-ssa-operands.c}. They are stored inside each statement's annotation and can be accessed with -@code{DEF_OPS}, @code{USE_OPS}, @code{VDEF_OPS} and @code{VUSE_OPS}. -The following are all the accessor macros available to access USE -operands. To access all the other operand arrays, just change the -name accordingly: +@code{DEF_OPS}, @code{USE_OPS}, @code{V_MAY_DEF_OPS}, +@code{V_MUST_DEF_OPS} and @code{VUSE_OPS}. The following are all the +accessor macros available to access USE operands. To access all the +other operand arrays, just change the name accordingly: @defmac USE_OPS (@var{ann}) Returns the array of operands used by the statement with annotation @@ -786,7 +795,8 @@ void print_ops (tree stmt) @{ vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; def_optype defs; use_optype uses; stmt_ann_t ann; @@ -803,9 +813,13 @@ print_ops (tree stmt) for (i = 0; i < NUM_USES (uses); i++) print_generic_expr (stderr, USE_OP (uses, i), 0); - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) - print_generic_expr (stderr, VDEF_OP (vdefs, i), 0); + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) + print_generic_expr (stderr, V_MAY_DEF_OP (v_may_defs, i), 0); + + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, i), 0); vuses = VUSE_OPS (ann); for (i = 0; i < NUM_VUSES (vuses); i++) @@ -1095,11 +1109,11 @@ foo (int i) p_6 = &b; # p_1 = PHI ; - # a_7 = VDEF ; - # b_8 = VDEF ; + # a_7 = V_MAY_DEF ; + # b_8 = V_MAY_DEF ; *p_1 = 3; - # a_9 = VDEF + # a_9 = V_MAY_DEF # VUSE a_9 = b_8 + 2; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8e856429774..b8514dc0cd9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2004-06-10 Brian Booth + + * gcc.dg/tree-ssa/20031015-1.c: Scan for + V_MAY_DEF instead of VDEF. + * gcc.dg/tree-ssa/20040517-1.c: Ditto. + 2004-06-10 Tobias Schlueter PR fortran/14957 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c index 62772b7b939..74109e1c451 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20031015-1.c @@ -13,4 +13,4 @@ main(void) return 0; } -/* { dg-final { scan-tree-dump-times "VDEF" 2 "alias" } } */ +/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 2 "alias" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c index c38f1b360f1..d3d0100a02c 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/20040517-1.c @@ -16,5 +16,5 @@ void bar (void) malloc functions may clobber global memory. Only the function result does not alias any other pointer. Hence, we must have a VDEF for a before and after the call to foo(). */ -/* { dg-final { scan-tree-dump-times "VDEF" 2 "ssa"} } */ +/* { dg-final { scan-tree-dump-times "V_MAY_DEF" 1 "ssa"} } */ diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 00d008fbaaf..3bcf1d525c9 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -59,8 +59,9 @@ struct dfa_stats_d long num_phis; long num_phi_args; int max_num_phi_args; - long num_vdefs; + long num_v_may_defs; long num_vuses; + long num_v_must_defs; }; @@ -280,7 +281,7 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) size_t i; use_optype uses; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; stmt_ann_t ann; #ifdef ENABLE_CHECKING @@ -314,10 +315,10 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) add_immediate_use (imm_rdef_stmt, stmt); } - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree vuse = VDEF_OP (vdefs, i); + tree vuse = V_MAY_DEF_OP (v_may_defs, i); tree imm_rdef_stmt = SSA_NAME_DEF_STMT (vuse); if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (vuse))) add_immediate_use (imm_rdef_stmt, stmt); @@ -390,7 +391,7 @@ redirect_immediate_uses (tree old, tree new) stmt_ann_t ann = get_stmt_ann (old); use_optype uses = USE_OPS (ann); vuse_optype vuses = VUSE_OPS (ann); - vdef_optype vdefs = VDEF_OPS (ann); + v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann); unsigned int i; /* Look at USE_OPS or VUSE_OPS according to FLAGS. */ @@ -400,8 +401,8 @@ redirect_immediate_uses (tree old, tree new) for (i = 0; i < NUM_VUSES (vuses); i++) redirect_immediate_use (VUSE_OP (vuses, i), old, new); - for (i = 0; i < NUM_VDEFS (vdefs); i++) - redirect_immediate_use (VDEF_OP (vdefs, i), old, new); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) + redirect_immediate_use (V_MAY_DEF_OP (v_may_defs, i), old, new); } @@ -699,9 +700,14 @@ dump_dfa_stats (FILE *file) fprintf (file, fmt_str_1, "VUSE operands", dfa_stats.num_vuses, SCALE (size), LABEL (size)); - size = dfa_stats.num_vdefs * sizeof (tree *); + size = dfa_stats.num_v_may_defs * sizeof (tree *); total += size; - fprintf (file, fmt_str_1, "VDEF operands", dfa_stats.num_vdefs, + fprintf (file, fmt_str_1, "V_MAY_DEF operands", dfa_stats.num_v_may_defs, + SCALE (size), LABEL (size)); + + size = dfa_stats.num_v_must_defs * sizeof (tree *); + total += size; + fprintf (file, fmt_str_1, "V_MUST_DEF operands", dfa_stats.num_v_must_defs, SCALE (size), LABEL (size)); size = dfa_stats.num_phis * sizeof (struct tree_phi_node); @@ -797,8 +803,11 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, dfa_stats_p->num_stmt_anns++; dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann)); dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann)); - dfa_stats_p->num_vdefs += NUM_VDEFS (VDEF_OPS (ann)); + dfa_stats_p->num_v_may_defs += + NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)); dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann)); + dfa_stats_p->num_v_must_defs += + NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)); break; } @@ -1012,21 +1021,43 @@ add_referenced_tmp_var (tree var) add_referenced_var (var, NULL); } +/* Return true if V_MAY_DEFS_AFTER contains fewer entries than + V_MAY_DEFS_BEFORE. Note that this assumes that both varrays + are V_MAY_DEF operands for the same statement. */ + +static inline bool +v_may_defs_disappeared_p (v_may_def_optype v_may_defs_before, + v_may_def_optype v_may_defs_after) +{ + /* If there was nothing before, nothing could've disappeared. */ + if (v_may_defs_before == NULL) + return false; + + /* All/some of them gone. */ + if (v_may_defs_after == NULL + || NUM_V_MAY_DEFS (v_may_defs_before) > + NUM_V_MAY_DEFS (v_may_defs_after)) + return true; + + return false; +} -/* Return true if VDEFS_AFTER contains fewer entries than VDEFS_BEFORE. - Note that this assumes that both varrays are VDEF operands for the same - statement. */ +/* Return true if V_MUST_DEFS_AFTER contains fewer entries than + V_MUST_DEFS_BEFORE. Note that this assumes that both varrays + are V_MUST_DEF operands for the same statement. */ static inline bool -vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after) +v_must_defs_disappeared_p (v_must_def_optype v_must_defs_before, + v_must_def_optype v_must_defs_after) { /* If there was nothing before, nothing could've disappeared. */ - if (vdefs_before == NULL) + if (v_must_defs_before == NULL) return false; /* All/some of them gone. */ - if (vdefs_after == NULL - || NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after)) + if (v_must_defs_after == NULL + || NUM_V_MUST_DEFS (v_must_defs_before) > + NUM_V_MUST_DEFS (v_must_defs_after)) return true; return false; @@ -1041,12 +1072,14 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) { def_optype defs; use_optype uses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; vuse_optype vuses; + v_must_def_optype v_must_defs; size_t i; bitmap vars_in_vops_to_rename; bool found_exposed_symbol = false; - vdef_optype vdefs_before, vdefs_after; + v_may_def_optype v_may_defs_before, v_may_defs_after; + v_must_def_optype v_must_defs_before, v_must_defs_after; stmt_ann_t ann; vars_in_vops_to_rename = BITMAP_XMALLOC (); @@ -1061,10 +1094,10 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) rename them if there are not any newly exposed symbols in the statement operands. */ ann = stmt_ann (stmt); - vdefs_before = vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs_before = v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree var = VDEF_RESULT (vdefs, i); + tree var = V_MAY_DEF_RESULT (v_may_defs, i); if (!DECL_P (var)) var = SSA_NAME_VAR (var); bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid); @@ -1079,6 +1112,15 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid); } + v_must_defs_before = v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree var = V_MUST_DEF_OP (v_must_defs, i); + if (!DECL_P (var)) + var = SSA_NAME_VAR (var); + bitmap_set_bit (vars_in_vops_to_rename, var_ann (var)->uid); + } + /* Now force an operand re-scan on the statement and mark any newly exposed variables. */ modify_stmt (stmt); @@ -1106,10 +1148,10 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) } } - vdefs_after = vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs_after = v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree var = VDEF_RESULT (vdefs, i); + tree var = V_MAY_DEF_RESULT (v_may_defs, i); if (DECL_P (var)) { found_exposed_symbol = true; @@ -1127,6 +1169,17 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) bitmap_set_bit (vars_to_rename, var_ann (var)->uid); } } + + v_must_defs_after = v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree var = V_MUST_DEF_OP (v_must_defs, i); + if (DECL_P (var)) + { + found_exposed_symbol = true; + bitmap_set_bit (vars_to_rename, var_ann (var)->uid); + } + } /* If we found any newly exposed symbols, or if there are fewer VDEF operands in the statement, add the variables we had set in @@ -1134,7 +1187,8 @@ mark_new_vars_to_rename (tree stmt, bitmap vars_to_rename) vanishing VDEFs because in those cases, the names that were formerly generated by this statement are not going to be available anymore. */ if (found_exposed_symbol - || vdefs_disappeared_p (vdefs_before, vdefs_after)) + || v_may_defs_disappeared_p (v_may_defs_before, v_may_defs_after) + || v_must_defs_disappeared_p (v_must_defs_before, v_must_defs_after)) bitmap_a_or_b (vars_to_rename, vars_to_rename, vars_in_vops_to_rename); BITMAP_XFREE (vars_in_vops_to_rename); diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 5ef287abff4..4bb5e41d318 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -172,10 +172,10 @@ get_use_ops (stmt_ann_t ann) return ann ? ann->use_ops : NULL; } -static inline vdef_optype -get_vdef_ops (stmt_ann_t ann) +static inline v_may_def_optype +get_v_may_def_ops (stmt_ann_t ann) { - return ann ? ann->vdef_ops : NULL; + return ann ? ann->v_may_def_ops : NULL; } static inline vuse_optype @@ -184,6 +184,12 @@ get_vuse_ops (stmt_ann_t ann) return ann ? ann->vuse_ops : NULL; } +static inline v_must_def_optype +get_v_must_def_ops (stmt_ann_t ann) +{ + return ann ? ann->v_must_def_ops : NULL; +} + static inline tree * get_use_op_ptr (use_optype uses, unsigned int index) { @@ -205,23 +211,23 @@ get_def_op_ptr (def_optype defs, unsigned int index) } static inline tree * -get_vdef_result_ptr(vdef_optype vdefs, unsigned int index) +get_v_may_def_result_ptr(v_may_def_optype v_may_defs, unsigned int index) { #ifdef ENABLE_CHECKING - if (index >= vdefs->num_vdefs) + if (index >= v_may_defs->num_v_may_defs) abort(); #endif - return &(vdefs->vdefs[index * 2]); + return &(v_may_defs->v_may_defs[index * 2]); } static inline tree * -get_vdef_op_ptr(vdef_optype vdefs, unsigned int index) +get_v_may_def_op_ptr(v_may_def_optype v_may_defs, unsigned int index) { #ifdef ENABLE_CHECKING - if (index >= vdefs->num_vdefs) + if (index >= v_may_defs->num_v_may_defs) abort(); #endif - return &(vdefs->vdefs[index * 2 + 1]); + return &(v_may_defs->v_may_defs[index * 2 + 1]); } static inline tree * @@ -234,6 +240,16 @@ get_vuse_op_ptr(vuse_optype vuses, unsigned int index) return &(vuses->vuses[index]); } +static inline tree * +get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index) +{ +#ifdef ENABLE_CHECKING + if (index >= v_must_defs->num_v_must_defs) + abort(); +#endif + return &(v_must_defs->v_must_defs[index]); +} + static inline void start_ssa_stmt_operands (tree stmt ATTRIBUTE_UNUSED) { diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index 41701e333f9..57271113e01 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -238,9 +238,10 @@ struct stmt_ann_d GTY(()) struct def_optype_d * GTY (()) def_ops; struct use_optype_d * GTY (()) use_ops; - /* Virtual operands (VDEF and VUSE). */ - struct vdef_optype_d * GTY (()) vdef_ops; + /* Virtual operands (V_MAY_DEF, VUSE, and V_MUST_DEF). */ + struct v_may_def_optype_d * GTY (()) v_may_def_ops; struct vuse_optype_d * GTY (()) vuse_ops; + struct v_must_def_optype_d * GTY (()) v_must_def_ops; /* Dataflow information. */ dataflow_t df; @@ -281,7 +282,7 @@ static inline int get_lineno (tree); static inline const char *get_filename (tree); static inline bool is_exec_stmt (tree); static inline bool is_label_stmt (tree); -static inline vdef_optype get_vdef_ops (stmt_ann_t); +static inline v_may_def_optype get_v_may_def_ops (stmt_ann_t); static inline vuse_optype get_vuse_ops (stmt_ann_t); static inline use_optype get_use_ops (stmt_ann_t); static inline def_optype get_def_ops (stmt_ann_t); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 7bb9c58f046..e07258a2894 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -211,7 +211,8 @@ mark_def_sites (struct dom_walk_data *walk_data, { struct mark_def_sites_global_data *gd = walk_data->global_data; sbitmap kills = gd->kills; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; vuse_optype vuses; def_optype defs; use_optype uses; @@ -248,22 +249,36 @@ mark_def_sites (struct dom_walk_data *walk_data, } /* Note that virtual definitions are irrelevant for computing KILLS - because a VDEF does not constitute a killing definition of the + because a V_MAY_DEF does not constitute a killing definition of the variable. However, the operand of a virtual definitions is a use of the variable, so it may cause the variable to be considered live-on-entry. */ - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - if (prepare_operand_for_rename (VDEF_OP_PTR (vdefs, i), &uid, true)) + if (prepare_operand_for_rename (V_MAY_DEF_OP_PTR (v_may_defs, i), + &uid, true)) { /* If we do not already have an SSA_NAME for our destination, then set the destination to the source. */ - if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME) - VDEF_RESULT (vdefs, i) = VDEF_OP (vdefs, i); + if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) + V_MAY_DEF_RESULT (v_may_defs, i) = V_MAY_DEF_OP (v_may_defs, i); + + set_livein_block (V_MAY_DEF_OP (v_may_defs, i), bb); + set_def_block (V_MAY_DEF_RESULT (v_may_defs, i), bb); + } + } + + /* Now process the virtual must-defs made by this statement. */ + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree *def_p = V_MUST_DEF_OP_PTR (v_must_defs, i); - set_livein_block (VDEF_OP (vdefs, i), bb); - set_def_block (VDEF_RESULT (vdefs, i), bb); + if (prepare_operand_for_rename (def_p, &uid, false)) + { + set_def_block (*def_p, bb); + SET_BIT (kills, uid); } } @@ -717,7 +732,8 @@ rewrite_stmt (struct dom_walk_data *walk_data, stmt_ann_t ann; tree stmt; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; def_optype defs; use_optype uses; struct rewrite_block_data *bd; @@ -744,7 +760,8 @@ rewrite_stmt (struct dom_walk_data *walk_data, defs = DEF_OPS (ann); uses = USE_OPS (ann); vuses = VUSE_OPS (ann); - vdefs = VDEF_OPS (ann); + v_may_defs = V_MAY_DEF_OPS (ann); + v_must_defs = V_MUST_DEF_OPS (ann); /* Step 1. Rewrite USES and VUSES in the statement. */ for (i = 0; i < NUM_USES (uses); i++) @@ -768,18 +785,32 @@ rewrite_stmt (struct dom_walk_data *walk_data, } /* Register new virtual definitions made by the statement. */ - for (i = 0; i < NUM_VDEFS (vdefs); i++) + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - rewrite_operand (VDEF_OP_PTR (vdefs, i)); + rewrite_operand (V_MAY_DEF_OP_PTR (v_may_defs, i)); - if (TREE_CODE (VDEF_RESULT (vdefs, i)) != SSA_NAME) - *VDEF_RESULT_PTR (vdefs, i) - = make_ssa_name (VDEF_RESULT (vdefs, i), stmt); + if (TREE_CODE (V_MAY_DEF_RESULT (v_may_defs, i)) != SSA_NAME) + *V_MAY_DEF_RESULT_PTR (v_may_defs, i) + = make_ssa_name (V_MAY_DEF_RESULT (v_may_defs, i), stmt); /* FIXME: We shouldn't be registering new defs if the variable doesn't need to be renamed. */ - register_new_def (VDEF_RESULT (vdefs, i), &bd->block_defs); + register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), &bd->block_defs); + } + + /* Register new virtual mustdefs made by the statement. */ + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree *v_must_def_p = V_MUST_DEF_OP_PTR (v_must_defs, i); + + if (TREE_CODE (*v_must_def_p) != SSA_NAME) + *v_must_def_p = make_ssa_name (*v_must_def_p, stmt); + + /* FIXME: We shouldn't be registering new mustdefs if the variable + doesn't need to be renamed. */ + register_new_def (*v_must_def_p, &bd->block_defs); } + } diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 03c43917f61..eee24c4a7b8 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -1134,8 +1134,8 @@ coalesce_vars (var_map map, tree_live_info_p liveinfo) dependent on any virtual variable (via a VUSE) has a dependence added to the special partition defined by VIRTUAL_PARTITION. - Whenever a VDEF is seen, all expressions dependent this VIRTUAL_PARTITION - are removed from consideration. + Whenever a V_MAY_DEF is seen, all expressions dependent this + VIRTUAL_PARTITION are removed from consideration. At the end of a basic block, all expression are removed from consideration in preparation for the next block. @@ -1171,7 +1171,7 @@ typedef struct temp_expr_table_d value_expr_p pending_dependence; } *temp_expr_table_p; -/* Used to indicate a dependancy on VDEFs. */ +/* Used to indicate a dependancy on V_MAY_DEFs. */ #define VIRTUAL_PARTITION(table) (table->virtual_partition) static temp_expr_table_p new_temp_expr_table (var_map); @@ -1437,8 +1437,12 @@ check_replaceable (temp_expr_table_p tab, tree stmt) if (DECL_HARD_REGISTER (SSA_NAME_VAR (def))) return false; - /* There must be no VDEFS. */ - if (NUM_VDEFS (VDEF_OPS (ann)) != 0) + /* There must be no V_MAY_DEFS. */ + if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0) + return false; + + /* There must be no V_MUST_DEFS. */ + if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0) return false; /* Float expressions must go through memory if float-store is on. */ @@ -1646,8 +1650,12 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) free_value_expr (tab, p); } - /* A VDEF kills any expression using a virtual operand. */ - if (NUM_VDEFS (VDEF_OPS (ann)) > 0) + /* A V_MAY_DEF kills any expression using a virtual operand. */ + if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0) + kill_virtual_exprs (tab, true); + + /* A V_MUST_DEF kills any expression using a virtual operand. */ + if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0) kill_virtual_exprs (tab, true); } } diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c index d5566b822bf..b550fc9870d 100644 --- a/gcc/tree-pretty-print.c +++ b/gcc/tree-pretty-print.c @@ -2061,15 +2061,27 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) { size_t i; stmt_ann_t ann = stmt_ann (stmt); - vdef_optype vdefs = VDEF_OPS (ann); + v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann); + v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann); vuse_optype vuses = VUSE_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { pp_string (buffer, "# "); - dump_generic_node (buffer, VDEF_RESULT (vdefs, i), spc + 2, flags, false); - pp_string (buffer, " = VDEF <"); - dump_generic_node (buffer, VDEF_OP (vdefs, i), spc + 2, flags, false); + dump_generic_node (buffer, V_MAY_DEF_RESULT (v_may_defs, i), + spc + 2, flags, false); + pp_string (buffer, " = V_MAY_DEF <"); + dump_generic_node (buffer, V_MAY_DEF_OP (v_may_defs, i), + spc + 2, flags, false); + pp_string (buffer, ">;"); + newline_and_indent (buffer, spc); + } + + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree v_must_def = V_MUST_DEF_OP (v_must_defs, i); + pp_string (buffer, "# V_MUST_DEF <"); + dump_generic_node (buffer, v_must_def, spc + 2, flags, false); pp_string (buffer, ">;"); newline_and_indent (buffer, spc); } diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 4f1bbcdd12e..219c8148985 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -112,22 +112,42 @@ sra_elt_eq (const void *x, const void *y) return true; } -/* Mark all the variables in VDEF operands for STMT for renaming. +/* Mark all the variables in V_MAY_DEF operands for STMT for renaming. This becomes necessary when we modify all of a non-scalar. */ static void -mark_all_vdefs (tree stmt) +mark_all_v_may_defs (tree stmt) { - vdef_optype vdefs; + v_may_def_optype v_may_defs; size_t i, n; get_stmt_operands (stmt); - vdefs = VDEF_OPS (stmt_ann (stmt)); - n = NUM_VDEFS (vdefs); + v_may_defs = V_MAY_DEF_OPS (stmt_ann (stmt)); + n = NUM_V_MAY_DEFS (v_may_defs); for (i = 0; i < n; i++) { - tree sym = VDEF_RESULT (vdefs, i); + tree sym = V_MAY_DEF_RESULT (v_may_defs, i); + bitmap_set_bit (vars_to_rename, var_ann (sym)->uid); + } +} + +/* Mark all the variables in V_MUST_DEF operands for STMT for renaming. + This becomes necessary when we modify all of a non-scalar. */ + +static void +mark_all_v_must_defs (tree stmt) +{ + v_must_def_optype v_must_defs; + size_t i, n; + + get_stmt_operands (stmt); + v_must_defs = V_MUST_DEF_OPS (stmt_ann (stmt)); + n = NUM_V_MUST_DEFS (v_must_defs); + + for (i = 0; i < n; i++) + { + tree sym = V_MUST_DEF_OP (v_must_defs, i); bitmap_set_bit (vars_to_rename, var_ann (sym)->uid); } } @@ -685,7 +705,8 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode) /* Mark all the variables in VDEF operands for renaming, because the VA_ARG_EXPR will now be in a different statement. */ - mark_all_vdefs (stmt); + mark_all_v_may_defs (stmt); + mark_all_v_must_defs (stmt); /* Set RHS to be the new temporary TMP. */ rhs = tmp; @@ -784,7 +805,8 @@ create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode) /* Otherwise, mark all the symbols in the VDEFs for the last scalarized statement just created. Since all the statements introduce the same VDEFs, we only need to check the last one. */ - mark_all_vdefs (tsi_stmt (tsi)); + mark_all_v_may_defs (tsi_stmt (tsi)); + mark_all_v_must_defs (tsi_stmt (tsi)); } else abort (); @@ -830,8 +852,9 @@ scalarize_structures (void) /* If the statement has no virtual operands, then it doesn't make structure references that we care about. */ - if (NUM_VDEFS (VDEF_OPS (ann)) == 0 - && NUM_VUSES (VUSE_OPS (ann)) == 0) + if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0 + && NUM_VUSES (VUSE_OPS (ann)) == 0 + && NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0) continue; /* Structure references may only appear in certain statements. */ @@ -899,17 +922,17 @@ scalarize_modify_expr (block_stmt_iterator *si_p) if (is_sra_candidate_ref (lhs, false)) { tree sym; - vdef_optype vdefs; + v_may_def_optype v_may_defs; scalarize_component_ref (stmt, &TREE_OPERAND (stmt, 0)); /* Mark the LHS to be renamed, as we have just removed the previous - VDEF for AGGREGATE. The statement should have exactly one VDEF - for variable AGGREGATE. */ - vdefs = STMT_VDEF_OPS (stmt); - if (NUM_VDEFS (vdefs) != 1) + V_MAY_DEF for AGGREGATE. The statement should have exactly one + V_MAY_DEF for variable AGGREGATE. */ + v_may_defs = STMT_V_MAY_DEF_OPS (stmt); + if (NUM_V_MAY_DEFS (v_may_defs) != 1) abort (); - sym = SSA_NAME_VAR (VDEF_RESULT (vdefs, 0)); + sym = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, 0)); bitmap_set_bit (vars_to_rename, var_ann (sym)->uid); } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 1fa94c3771c..e980aa2d3a7 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -174,7 +174,7 @@ bool aliases_computed_p; this variable is used to represent the clobbering effects of function calls. In these cases, all the call clobbered variables in the program are forced to alias this variable. This reduces compile times by not - having to keep track of too many VDEF expressions at call sites. */ + having to keep track of too many V_MAY_DEF expressions at call sites. */ tree global_var; @@ -264,11 +264,11 @@ tree global_var; p_6 = &b; # p_1 = PHI ; - # a_7 = VDEF ; - # b_8 = VDEF ; + # a_7 = V_MAY_DEF ; + # b_8 = V_MAY_DEF ; *p_1 = 3; - # a_9 = VDEF + # a_9 = V_MAY_DEF # VUSE a_9 = b_8 + 2; @@ -536,7 +536,8 @@ compute_points_to_and_addr_escape (struct alias_info *ai) { use_optype uses; def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; stmt_ann_t ann; bitmap addr_taken; tree stmt = bsi_stmt (si); @@ -658,11 +659,21 @@ compute_points_to_and_addr_escape (struct alias_info *ai) (VARRAY_UINT (ai->num_references, ann->uid))++; } - /* Mark variables in VDEF operands as being written to. */ - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + /* Mark variables in V_MAY_DEF operands as being written to. */ + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree op = VDEF_OP (vdefs, i); + tree op = V_MAY_DEF_OP (v_may_defs, i); + tree var = SSA_NAME_VAR (op); + var_ann_t ann = var_ann (var); + bitmap_set_bit (ai->written_vars, ann->uid); + } + + /* Mark variables in V_MUST_DEF operands as being written to. */ + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree op = V_MUST_DEF_OP (v_must_defs, i); tree var = SSA_NAME_VAR (op); var_ann_t ann = var_ann (var); bitmap_set_bit (ai->written_vars, ann->uid); @@ -1040,7 +1051,7 @@ group_aliases (struct alias_info *ai) p_5 = &a; ... - # a_9 = VDEF + # a_9 = V_MAY_DEF p_5->field = 0 ... Several modifications to TMT.20 ... # VUSE @@ -1273,8 +1284,8 @@ setup_pointers_and_addressables (struct alias_info *ai) } -/* Determine whether to use .GLOBAL_VAR to model call clobbering semantics. At - every call site, we need to emit VDEF expressions to represent the +/* Determine whether to use .GLOBAL_VAR to model call clobbering semantics. At + every call site, we need to emit V_MAY_DEF expressions to represent the clobbering effects of the call for variables whose address escapes the current function. @@ -1283,10 +1294,11 @@ setup_pointers_and_addressables (struct alias_info *ai) (.GLOBAL_VAR). This works well, but it ties the optimizer hands because references to any call clobbered variable is a reference to .GLOBAL_VAR. - The second approach is to emit a clobbering VDEF for every call-clobbered - variable at call sites. This is the preferred way in terms of optimization - opportunities but it may create too many VDEF operands if there are many - call clobbered variables and function calls in the function. + The second approach is to emit a clobbering V_MAY_DEF for every + call-clobbered variable at call sites. This is the preferred way in terms + of optimization opportunities but it may create too many V_MAY_DEF operands + if there are many call clobbered variables and function calls in the + function. To decide whether or not to use .GLOBAL_VAR we multiply the number of function calls found by the number of call-clobbered variables. If that diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index ab7de37ab4c..4f5612b6f07 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -610,7 +610,8 @@ visit_stmt (tree stmt) size_t i; stmt_ann_t ann; def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; /* If the statement has already been deemed to be VARYING, don't simulate it again. */ @@ -669,10 +670,15 @@ visit_stmt (tree stmt) add_outgoing_control_edges (bb_for_stmt (stmt)); } - /* Mark all VDEF operands VARYING. */ - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) - def_to_varying (VDEF_RESULT (vdefs, i)); + /* Mark all V_MAY_DEF operands VARYING. */ + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) + def_to_varying (V_MAY_DEF_RESULT (v_may_defs, i)); + + /* Mark all V_MUST_DEF operands VARYING. */ + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + def_to_varying (V_MUST_DEF_OP (v_must_defs, i)); } @@ -1129,7 +1135,8 @@ initialize (void) tree stmt; stmt_ann_t ann; def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; size_t x; int vary; @@ -1149,14 +1156,23 @@ initialize (void) } DONT_SIMULATE_AGAIN (stmt) = vary; - /* Mark all VDEF operands VARYING. */ - vdefs = VDEF_OPS (ann); - for (x = 0; x < NUM_VDEFS (vdefs); x++) + /* Mark all V_MAY_DEF operands VARYING. */ + v_may_defs = V_MAY_DEF_OPS (ann); + for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++) { - tree res = VDEF_RESULT (vdefs, x); + tree res = V_MAY_DEF_RESULT (v_may_defs, x); get_value (res)->lattice_val = VARYING; SET_BIT (virtual_var, SSA_NAME_VERSION (res)); } + + /* Mark all V_MUST_DEF operands VARYING. */ + v_must_defs = V_MUST_DEF_OPS (ann); + for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++) + { + tree v_must_def = V_MUST_DEF_OP (v_must_defs, x); + get_value (v_must_def)->lattice_val = VARYING; + SET_BIT (virtual_var, SSA_NAME_VERSION (v_must_def)); + } } for (e = bb->succ; e; e = e->succ_next) @@ -2064,7 +2080,8 @@ set_rhs (tree *stmt_p, tree expr) if (TREE_SIDE_EFFECTS (expr)) { def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; size_t i; /* Fix all the SSA_NAMEs created by *STMT_P to point to its new @@ -2077,10 +2094,18 @@ set_rhs (tree *stmt_p, tree expr) SSA_NAME_DEF_STMT (var) = *stmt_p; } - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) + { + tree var = V_MAY_DEF_RESULT (v_may_defs, i); + if (TREE_CODE (var) == SSA_NAME) + SSA_NAME_DEF_STMT (var) = *stmt_p; + } + + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) { - tree var = VDEF_RESULT (vdefs, i); + tree var = V_MUST_DEF_OP (v_must_defs, i); if (TREE_CODE (var) == SSA_NAME) SSA_NAME_DEF_STMT (var) = *stmt_p; } diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index 688116113b1..753a6772ea0 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -225,16 +225,16 @@ cprop_operand (stmt_ann_t ann, tree *op_p, varray_type const_and_copies) known value for that SSA_NAME (or NULL if no value is known). Propagate values from CONST_AND_COPIES into the uses, vuses and - vdef_ops of STMT. */ + v_may_def_ops of STMT. */ bool cprop_into_stmt (tree stmt, varray_type const_and_copies) { bool may_have_exposed_new_symbols = false; stmt_ann_t ann = stmt_ann (stmt); - size_t i, num_uses, num_vuses, num_vdefs; + size_t i, num_uses, num_vuses, num_v_may_defs; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; use_optype uses; uses = USE_OPS (ann); @@ -257,11 +257,11 @@ cprop_into_stmt (tree stmt, varray_type const_and_copies) |= cprop_operand (ann, op_p, const_and_copies); } - vdefs = VDEF_OPS (ann); - num_vdefs = NUM_VDEFS (vdefs); - for (i = 0; i < num_vdefs; i++) + v_may_defs = V_MAY_DEF_OPS (ann); + num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs); + for (i = 0; i < num_v_may_defs; i++) { - tree *op_p = VDEF_OP_PTR (vdefs, i); + tree *op_p = V_MAY_DEF_OP_PTR (v_may_defs, i); if (TREE_CODE (*op_p) == SSA_NAME) may_have_exposed_new_symbols |= cprop_operand (ann, op_p, const_and_copies); diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 7921a9f0cf6..90bcf211612 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -286,7 +286,8 @@ static void mark_stmt_if_obviously_necessary (tree stmt, bool aggressive) { def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; stmt_ann_t ann; size_t i; @@ -387,11 +388,22 @@ mark_stmt_if_obviously_necessary (tree stmt, bool aggressive) } } - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree vdef = VDEF_RESULT (vdefs, i); - if (need_to_preserve_store (vdef)) + tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i); + if (need_to_preserve_store (v_may_def)) + { + mark_stmt_necessary (stmt, true); + return; + } + } + + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + tree v_must_def = V_MUST_DEF_OP (v_must_defs, i); + if (need_to_preserve_store (v_must_def)) { mark_stmt_necessary (stmt, true); return; @@ -558,10 +570,10 @@ propagate_necessity (struct edge_list *el) else { /* Propagate through the operands. Examine all the USE, VUSE and - VDEF operands in this statement. Mark all the statements which - feed this statement's uses as necessary. */ + V_MAY_DEF operands in this statement. Mark all the statements + which feed this statement's uses as necessary. */ vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; use_optype uses; stmt_ann_t ann; size_t k; @@ -577,12 +589,13 @@ propagate_necessity (struct edge_list *el) for (k = 0; k < NUM_VUSES (vuses); k++) mark_operand_necessary (VUSE_OP (vuses, k)); - /* The operands of VDEF expressions are also needed as they + /* The operands of V_MAY_DEF expressions are also needed as they represent potential definitions that may reach this - statement (VDEF operands allow us to follow def-def links). */ - vdefs = VDEF_OPS (ann); - for (k = 0; k < NUM_VDEFS (vdefs); k++) - mark_operand_necessary (VDEF_OP (vdefs, k)); + statement (V_MAY_DEF operands allow us to follow def-def + links). */ + v_may_defs = V_MAY_DEF_OPS (ann); + for (k = 0; k < NUM_V_MAY_DEFS (v_may_defs); k++) + mark_operand_necessary (V_MAY_DEF_OP (v_may_defs, k)); } } } diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 5b311631067..688de2a2d48 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -347,7 +347,8 @@ redirect_edges_and_update_ssa_graph (varray_type redirection_edges) { unsigned int j; def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; tree stmt = bsi_stmt (bsi); stmt_ann_t ann = stmt_ann (stmt); @@ -363,11 +364,18 @@ redirect_edges_and_update_ssa_graph (varray_type redirection_edges) bitmap_set_bit (vars_to_rename, var_ann (op)->uid); } - vdefs = VDEF_OPS (ann); - for (j = 0; j < NUM_VDEFS (vdefs); j++) + v_may_defs = STMT_V_MAY_DEF_OPS (stmt); + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree op = VDEF_RESULT (vdefs, j); - bitmap_set_bit (virtuals_to_rename, var_ann (op)->uid); + tree op = V_MAY_DEF_RESULT (v_may_defs, j); + bitmap_set_bit (vars_to_rename, var_ann (op)->uid); + } + + v_must_defs = STMT_V_MUST_DEF_OPS (stmt); + for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++) + { + tree op = V_MUST_DEF_OP (v_must_defs, j); + bitmap_set_bit (vars_to_rename, var_ann (op)->uid); } } @@ -2289,7 +2297,7 @@ static bool eliminate_redundant_computations (struct dom_walk_data *walk_data, tree stmt, stmt_ann_t ann) { - vdef_optype vdefs = VDEF_OPS (ann); + v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann); tree *expr_p, def = NULL_TREE; bool insert = true; tree cached_lhs; @@ -2306,7 +2314,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data, || ! def || TREE_CODE (def) != SSA_NAME || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) - || NUM_VDEFS (vdefs) != 0) + || NUM_V_MAY_DEFS (v_may_defs) != 0) insert = false; /* Check if the expression has been computed before. */ @@ -2511,7 +2519,8 @@ record_equivalences_from_stmt (tree stmt, if (rhs) { - vdef_optype vdefs = VDEF_OPS (ann); + v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann); + v_must_def_optype v_must_defs = V_MUST_DEF_OPS (ann); /* Build a new statement with the RHS and LHS exchanged. */ new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs); @@ -2523,14 +2532,22 @@ record_equivalences_from_stmt (tree stmt, /* Clear out the virtual operands on the new statement, we are going to set them explicitly below. */ remove_vuses (new); - remove_vdefs (new); + remove_v_may_defs (new); + remove_v_must_defs (new); start_ssa_stmt_operands (new); /* For each VDEF on the original statement, we want to create a - VUSE of the VDEF result on the new statement. */ - for (j = 0; j < NUM_VDEFS (vdefs); j++) + VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new + statement. */ + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree op = VDEF_RESULT (vdefs, j); + tree op = V_MAY_DEF_RESULT (v_may_defs, j); + add_vuse (op, new); + } + + for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++) + { + tree op = V_MUST_DEF_OP (v_must_defs, j); add_vuse (op, new); } @@ -2565,7 +2582,6 @@ optimize_stmt (struct dom_walk_data *walk_data, { stmt_ann_t ann; tree stmt; - vdef_optype vdefs; bool may_optimize_p; bool may_have_exposed_new_symbols = false; struct dom_walk_block_data *bd @@ -2575,7 +2591,6 @@ optimize_stmt (struct dom_walk_data *walk_data, get_stmt_operands (stmt); ann = stmt_ann (stmt); - vdefs = VDEF_OPS (ann); opt_stats.num_stmts++; may_have_exposed_new_symbols = false; @@ -2585,7 +2600,7 @@ optimize_stmt (struct dom_walk_data *walk_data, print_generic_stmt (dump_file, stmt, TDF_SLIM); } - /* Const/copy propagate into USES, VUSES and the RHS of VDEFs. */ + /* Const/copy propagate into USES, VUSES and the RHS of V_MAY_DEFs. */ may_have_exposed_new_symbols = cprop_into_stmt (stmt, const_and_copies); /* If the statement has been modified with constant replacements, @@ -3171,7 +3186,8 @@ static void register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p) { def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; unsigned int i; defs = DEF_OPS (ann); @@ -3185,12 +3201,21 @@ register_definitions_for_stmt (stmt_ann_t ann, varray_type *block_defs_p) } /* Register new virtual definitions made by the statement. */ - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) + { + /* FIXME: We shouldn't be registering new defs if the variable + doesn't need to be renamed. */ + register_new_def (V_MAY_DEF_RESULT (v_may_defs, i), block_defs_p); + } + + /* Register new virtual mustdefs made by the statement. */ + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) { /* FIXME: We shouldn't be registering new defs if the variable doesn't need to be renamed. */ - register_new_def (VDEF_RESULT (vdefs, i), block_defs_p); + register_new_def (V_MUST_DEF_OP (v_must_defs, i), block_defs_p); } } diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index fca08ac6519..88ca1363c87 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -95,7 +95,7 @@ static void dse_optimize_stmt (struct dom_walk_data *, static void dse_record_phis (struct dom_walk_data *, basic_block); static void dse_finalize_block (struct dom_walk_data *, basic_block); static void fix_phi_uses (tree, tree); -static void fix_stmt_vdefs (tree, tree); +static void fix_stmt_v_may_defs (tree, tree); static void record_voperand_set (bitmap, bitmap *, unsigned int); /* Function indicating whether we ought to include information for 'var' @@ -109,70 +109,71 @@ need_imm_uses_for (tree var) } -/* Replace uses in PHI which match VDEF_RESULTs in STMT with the - corresponding VDEF_OP in STMT. */ +/* Replace uses in PHI which match V_MAY_DEF_RESULTs in STMT with the + corresponding V_MAY_DEF_OP in STMT. */ static void fix_phi_uses (tree phi, tree stmt) { stmt_ann_t ann = stmt_ann (stmt); - vdef_optype vdefs; + v_may_def_optype v_may_defs; unsigned int i; int j; get_stmt_operands (stmt); - vdefs = VDEF_OPS (ann); + v_may_defs = V_MAY_DEF_OPS (ann); - /* Walk each VDEF in STMT. */ - for (i = 0; i < NUM_VDEFS (vdefs); i++) + /* Walk each V_MAY_DEF in STMT. */ + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - tree vdef = VDEF_RESULT (vdefs, i); + tree v_may_def = V_MAY_DEF_RESULT (v_may_defs, i); - /* Find any uses in the PHI which match VDEF and replace - them with the appropriate VDEF_OP. */ + /* Find any uses in the PHI which match V_MAY_DEF and replace + them with the appropriate V_MAY_DEF_OP. */ for (j = 0; j < PHI_NUM_ARGS (phi); j++) - if (vdef == PHI_ARG_DEF (phi, j)) - PHI_ARG_DEF (phi, j) = VDEF_OP (vdefs, i); + if (v_may_def == PHI_ARG_DEF (phi, j)) + PHI_ARG_DEF (phi, j) = V_MAY_DEF_OP (v_may_defs, i); } } -/* Replace the VDEF_OPs in STMT1 which match VDEF_RESULTs in STMT2 with - the appropriate VDEF_OPs from STMT2. */ +/* Replace the V_MAY_DEF_OPs in STMT1 which match V_MAY_DEF_RESULTs + in STMT2 with the appropriate V_MAY_DEF_OPs from STMT2. */ static void -fix_stmt_vdefs (tree stmt1, tree stmt2) +fix_stmt_v_may_defs (tree stmt1, tree stmt2) { stmt_ann_t ann1 = stmt_ann (stmt1); stmt_ann_t ann2 = stmt_ann (stmt2); - vdef_optype vdefs1; - vdef_optype vdefs2; + v_may_def_optype v_may_defs1; + v_may_def_optype v_may_defs2; unsigned int i, j; get_stmt_operands (stmt1); get_stmt_operands (stmt2); - vdefs1 = VDEF_OPS (ann1); - vdefs2 = VDEF_OPS (ann2); + v_may_defs1 = V_MAY_DEF_OPS (ann1); + v_may_defs2 = V_MAY_DEF_OPS (ann2); - /* Walk each VDEF_OP in stmt1. */ - for (i = 0; i < NUM_VDEFS (vdefs1); i++) + /* Walk each V_MAY_DEF_OP in stmt1. */ + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs1); i++) { - tree vdef1 = VDEF_OP (vdefs1, i); + tree v_may_def1 = V_MAY_DEF_OP (v_may_defs1, i); - /* Find the appropriate VDEF_RESULT in STMT2. */ - for (j = 0; j < NUM_VDEFS (vdefs2); j++) + /* Find the appropriate V_MAY_DEF_RESULT in STMT2. */ + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs2); j++) { - if (vdef1 == VDEF_RESULT (vdefs2, j)) + if (v_may_def1 == V_MAY_DEF_RESULT (v_may_defs2, j)) { /* Update. */ - *VDEF_OP_PTR (vdefs1, i) = VDEF_OP (vdefs2, j); + *V_MAY_DEF_OP_PTR (v_may_defs1, i) = + V_MAY_DEF_OP (v_may_defs2, j); break; } } #ifdef ENABLE_CHECKING - /* If we did not find a corresponding VDEF_RESULT, then something + /* If we did not find a corresponding V_MAY_DEF_RESULT, then something has gone terribly wrong. */ - if (j == NUM_VDEFS (vdefs2)) + if (j == NUM_V_MAY_DEFS (v_may_defs2)) abort (); #endif @@ -234,14 +235,14 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, struct dse_global_data *dse_gd = walk_data->global_data; tree stmt = bsi_stmt (bsi); stmt_ann_t ann = stmt_ann (stmt); - vdef_optype vdefs; + v_may_def_optype v_may_defs; get_stmt_operands (stmt); - vdefs = VDEF_OPS (ann); + v_may_defs = V_MAY_DEF_OPS (ann); /* If this statement has no virtual uses, then there is nothing to do. */ - if (NUM_VDEFS (vdefs) == 0) + if (NUM_V_MAY_DEFS (v_may_defs) == 0) return; /* We know we have virtual definitions. If this is a MODIFY_EXPR, then @@ -269,7 +270,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, represents the only use of this store. Note this does not handle the case where the store has - multiple VDEFs which all reach a set of PHI nodes in the + multiple V_MAY_DEFs which all reach a set of PHI nodes in the same block. */ while (num_uses == 1 && TREE_CODE (use) == PHI_NODE @@ -300,7 +301,7 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, if (skipped_phi) fix_phi_uses (skipped_phi, stmt); else - fix_stmt_vdefs (use, stmt); + fix_stmt_v_may_defs (use, stmt); if (dump_file && (dump_flags & TDF_DETAILS)) { diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index f61aed2b799..388e2e37cc6 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -298,7 +298,8 @@ create_ssa_var_map (int flags) tree stmt; stmt_ann_t ann; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; use_optype uses; def_optype defs; unsigned x; @@ -383,16 +384,26 @@ create_ssa_var_map (int flags) #endif } - vdefs = VDEF_OPS (ann); - for (x = 0; x < NUM_VDEFS (vdefs); x++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (x = 0; x < NUM_V_MAY_DEFS (v_may_defs); x++) { - tree var = VDEF_OP (vdefs, x); + tree var = V_MAY_DEF_OP (v_may_defs, x); set_is_used (var); #if defined ENABLE_CHECKING SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid); #endif } + + v_must_defs = V_MUST_DEF_OPS (ann); + for (x = 0; x < NUM_V_MUST_DEFS (v_must_defs); x++) + { + tree var = V_MUST_DEF_OP (v_must_defs, x); + set_is_used (var); +#if defined ENABLE_CHECKING + SET_BIT (used_in_virtual_ops, var_ann (SSA_NAME_VAR (var))->uid); +#endif + } } } diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 58ee74623a0..bbcba9c98db 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -104,8 +104,9 @@ mark_defs_for_rewrite (basic_block bb) block_stmt_iterator bsi; stmt_ann_t ann; def_optype defs; - vdef_optype vdefs; + v_may_def_optype v_may_defs; vuse_optype vuses; + v_must_def_optype v_must_defs; unsigned i; for (stmt = phi_nodes (bb); stmt; stmt = TREE_CHAIN (stmt)) @@ -141,16 +142,23 @@ mark_defs_for_rewrite (basic_block bb) bitmap_set_bit (vars_to_rename, var_ann (var)->uid); } - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - var = SSA_NAME_VAR (VDEF_RESULT (vdefs, i)); + var = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i)); + bitmap_set_bit (vars_to_rename, var_ann (var)->uid); + } + + v_must_defs = V_MUST_DEF_OPS (ann); + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + var = SSA_NAME_VAR (V_MUST_DEF_OP (v_must_defs, i)); bitmap_set_bit (vars_to_rename, var_ann (var)->uid); } /* We also need to rewrite vuses, since we will copy the statements and the ssa versions could not be recovered in the copy. We do - not have to do this for operands of VDEFS explicitly, since + not have to do this for operands of V_MAY_DEFS explicitly, since they have the same underlying variable as the results. */ vuses = VUSE_OPS (ann); for (i = 0; i < NUM_VUSES (vuses); i++) diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index cc246ce45be..eae021ecf80 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -37,9 +37,13 @@ Boston, MA 02111-1307, USA. */ /* By default, operands are loaded. */ #define opf_none 0 -/* Operand is the target of an assignment expression. */ +/* Operand is the target of an assignment expression or a + call-clobbered variable */ #define opf_is_def (1 << 0) +/* Operand is the target of an assignment expression. */ +#define opf_kill_def (1 << 2) + /* No virtual operands should be created in the expression. This is used when traversing ADDR_EXPR nodes which have different semantics than other expressions. Inside an ADDR_EXPR node, the only operands that we @@ -54,27 +58,32 @@ static GTY (()) varray_type build_defs; /* Array for building all the use operands. */ static GTY (()) varray_type build_uses; -/* Array for building all the vdef operands. */ -static GTY (()) varray_type build_vdefs; +/* Array for building all the v_may_def operands. */ +static GTY (()) varray_type build_v_may_defs; /* Array for building all the vuse operands. */ static GTY (()) varray_type build_vuses; +/* Array for building all the v_must_def operands. */ +static GTY (()) varray_type build_v_must_defs; + #ifdef ENABLE_CHECKING tree check_build_stmt; #endif typedef struct voperands_d { - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; vuse_optype vuse_ops; + v_must_def_optype v_must_def_ops; } *voperands_t; static void note_addressable (tree, stmt_ann_t); static void get_expr_operands (tree, tree *, int, voperands_t); static inline void append_def (tree *, tree); static inline void append_use (tree *, tree); -static void append_vdef (tree, tree, voperands_t); +static void append_v_may_def (tree, tree, voperands_t); +static void append_v_must_def (tree, tree, voperands_t); static void add_call_clobber_ops (tree, voperands_t); static void add_call_read_ops (tree, voperands_t); static void add_stmt_operand (tree *, tree, int, voperands_t); @@ -85,8 +94,8 @@ struct freelist_d GTY((chain_next ("%h.next"))) struct freelist_d *next; }; -#define NUM_FREE 4 -static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0} }; +#define NUM_FREE 5 +static GTY ((length ("NUM_FREE"))) struct freelist_d optype_freelist[NUM_FREE] = { {0}, {0}, {0}, {0}, {0} }; static inline void * @@ -155,17 +164,17 @@ allocate_use_optype (unsigned num) return use_ops; } -static inline vdef_optype -allocate_vdef_optype (unsigned num) +static inline v_may_def_optype +allocate_v_may_def_optype (unsigned num) { - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; unsigned size; - size = sizeof (struct vdef_optype_d) + sizeof (tree) * ((num * 2) - 1); - vdef_ops = check_optype_freelist (num * 2); - if (!vdef_ops) - vdef_ops = ggc_alloc (size); - vdef_ops->num_vdefs = num; - return vdef_ops; + size = sizeof (struct v_may_def_optype_d) + sizeof (tree) * ((num * 2) - 1); + v_may_def_ops = check_optype_freelist (num * 2); + if (!v_may_def_ops) + v_may_def_ops = ggc_alloc (size); + v_may_def_ops->num_v_may_defs = num; + return v_may_def_ops; } static inline vuse_optype @@ -181,6 +190,19 @@ allocate_vuse_optype (unsigned num) return vuse_ops; } +static inline v_must_def_optype +allocate_v_must_def_optype (unsigned num) +{ + v_must_def_optype v_must_def_ops; + unsigned size; + size = sizeof (struct v_must_def_optype_d) + sizeof (tree *) * (num - 1); + v_must_def_ops = check_optype_freelist (num); + if (!v_must_def_ops) + v_must_def_ops = ggc_alloc (size); + v_must_def_ops->num_v_must_defs = num; + return v_must_def_ops; +} + static inline void free_uses (use_optype *uses, bool dealloc) { @@ -215,13 +237,24 @@ free_vuses (vuse_optype *vuses, bool dealloc) } static inline void -free_vdefs (vdef_optype *vdefs, bool dealloc) +free_v_may_defs (v_may_def_optype *v_may_defs, bool dealloc) +{ + if (*v_may_defs) + { + if (dealloc) + add_optype_freelist (*v_may_defs, (*v_may_defs)->num_v_may_defs); + *v_may_defs = NULL; + } +} + +static inline void +free_v_must_defs (v_must_def_optype *v_must_defs, bool dealloc) { - if (*vdefs) + if (*v_must_defs) { if (dealloc) - add_optype_freelist (*vdefs, (*vdefs)->num_vdefs); - *vdefs = NULL; + add_optype_freelist (*v_must_defs, (*v_must_defs)->num_v_must_defs); + *v_must_defs = NULL; } } @@ -236,15 +269,24 @@ remove_vuses (tree stmt) } void -remove_vdefs (tree stmt) +remove_v_may_defs (tree stmt) { stmt_ann_t ann; ann = stmt_ann (stmt); if (ann) - free_vdefs (&(ann->vdef_ops), true); + free_v_may_defs (&(ann->v_may_def_ops), true); } +void +remove_v_must_defs (tree stmt) +{ + stmt_ann_t ann; + + ann = stmt_ann (stmt); + if (ann) + free_v_must_defs (&(ann->v_must_def_ops), true); +} void init_ssa_operands (void) @@ -253,8 +295,9 @@ init_ssa_operands (void) VARRAY_TREE_PTR_INIT (build_defs, 5, "build defs"); VARRAY_TREE_PTR_INIT (build_uses, 10, "build uses"); - VARRAY_TREE_INIT (build_vdefs, 10, "build vdefs"); + VARRAY_TREE_INIT (build_v_may_defs, 10, "build v_may_defs"); VARRAY_TREE_INIT (build_vuses, 10, "build vuses"); + VARRAY_TREE_INIT (build_v_must_defs, 10, "build v_must_defs"); for (x = 0; x < NUM_FREE; x++) optype_freelist[x].next = NULL; @@ -328,29 +371,29 @@ finalize_ssa_uses (tree stmt) } static void -finalize_ssa_vdefs (tree stmt) +finalize_ssa_v_may_defs (tree stmt) { unsigned num, x; - vdef_optype vdef_ops; + v_may_def_optype v_may_def_ops; stmt_ann_t ann; - num = VARRAY_ACTIVE_SIZE (build_vdefs); + num = VARRAY_ACTIVE_SIZE (build_v_may_defs); if (num == 0) return; #ifdef ENABLE_CHECKING - /* VDEFs must be entered in pairs of result/uses. */ + /* V_MAY_DEFs must be entered in pairs of result/uses. */ if (num % 2 != 0) abort(); #endif - vdef_ops = allocate_vdef_optype (num / 2); + v_may_def_ops = allocate_v_may_def_optype (num / 2); for (x = 0; x < num; x++) - vdef_ops->vdefs[x] = VARRAY_TREE (build_vdefs, x); - VARRAY_CLEAR (build_vdefs); + v_may_def_ops->v_may_defs[x] = VARRAY_TREE (build_v_may_defs, x); + VARRAY_CLEAR (build_v_may_defs); ann = stmt_ann (stmt); - ann->vdef_ops = vdef_ops; + ann->v_may_def_ops = v_may_def_ops; } static inline void @@ -359,12 +402,12 @@ finalize_ssa_vuses (tree stmt) unsigned num, x; stmt_ann_t ann; vuse_optype vuse_ops; - vdef_optype vdefs; + v_may_def_optype v_may_defs; #ifdef ENABLE_CHECKING - if (VARRAY_ACTIVE_SIZE (build_vdefs) > 0) + if (VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0) { - fprintf (stderr, "Please finalize VDEFs before finalize VUSES.\n"); + fprintf (stderr, "Please finalize V_MAY_DEFs before finalize VUSES.\n"); abort (); } #endif @@ -374,42 +417,42 @@ finalize_ssa_vuses (tree stmt) return; /* Remove superfluous VUSE operands. If the statement already has a - VDEF operation for a variable 'a', then a VUSE for 'a' is not - needed because VDEFs imply a VUSE of the variable. For instance, + V_MAY_DEF operation for a variable 'a', then a VUSE for 'a' is not + needed because V_MAY_DEFs imply a VUSE of the variable. For instance, suppose that variable 'a' is aliased: # VUSE - # a_3 = VDEF + # a_3 = V_MAY_DEF a = a + 1; - The VUSE is superfluous because it is implied by the VDEF + The VUSE is superfluous because it is implied by the V_MAY_DEF operation. */ ann = stmt_ann (stmt); - vdefs = VDEF_OPS (ann); - if (NUM_VDEFS (vdefs) > 0) + v_may_defs = V_MAY_DEF_OPS (ann); + if (NUM_V_MAY_DEFS (v_may_defs) > 0) { size_t i, j; for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vuses); i++) { bool found = false; - for (j = 0; j < NUM_VDEFS (vdefs); j++) + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree vuse_var, vdef_var; + tree vuse_var, v_may_def_var; tree vuse = VARRAY_TREE (build_vuses, i); - tree vdef = VDEF_OP (vdefs, j); + tree v_may_def = V_MAY_DEF_OP (v_may_defs, j); if (TREE_CODE (vuse) == SSA_NAME) vuse_var = SSA_NAME_VAR (vuse); else vuse_var = vuse; - if (TREE_CODE (vdef) == SSA_NAME) - vdef_var = SSA_NAME_VAR (vdef); + if (TREE_CODE (v_may_def) == SSA_NAME) + v_may_def_var = SSA_NAME_VAR (v_may_def); else - vdef_var = vdef; + v_may_def_var = v_may_def; - if (vuse_var == vdef_var) + if (vuse_var == v_may_def_var) { found = true; break; @@ -450,6 +493,32 @@ finalize_ssa_vuses (tree stmt) ann->vuse_ops = vuse_ops; } +static void +finalize_ssa_v_must_defs (tree stmt) +{ + unsigned num, x; + stmt_ann_t ann; + v_must_def_optype v_must_def_ops; + + num = VARRAY_ACTIVE_SIZE (build_v_must_defs); + if (num == 0) + return; + +#ifdef ENABLE_CHECKING + /* There should only be a single V_MUST_DEF per assignment. */ + if (TREE_CODE (stmt) == MODIFY_EXPR && num > 1) + abort (); +#endif + + v_must_def_ops = allocate_v_must_def_optype (num); + for (x = 0; x < num ; x++) + v_must_def_ops->v_must_defs[x] = VARRAY_TREE (build_v_must_defs, x); + VARRAY_POP_ALL (build_v_must_defs); + + ann = stmt_ann (stmt); + ann->v_must_def_ops = v_must_def_ops; +} + extern void finalize_ssa_stmt_operands (tree stmt) { @@ -460,7 +529,8 @@ finalize_ssa_stmt_operands (tree stmt) finalize_ssa_defs (stmt); finalize_ssa_uses (stmt); - finalize_ssa_vdefs (stmt); + finalize_ssa_v_must_defs (stmt); + finalize_ssa_v_may_defs (stmt); finalize_ssa_vuses (stmt); #ifdef ENABLE_CHECKING @@ -476,7 +546,8 @@ verify_start_operands (tree stmt ATTRIBUTE_UNUSED) if (VARRAY_ACTIVE_SIZE (build_defs) > 0 || VARRAY_ACTIVE_SIZE (build_uses) > 0 || VARRAY_ACTIVE_SIZE (build_vuses) > 0 - || VARRAY_ACTIVE_SIZE (build_vdefs) > 0) + || VARRAY_ACTIVE_SIZE (build_v_may_defs) > 0 + || VARRAY_ACTIVE_SIZE (build_v_must_defs) > 0) abort (); if (check_build_stmt != NULL) abort(); @@ -517,7 +588,7 @@ append_use (tree *use_p, tree stmt ATTRIBUTE_UNUSED) operands. */ static void -append_vdef (tree var, tree stmt, voperands_t prev_vops) +append_v_may_def (tree var, tree stmt, voperands_t prev_vops) { stmt_ann_t ann; size_t i; @@ -532,9 +603,9 @@ append_vdef (tree var, tree stmt, voperands_t prev_vops) /* Don't allow duplicate entries. */ - for (i = 0; i < VARRAY_ACTIVE_SIZE (build_vdefs); i += 2) + for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_may_defs); i += 2) { - tree result = VARRAY_TREE (build_vdefs, i); + tree result = VARRAY_TREE (build_v_may_defs, i); if (var == result || (TREE_CODE (result) == SSA_NAME && var == SSA_NAME_VAR (result))) @@ -542,32 +613,32 @@ append_vdef (tree var, tree stmt, voperands_t prev_vops) } /* If the statement already had virtual definitions, see if any of the - existing VDEFs matches VAR. If so, re-use it, otherwise add a new - VDEF for VAR. */ + existing V_MAY_DEFs matches VAR. If so, re-use it, otherwise add a new + V_MAY_DEF for VAR. */ result = NULL_TREE; source = NULL_TREE; if (prev_vops) - for (i = 0; i < NUM_VDEFS (prev_vops->vdef_ops); i++) + for (i = 0; i < NUM_V_MAY_DEFS (prev_vops->v_may_def_ops); i++) { - result = VDEF_RESULT (prev_vops->vdef_ops, i); + result = V_MAY_DEF_RESULT (prev_vops->v_may_def_ops, i); if (result == var || (TREE_CODE (result) == SSA_NAME && SSA_NAME_VAR (result) == var)) { - source = VDEF_OP (prev_vops->vdef_ops, i); + source = V_MAY_DEF_OP (prev_vops->v_may_def_ops, i); break; } } - /* If no previous VDEF operand was found for VAR, create one now. */ + /* If no previous V_MAY_DEF operand was found for VAR, create one now. */ if (source == NULL_TREE) { result = var; source = var; } - VARRAY_PUSH_TREE (build_vdefs, result); - VARRAY_PUSH_TREE (build_vdefs, source); + VARRAY_PUSH_TREE (build_v_may_defs, result); + VARRAY_PUSH_TREE (build_v_may_defs, source); } @@ -626,6 +697,61 @@ append_vuse (tree var, tree stmt, voperands_t prev_vops) VARRAY_PUSH_TREE (build_vuses, var); } +/* Add VAR to the list of virtual must definitions for STMT. If PREV_VOPS + is not NULL, the existing entries are preserved and no new entries are + added here. This is done to preserve the SSA numbering of virtual + operands. */ + +static void +append_v_must_def (tree var, tree stmt, voperands_t prev_vops) +{ + stmt_ann_t ann; + size_t i; + bool found; + tree v_must_def; + +#ifdef ENABLE_CHECKING + if (check_build_stmt != stmt) + abort(); +#endif + + ann = stmt_ann (stmt); + + /* Don't allow duplicate entries. */ + for (i = 0; i < VARRAY_ACTIVE_SIZE (build_v_must_defs); i++) + { + tree v_must_def_var = VARRAY_TREE (build_v_must_defs, i); + if (var == v_must_def_var + || (TREE_CODE (v_must_def_var) == SSA_NAME + && var == SSA_NAME_VAR (v_must_def_var))) + return; + } + + /* If the statement already had virtual must defs, see if any of the + existing V_MUST_DEFs matches VAR. If so, re-use it, otherwise add a new + V_MUST_DEF for VAR. */ + found = false; + v_must_def = NULL_TREE; + if (prev_vops) + for (i = 0; i < NUM_V_MUST_DEFS (prev_vops->v_must_def_ops); i++) + { + v_must_def = V_MUST_DEF_OP (prev_vops->v_must_def_ops, i); + if (v_must_def == var + || (TREE_CODE (v_must_def) == SSA_NAME + && SSA_NAME_VAR (v_must_def) == var)) + { + found = true; + break; + } + } + + /* If VAR existed already in PREV_VOPS, re-use it. */ + if (found) + var = v_must_def; + + VARRAY_PUSH_TREE (build_v_must_defs, var); +} + /* External entry point which by-passes the previous vops mechanism. */ void @@ -676,12 +802,14 @@ get_stmt_operands (tree stmt) /* Before removing existing virtual operands, save them in PREV_VOPS so that we can re-use their SSA versions. */ - prev_vops.vdef_ops = VDEF_OPS (ann); + prev_vops.v_may_def_ops = V_MAY_DEF_OPS (ann); prev_vops.vuse_ops = VUSE_OPS (ann); + prev_vops.v_must_def_ops = V_MUST_DEF_OPS (ann); /* Dont free the previous values to memory since we're still using them. */ - free_vdefs (&(ann->vdef_ops), false); + free_v_may_defs (&(ann->v_may_def_ops), false); free_vuses (&(ann->vuse_ops), false); + free_v_must_defs (&(ann->v_must_def_ops), false); start_ssa_stmt_operands (stmt); @@ -690,7 +818,15 @@ get_stmt_operands (tree stmt) { case MODIFY_EXPR: get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none, &prev_vops); - get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, &prev_vops); + if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF + || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF + || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR + || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR) + get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def, + &prev_vops); + else + get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), + opf_is_def | opf_kill_def, &prev_vops); break; case COND_EXPR: @@ -792,8 +928,9 @@ get_stmt_operands (tree stmt) finalize_ssa_stmt_operands (stmt); /* Now free the previous virtual ops to memory. */ - free_vdefs (&(prev_vops.vdef_ops), true); + free_v_may_defs (&(prev_vops.v_may_def_ops), true); free_vuses (&(prev_vops.vuse_ops), true); + free_v_must_defs (&(prev_vops.v_must_def_ops), true); /* Clear the modified bit for STMT. Subsequent calls to get_stmt_operands for this statement will do nothing until the @@ -806,7 +943,7 @@ get_stmt_operands (tree stmt) /* Recursively scan the expression pointed by EXPR_P in statement STMT. FLAGS is one of the OPF_* constants modifying how to interpret the - operands found. PREV_VOPS is as in append_vdef and append_vuse. */ + operands found. PREV_VOPS is as in append_v_may_def and append_vuse. */ static void get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) @@ -1053,7 +1190,15 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) if (code == MODIFY_EXPR) { get_expr_operands (stmt, &TREE_OPERAND (expr, 1), opf_none, prev_vops); - get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, prev_vops); + if (TREE_CODE (TREE_OPERAND (expr, 0)) == ARRAY_REF + || TREE_CODE (TREE_OPERAND (expr, 0)) == COMPONENT_REF + || TREE_CODE (TREE_OPERAND (expr, 0)) == REALPART_EXPR + || TREE_CODE (TREE_OPERAND (expr, 0)) == IMAGPART_EXPR) + get_expr_operands (stmt, &TREE_OPERAND (expr, 0), opf_is_def, + prev_vops); + else + get_expr_operands (stmt, &TREE_OPERAND (expr, 0), + opf_is_def | opf_kill_def, prev_vops); return; } @@ -1104,7 +1249,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags, voperands_t prev_vops) operands. PREV_VOPS is used when adding virtual operands to statements that - already had them (See append_vdef and append_vuse). */ + already had them (See append_v_may_def and append_vuse). */ static void add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) @@ -1193,9 +1338,21 @@ add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) /* The variable is not aliased or it is an alias tag. */ if (flags & opf_is_def) { - append_vdef (var, stmt, prev_vops); if (v_ann->is_alias_tag) - s_ann->makes_aliased_stores = 1; + { + /* Alias tagged vars get regular V_MAY_DEF */ + s_ann->makes_aliased_stores = 1; + append_v_may_def (var, stmt, prev_vops); + } + else if ((flags & opf_kill_def) + && v_ann->mem_tag_kind == NOT_A_TAG) + /* V_MUST_DEF for non-aliased non-GIMPLE register + variable definitions. Avoid memory tags. */ + append_v_must_def (var, stmt, prev_vops); + else + /* Call-clobbered variables & memory tags get + V_MAY_DEF */ + append_v_may_def (var, stmt, prev_vops); } else { @@ -1220,10 +1377,10 @@ add_stmt_operand (tree *var_p, tree stmt, int flags, voperands_t prev_vops) references to the members of the variable's alias set. This fixes the bug in gcc.c-torture/execute/20020503-1.c. */ if (v_ann->is_alias_tag) - append_vdef (var, stmt, prev_vops); + append_v_may_def (var, stmt, prev_vops); for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++) - append_vdef (VARRAY_TREE (aliases, i), stmt, prev_vops); + append_v_may_def (VARRAY_TREE (aliases, i), stmt, prev_vops); s_ann->makes_aliased_stores = 1; } @@ -1267,9 +1424,10 @@ add_call_clobber_ops (tree stmt, voperands_t prev_vops) call-clobbered variables. */ stmt_ann (stmt)->makes_clobbering_call = true; - /* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add a VDEF - operand for every call clobbered variable. See compute_may_aliases for - the heuristic used to decide whether to create .GLOBAL_VAR or not. */ + /* If we had created .GLOBAL_VAR earlier, use it. Otherwise, add + a V_MAY_DEF operand for every call clobbered variable. See + compute_may_aliases for the heuristic used to decide whether + to create .GLOBAL_VAR or not. */ if (global_var) add_stmt_operand (&global_var, stmt, opf_is_def, prev_vops); else @@ -1280,7 +1438,8 @@ add_call_clobber_ops (tree stmt, voperands_t prev_vops) { tree var = referenced_var (i); - /* If VAR is read-only, don't add a VDEF, just a VUSE operand. */ + /* If VAR is read-only, don't add a V_MAY_DEF, just a + VUSE operand. */ if (!TREE_READONLY (var)) add_stmt_operand (&var, stmt, opf_is_def, prev_vops); else diff --git a/gcc/tree-ssa-operands.h b/gcc/tree-ssa-operands.h index ceee6d037ab..e83c776d11f 100644 --- a/gcc/tree-ssa-operands.h +++ b/gcc/tree-ssa-operands.h @@ -39,13 +39,13 @@ typedef struct use_optype_d GTY(()) typedef use_optype_t *use_optype; -typedef struct vdef_optype_d GTY(()) +typedef struct v_may_def_optype_d GTY(()) { - unsigned num_vdefs; - tree GTY((length ("%h.num_vdefs * 2"))) vdefs[1]; -} vdef_optype_t; + unsigned num_v_may_defs; + tree GTY((length ("%h.num_v_may_defs * 2"))) v_may_defs[1]; +} v_may_def_optype_t; -typedef vdef_optype_t *vdef_optype; +typedef v_may_def_optype_t *v_may_def_optype; typedef struct vuse_optype_d GTY(()) { @@ -55,6 +55,14 @@ typedef struct vuse_optype_d GTY(()) typedef vuse_optype_t *vuse_optype; +typedef struct v_must_def_optype_d GTY(()) +{ + unsigned num_v_must_defs; + tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1]; +} v_must_def_optype_t; + +typedef v_must_def_optype_t *v_must_def_optype; + #define USE_OPS(ANN) get_use_ops (ANN) #define STMT_USE_OPS(STMT) get_use_ops (stmt_ann (STMT)) #define NUM_USES(OPS) ((OPS) ? (OPS)->num_uses : 0) @@ -69,13 +77,13 @@ typedef vuse_optype_t *vuse_optype; #define DEF_OP(OPS, I) (*(DEF_OP_PTR ((OPS), (I)))) -#define VDEF_OPS(ANN) get_vdef_ops (ANN) -#define STMT_VDEF_OPS(STMT) get_vdef_ops (stmt_ann(STMT)) -#define NUM_VDEFS(OPS) ((OPS) ? (OPS)->num_vdefs : 0) -#define VDEF_RESULT_PTR(OPS, I) get_vdef_result_ptr ((OPS), (I)) -#define VDEF_RESULT(OPS, I) (*(VDEF_RESULT_PTR ((OPS), (I)))) -#define VDEF_OP_PTR(OPS, I) get_vdef_op_ptr ((OPS), (I)) -#define VDEF_OP(OPS, I) (*(VDEF_OP_PTR ((OPS), (I)))) +#define V_MAY_DEF_OPS(ANN) get_v_may_def_ops (ANN) +#define STMT_V_MAY_DEF_OPS(STMT) get_v_may_def_ops (stmt_ann(STMT)) +#define NUM_V_MAY_DEFS(OPS) ((OPS) ? (OPS)->num_v_may_defs : 0) +#define V_MAY_DEF_RESULT_PTR(OPS, I) get_v_may_def_result_ptr ((OPS), (I)) +#define V_MAY_DEF_RESULT(OPS, I) (*(V_MAY_DEF_RESULT_PTR ((OPS), (I)))) +#define V_MAY_DEF_OP_PTR(OPS, I) get_v_may_def_op_ptr ((OPS), (I)) +#define V_MAY_DEF_OP(OPS, I) (*(V_MAY_DEF_OP_PTR ((OPS), (I)))) #define VUSE_OPS(ANN) get_vuse_ops (ANN) @@ -85,6 +93,12 @@ typedef vuse_optype_t *vuse_optype; #define VUSE_OP(OPS, I) (*(VUSE_OP_PTR ((OPS), (I)))) +#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN) +#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT)) +#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0) +#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I)) +#define V_MUST_DEF_OP(OPS, I) (*(V_MUST_DEF_OP_PTR ((OPS), (I)))) + extern void init_ssa_operands (void); extern void fini_ssa_operands (void); extern void verify_start_operands (tree); @@ -92,6 +106,7 @@ extern void finalize_ssa_stmt_operands (tree); void add_vuse (tree, tree); extern void get_stmt_operands (tree); extern void remove_vuses (tree); -extern void remove_vdefs (tree); +extern void remove_v_may_defs (tree); +extern void remove_v_must_defs (tree); #endif /* GCC_TREE_SSA_OPERANDS_H */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 2e2f42747e5..aa45e10ea79 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -1312,7 +1312,8 @@ subst_phis (struct expr_info *ei, tree Z, basic_block pred, basic_block bb) else { remove_vuses (stmt_copy); - remove_vdefs (stmt_copy); + remove_v_may_defs (stmt_copy); + remove_v_must_defs (stmt_copy); } if (pred->index < n_phi_preds) @@ -3016,13 +3017,16 @@ process_left_occs_and_kills (varray_type bexprs, tree expr) { size_t i, j, k; - stmt_ann_t ann = stmt_ann (expr); - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; vuse_optype vuses; def_optype defs; - defs = DEF_OPS (ann); - vdefs = VDEF_OPS (ann); - if (NUM_DEFS (defs) == 0 && NUM_VDEFS (vdefs) == 0) + defs = STMT_DEF_OPS (expr); + v_may_defs = STMT_V_MAY_DEF_OPS (expr); + v_must_defs = STMT_V_MUST_DEF_OPS (expr); + if (NUM_DEFS (defs) == 0 + && NUM_V_MAY_DEFS (v_may_defs) == 0 + && NUM_V_MUST_DEFS (v_must_defs) == 0) return; for (j = 0; j < VARRAY_ACTIVE_SIZE (bexprs); j++) @@ -3052,19 +3056,36 @@ process_left_occs_and_kills (varray_type bexprs, tree expr) } } - /* If we VDEF the VUSE of the expression, it's also a left + /* If we virtually define the variable itself, + it's a left occurrence. */ + for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) + { + if (names_match_p (V_MUST_DEF_OP (v_must_defs, i), ei->expr)) + { + if (TREE_CODE (expr) == ASM_EXPR) + { + ei->loadpre_cand = false; + continue; + } + VARRAY_PUSH_TREE (ei->lefts, expr); + VARRAY_PUSH_TREE (ei->occurs, NULL); + VARRAY_PUSH_TREE (ei->kills, NULL); + } + } + + /* If we V_MAY_DEF the VUSE of the expression, it's also a left occurrence. */ random_occur = VARRAY_TREE (ei->occurs, 0); ann = stmt_ann (random_occur); vuses = VUSE_OPS (ann); - if (NUM_VDEFS (vdefs) != 0) + if (NUM_V_MAY_DEFS (v_may_defs) != 0) { for (k = 0; k < NUM_VUSES (vuses); k++) { vuse_name = VUSE_OP (vuses, k); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - if (names_match_p (VDEF_OP (vdefs, i), vuse_name)) + if (names_match_p (V_MAY_DEF_OP (v_may_defs, i), vuse_name)) { VARRAY_PUSH_TREE (ei->lefts, expr); VARRAY_PUSH_TREE (ei->occurs, NULL); diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index f6eb1fd23fa..52a61944e6e 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -314,20 +314,21 @@ verify_ssa (void) tree stmt; stmt_ann_t ann; unsigned int j; - vdef_optype vdefs; + v_may_def_optype v_may_defs; + v_must_def_optype v_must_defs; def_optype defs; stmt = bsi_stmt (bsi); ann = stmt_ann (stmt); get_stmt_operands (stmt); - vdefs = VDEF_OPS (ann); - if (ann->makes_aliased_stores && NUM_VDEFS (vdefs) == 0) - error ("Makes aliased stores, but no VDEFS"); - - for (j = 0; j < NUM_VDEFS (vdefs); j++) + v_may_defs = V_MAY_DEF_OPS (ann); + if (ann->makes_aliased_stores && NUM_V_MAY_DEFS (v_may_defs) == 0) + error ("Makes aliased stores, but no V_MAY_DEFS"); + + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree op = VDEF_RESULT (vdefs, j); + tree op = V_MAY_DEF_RESULT (v_may_defs, j); if (is_gimple_reg (op)) { error ("Found a virtual definition for a GIMPLE register"); @@ -337,6 +338,20 @@ verify_ssa (void) } err |= verify_def (bb, definition_block, op, stmt); } + + v_must_defs = STMT_V_MUST_DEF_OPS (stmt); + for (j = 0; j < NUM_V_MUST_DEFS (v_must_defs); j++) + { + tree op = V_MUST_DEF_OP (v_must_defs, j); + if (is_gimple_reg (op)) + { + error ("Found a virtual must-def for a GIMPLE register"); + debug_generic_stmt (op); + debug_generic_stmt (stmt); + err = true; + } + err |= verify_def (bb, definition_block, op, stmt); + } defs = DEF_OPS (ann); for (j = 0; j < NUM_DEFS (defs); j++) @@ -380,14 +395,14 @@ verify_ssa (void) /* Now verify all the uses and vuses in every statement of the block. - Remember, the RHS of a VDEF is a use as well. */ + Remember, the RHS of a V_MAY_DEF is a use as well. */ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) { tree stmt = bsi_stmt (bsi); stmt_ann_t ann = stmt_ann (stmt); unsigned int j; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; use_optype uses; vuses = VUSE_OPS (ann); @@ -406,10 +421,10 @@ verify_ssa (void) op, stmt, false); } - vdefs = VDEF_OPS (ann); - for (j = 0; j < NUM_VDEFS (vdefs); j++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (j = 0; j < NUM_V_MAY_DEFS (v_may_defs); j++) { - tree op = VDEF_OP (vdefs, j); + tree op = V_MAY_DEF_OP (v_may_defs, j); if (is_gimple_reg (op)) { @@ -699,7 +714,7 @@ replace_immediate_uses (tree var, tree repl) { use_optype uses; vuse_optype vuses; - vdef_optype vdefs; + v_may_def_optype v_may_defs; int i, j, n; dataflow_t df; tree stmt; @@ -742,10 +757,10 @@ replace_immediate_uses (tree var, tree repl) if (VUSE_OP (vuses, j) == var) propagate_value (VUSE_OP_PTR (vuses, j), repl); - vdefs = VDEF_OPS (ann); - for (j = 0; j < (int) NUM_VDEFS (vdefs); j++) - if (VDEF_OP (vdefs, j) == var) - propagate_value (VDEF_OP_PTR (vdefs, j), repl); + v_may_defs = V_MAY_DEF_OPS (ann); + for (j = 0; j < (int) NUM_V_MAY_DEFS (v_may_defs); j++) + if (V_MAY_DEF_OP (v_may_defs, j) == var) + propagate_value (V_MAY_DEF_OP_PTR (v_may_defs, j), repl); } modify_stmt (stmt); diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 47d707682b3..92626860f23 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -391,7 +391,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) /* If the statement has virtual operands, fail. */ ann = stmt_ann (stmt); - if (NUM_VDEFS (VDEF_OPS (ann)) + if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) + || NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) || NUM_VUSES (VUSE_OPS (ann))) return; } @@ -644,7 +645,7 @@ eliminate_tail_call (struct tailcall *t) edge e; tree phi; stmt_ann_t ann; - vdef_optype vdefs; + v_may_def_optype v_may_defs; unsigned i; stmt = bsi_stmt (t->call_bsi); @@ -696,10 +697,10 @@ eliminate_tail_call (struct tailcall *t) } /* Add phi nodes for the call clobbered variables. */ - vdefs = VDEF_OPS (ann); - for (i = 0; i < NUM_VDEFS (vdefs); i++) + v_may_defs = V_MAY_DEF_OPS (ann); + for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) { - param = SSA_NAME_VAR (VDEF_RESULT (vdefs, i)); + param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i)); for (phi = phi_nodes (first); phi; phi = TREE_CHAIN (phi)) if (param == SSA_NAME_VAR (PHI_RESULT (phi))) break; @@ -721,7 +722,7 @@ eliminate_tail_call (struct tailcall *t) abort (); } - add_phi_arg (&phi, VDEF_OP (vdefs, i), e); + add_phi_arg (&phi, V_MAY_DEF_OP (v_may_defs, i), e); } /* Update the values of accumulators. */ -- 2.30.2