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:
Brian Booth 2004-06-10 21:41:08 +00:00 committed by Brian Booth
parent d57f161721
commit a32b97a20d
25 changed files with 973 additions and 336 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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" } } */

View File

@ -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"} } */

View File

@ -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);

View File

@ -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)
{

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);

View File

@ -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));
}
}
}

View File

@ -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);
}
}

View File

@ -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))
{

View File

@ -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
}
}
}

View File

@ -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++)

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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);

View File

@ -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. */