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
This commit is contained in:
parent
d57f161721
commit
a32b97a20d
166
gcc/ChangeLog
166
gcc/ChangeLog
|
@ -1,3 +1,169 @@
|
|||
2004-06-10 Brian Booth <bbooth@redhat.com>
|
||||
|
||||
* 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 <vmakarov@redhat.com>
|
||||
|
||||
PR target/15653
|
||||
|
|
|
@ -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 <a>
|
||||
# b = VDEF <b>
|
||||
# a = V_MAY_DEF <a>
|
||||
# b = V_MAY_DEF <b>
|
||||
*p = 5;
|
||||
|
||||
# VUSE <a>
|
||||
|
@ -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 <p_4(1), p_6(2)>;
|
||||
|
||||
# a_7 = VDEF <a_3>;
|
||||
# b_8 = VDEF <b_5>;
|
||||
# a_7 = V_MAY_DEF <a_3>;
|
||||
# b_8 = V_MAY_DEF <b_5>;
|
||||
*p_1 = 3;
|
||||
|
||||
# a_9 = VDEF <a_7>
|
||||
# a_9 = V_MAY_DEF <a_7>
|
||||
# VUSE <b_8>
|
||||
a_9 = b_8 + 2;
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2004-06-10 Brian Booth <bbooth@redhat.com>
|
||||
|
||||
* 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 <tobias.schlueter@physik.uni-muenchen.de>
|
||||
|
||||
PR fortran/14957
|
||||
|
|
|
@ -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" } } */
|
||||
|
|
|
@ -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"} } */
|
||||
|
||||
|
|
110
gcc/tree-dfa.c
110
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 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_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
|
||||
vdefs_disappeared_p (vdef_optype vdefs_before, vdef_optype vdefs_after)
|
||||
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 (vdefs_before == NULL)
|
||||
if (v_may_defs_before == NULL)
|
||||
return false;
|
||||
|
||||
/* All/some of them gone. */
|
||||
if (vdefs_after == NULL
|
||||
|| NUM_VDEFS (vdefs_before) > NUM_VDEFS (vdefs_after))
|
||||
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 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
|
||||
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 (v_must_defs_before == NULL)
|
||||
return false;
|
||||
|
||||
/* All/some of them gone. */
|
||||
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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
set_livein_block (VDEF_OP (vdefs, i), bb);
|
||||
set_def_block (VDEF_RESULT (vdefs, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 <p_4(1), p_6(2)>;
|
||||
|
||||
# a_7 = VDEF <a_3>;
|
||||
# b_8 = VDEF <b_5>;
|
||||
# a_7 = V_MAY_DEF <a_3>;
|
||||
# b_8 = V_MAY_DEF <b_5>;
|
||||
*p_1 = 3;
|
||||
|
||||
# a_9 = VDEF <a_7>
|
||||
# a_9 = V_MAY_DEF <a_7>
|
||||
# VUSE <b_8>
|
||||
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_8>
|
||||
# a_9 = V_MAY_DEF <a_8>
|
||||
p_5->field = 0
|
||||
... Several modifications to TMT.20 ...
|
||||
# VUSE <a_9>
|
||||
|
@ -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
|
||||
|
|
|
@ -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 = VDEF_RESULT (vdefs, 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 = V_MUST_DEF_OP (v_must_defs, i);
|
||||
if (TREE_CODE (var) == SSA_NAME)
|
||||
SSA_NAME_DEF_STMT (var) = *stmt_p;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 (VDEF_RESULT (vdefs, i), block_defs_p);
|
||||
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 (V_MUST_DEF_OP (v_must_defs, i), block_defs_p);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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))
|
||||
{
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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 (*vdefs)
|
||||
if (*v_may_defs)
|
||||
{
|
||||
if (dealloc)
|
||||
add_optype_freelist (*vdefs, (*vdefs)->num_vdefs);
|
||||
*vdefs = NULL;
|
||||
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 (*v_must_defs)
|
||||
{
|
||||
if (dealloc)
|
||||
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_2>
|
||||
# a_3 = VDEF <a_2>
|
||||
# a_3 = V_MAY_DEF <a_2>
|
||||
a = a + 1;
|
||||
|
||||
The VUSE <a_2> is superfluous because it is implied by the VDEF
|
||||
The VUSE <a_2> 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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue