Commit f47c96aa by Andrew MacLeod Committed by Andrew Macleod

lambda-code.c (gcc_loop_to_lambda_loop, [...]): Use generic operand interface.


2005-05-03  Andrew MacLeod  <amacleod@redhat.com>

	* lambda-code.c (gcc_loop_to_lambda_loop,
	lambda_loopnest_to_gcc_loopnest, phi_loop_edge_uses_def,
	stmt_is_bumper_for_loop, perfect_nest_p, replace_uses_of_x_with_y): Use
	generic operand interface.
	* tree-data-ref.c (find_data_references_in_loop): Use generic interface.
	* tree-dfa.c (collect_dfa_stats_r, mark_new_vars_to_rename): Use
	generic operand interface.
	* tree-flow-inline.h (delink_imm_use, link_imm_use_to_list,
	link_imm_use, link_imm_use_stmt, relink_imm_use, relink_imm_use_stmt,
	next_safe_imm_use, has_zero_uses, has_single_use, single_imm_use,
	num_imm_uses): Use ssa_use_operand_t.
	(get_def_ops, get_use_ops, get_v_may_def_ops, get_vuse_ops,
	get_v_must_def_ops): Delete.
	(get_def_from_ptr, get_phi_result_ptr): Get def directly now.
	(get_use_op_ptr, get_def_op_ptr, get_v_may_def_result_ptr,
	get_v_may_def_op_ptr, get_vuse_op_ptr, get_v_must_def_result_ptr,
	get_v_must_def_kill_ptr): Delete.
	(delink_stmt_imm_use): Move and use new operand interface.
	(op_iter_next_use, op_iter_next_def, op_iter_next_tree, op_iter_init,
	op_iter_next_tree): Use new operand implementation.
	(clear_and_done_ssa_iter): New.  Initialize a blank operand iterator.
	(op_iter_init_use, op_iter_init_def, op_iter_init_tree): Add iterator
	type check.
	(op_iter_next_mustdef, op_iter_next_maydef,
	op_iter_next_must_and_may_def): Delete. Replace with...
	(op_iter_next_maymustdef): New.  Combine must and may next operations.
	(op_iter_init_maydef, op_iter_init_mustdef,
	op_iter_init_must_and_may_def): Use new interface.
	(single_ssa_tree_operand ): New.  Process single operands only as trees.
	(single_ssa_use_operand): New.  Process single operands only as uses.
	(single_ssa_def_operand): New.  Process single operands only as defs.
	(zero_ssa_operands): New.  Return TRUE if there are zero operands of the
	specified types.
	(num_ssa_operands): New.  Count the number of specified operands.
	(compare_ssa_operands_equal): New.  Compare two statements' operands.
	(single_phi_def): New.  Return true if PHI has one def of the specified
	operand type.
	(op_iter_init_phiuse): New.  Initialize the iterator for PHI arguments.
	(op_iter_init_phidef): New.  Initialize the iterator for the PHI def.
	* tree-flow.h (struct immediate_use_iterator_d): Use ssa_use_operand_t.
	(struct stmt_ann_d): Operands field no longer require GTY().
	(vn_compute, vn_lookup_or_add, vn_add, vn_lookup): Change prototype.
	* tree-into-ssa.c (mark_def_sites): Use SSA_OP_VMUSTKILL.
	* tree-outof-ssa.c (check_replaceable, find_replaceable_in_bb,
	dump_replaceable_exprs, rewrite_trees): Use generic interface.
	* tree-phinodes.c (make_phi_node, release_phi_node, resize_phi_node):
	Use use_operand_p instead of ssa_imm_use_t *.
	* tree-pretty-print.c (dump_vops): check if operands are active before
	dumping virtual operands.
	* tree-sra.c (sra_walk_function): Use ZERO_SSA_OPERANDS.
	* tree-ssa-ccp.c (likely_value): Use ZERO_SSA_OPERANDS.
	(ccp_fold): Use new interface.
	(ccp_visit_stmt): Remove unused variables and code.
	(convert_to_gimple_builtin): Insert statements before calling
	mark_new_vars_to_rename.
	* tree-ssa-copy.c (stmt_may_generate_copy): Use ZERO_SSA_OPERANDS.
	(copy_prop_visit_cond_stmt): Use generic interface.
	* tree-ssa-dom.c (struct expr_hash_elt): Use stmt pointer, not the
	annotation in table.
	(thread_across_edge): Use generic interface.
	(initialize_hash_element): Initialzie with stmt, not annotation.
	(eliminate_redundant_computations): Use generic interface.
	(record_equivalences_from_stmt): Pass stmt, not annotation.
	(avail_expr_hash, real_avail_expr_hash, avail_expr_eq): Use generic
	interface.
	* tree-ssa-dse.c (dse_optimize_stmt): Use ZERO_SSA_OPERANDS.
	* tree-ssa-loop-ivopts.c (find_invariants_stmt,
	find_interesting_uses_stmt, protect_loop_closed_ssa_form_use): Use
	generic operand interface.
	* tree-ssa-loop-niter.c (chain_of_csts_start, get_val_for): Use generic
	interface.
	* tree-ssa-loop-unswitch.c (tree_may_unswitch_on): Use Generic operand
	Interface.
	* tree-ssa-operands.c (struct opbuild_list_d): New.  Operand build type.
	(build_defs, build_uses, build_v_may_defs, build_vuses,
	build_v_must_defs): Change type to struct opbuild_list_d.
	(ops_active): New.  Operands active boolean.
	(operand_memory, operand_memory_index): New.  Operand memory managers.
	(allocate_def_optype, allocate_use_optype, allocate_v_may_def_optype,
	allocate_vuse_optype, allocate_v_must_def_optype): Delete.
	(free_uses, free_defs, free_vuses, free_v_may_defs, free_v_must_defs):
	Change from functions to static variable list heads.
	(opbuild_initialize_virtual): New.  Initialize a virtual build list.
	(opbuild_initialize_real): New.  Initialize a virtual build list.
	(opbuild_free): New.  Free a build list.
	(opbuild_num_elems): New.  Number of items in a list.
	(opbuild_append_real): New.  Add a real (tree *) operand.
	(opbuild_append_virtual): New.  Add and sort a virtual (tree) operand.
	(opbuild_first): New.  Return first element index in a list.
	(opbuild_next): New.  Return next element in a list.
	(opbuild_elem_real): New.  Return real element.
	(opbuild_elem_virtual): New.  Return virtual element.
	(opbuild_elem_uid): New.  Return UID of virtual element.
	(opbuild_clear): New.  Reset an operand list.
	(opbuild_remove_elem): New.  Remove an element form a list.
	(ssa_operands_active): New.  Return true if operand cache is active.
	(init_ssa_operands, fini_ssa_operands): Initialize new implementation.
	(ssa_operand_alloc): New.  Allocate memory from an operand chunk.
	(correct_use_link): Use use_operand_p.
	(finalize_ssa_uses, finalize_ssa_v_may_defs, finalize_ssa_defs,
	finalize_ssa_vuses, finalize_ssa_v_must_defs): New implmentation.
	(cleanup_v_may_defs): Use new implmentation.
	(finalize_ssa_stmt_operands, start_ssa_stmt_operands): New
	implementation.
	(append_def, append_use, append_v_may_def, append_vuse,
	append_v_must_def): Call opbuild_append routine instead of using varray.
	(build_ssa_operands): Simplify to simply use stmt, don't maintain a
	global parse_old_ops variable.
	(free_ssa_operands): New implementation.
	(update_stmt_operands): Move.  Change argument to build_ssa_operands.
	(copy_virtual_operands): Move. New generic implementation.
	(create_ssa_artficial_load_stmt): Move. New implementation.
	(swap_tree_operands): Update for new implementation.
	(get_expr_operands): Add stmt parameter to calls to swap_tree_operands.
	(add_call_clobber_ops, add_call_read_ops): Initialize opbuild list
	rather than a varray.
	(verify_imm_links): Use use_operand_p.
	(dump_immediate_uses_for): If the immediate use variable is a virtual
	variable, show the virtual ops in the stmt.
	* tree-ssa-operands.h (def_operand_p): No longer a structure.
	(NULL_DEF_OPERAND_P): Now a #define.
	(def_optype_d, use_optype_d, v_def_use_operand_type, v_may_def_optype_d,
	vuse_operand_type, vuse_optype_d, v_must_def_optype_d): Delete.
	(def_optype_d, use_optype_d, maydef_optype_d, vuse_optype_d,
	mustdef_optype_d): New.  Use Linked list representation.
	(SSA_OPERAND_MEMORY_SIZE): New.  Size of operand memory chunk.
	(struct ssa_operand_memory_d): New.  Allocated Chunk node.
	(struct stmt_operands_d): Change to new pointers that are not GTY.
	(STMT_USE_OPS, NUM_USES, SET_USE_OP, STMT_DEF_OPS, NUM_DEFS, SET_DEF_OP,
	STMT_V_MAY_DEF_OPS, NUM_V_MAY_DEFS, SET_V_MAY_DEF_RESULT,
	SET_V_MAY_DEF_OP, STMT_VUSE_OPS, NUM_VUSES, SET_VUSE_OP,
	STMT_V_MUST_DEF_OPS, NUM_V_MUST_DEFS, SET_V_MUST_DEF_RESULT,
	SET_V_MUST_DEF_KILL): Delete.
	(V_MAY_DEF_OPS, V_MAY_DEF_RESULT_PTR, V_MAY_DEF_RESULT,
	V_MAY_DEF_OP_PTR, V_MAY_DEF_OP): Rename to MAYDEF_*.
	(V_MUST_DEF_OPS, V_MUST_DEF_RESULT_PTR, V_MUST_DEF_RESULT,
	V_MUST_DEF_KILL_PTR, V_MUST_DEF_KILL): Rename to MUSTDEF_*.
	(enum ssa_op_iter_type): Operand iterator typechecking values.
	(struct ssa_operand_iterator_d): Use linked lists of operands.
	(SSA_OP_VMUSTDEFKILL): Rename to SSA_OP_VMUSTKILL.
	(FOR_EACH_SSA_MAYDEF_OPERAND, FOR_EACH_SSA_MUSTDEF_OPERAND,
	FOR_EACH_SSA_MUST_AND_MAY_DEF_OPERAND): Use op_iter_next_maymustdef.
	(FOR_EACH_PHI_ARG): New.  Iterate over PHI arguments.
	(FOR_EACH_PHI_OR_STMT_USE): New.  Iterate over PHI or stmt uses.
	(FOR_EACH_PHI_OR_STMT_DEF): New.  Iterate over PHI or stmt defs.
	(SINGLE_SSA_TREE_OPERAND, SINGLE_SSA_USE_OPERAND,
	SINGLE_SSA_DEF_OPERAND, ZERO_SSA_OPERANDS, NUM_SSA_OPERANDS): New.
	* tree-ssa-opfinalize.h: New.  Function templates for expansion.
	(FINALIZE_ALLOC): Expands into alloc_def, alloc_use, alloc_maydef,
	alloc_vuse, and alloc_mustdef.
	(FINALIZE_FUNC): Expands into finalize_ssa_def_ops,
	finalize_ssa_use_ops, finalize_ssa_v_may_def_ops, finalize_ssa_vuse_ops,
	and finalize_ssa_v_must_def_ops.
	* tree-ssa-pre.c (add_to_sets): Pass tree to vn_add.
	(create_value_expr_from): Use stmt not vuse_optype as a parameter. Pass
	stmt around.
	(compute_avail): Use generic iterator interface.
	* tree-ssa-propagate.c (first_vdef): Use generic operand interface.
	(stmt_makes_single_load, stmt_makes_single_store): Use
	ZERO_SSA_OPERANDS.
	* tree-ssa-sink.c (is_hidden_global_store): Use ZERO_SSA_OPERANDS.
	(statement_sink_location): Use generic interface.
	* tree-ssa.c (verify_ssa):  Use %p in fprintf.  Use generic interface.
	(delete_tree_ssa): Don't call release_defs.  Call release_ssa_name and
	reset the immediate use link nodes.
	(stmt_references_memory_p): Use ZERO_SSA_OPERANDS.
	* tree-ssanames.c (make_ssa_name): Use use_operand_p.
	* tree-tailcall.c (find_tail_calls): Use ZERO_SSA_OPERANDS.
	(eliminate_tail_call): Use generic operand interface.
	* tree-vect-analyze.c (vect_analyze_data_refs): Use ZERO_SSA_OPERANDS.
	(vect_mark_relevant, vect_mark_stmts_to_be_vectorized): Use generic
	interface.
	* tree-vect-transform.c (update_vuses_to_preheader): Use generic
	interface.
	* tree-vectorizer.c (rename_variables_in_bb): Use generic interface.
	* tree-vn.c (struct val_expr_pair_d): Cache statment pointer instead of
	vuse_optype.
	(vn_compute, val_expr_pair_hash, vn_add, vn_lookup, vn_lookup_or_add):
	Use statement pointer instead of vuse_optype.  Use generic interface.
	* tree-vrp.c (maybe_add_assert_expr): Use generic interface.
	(stmt_interesting_for_vrp, vrp_visit_stmt): Use ZERO_SSA_OPERANDS.
	* tree.h (struct ssa_imm_use_d): Renamed to ssa_use_operand_d.
	(tree_ssa_name, phi_arg_d): Use ssa_use_operand_d.
	* doc/tree-ssa.texi: Update documentation for operand interface.

From-SVN: r99155
parent 992d08b1
...@@ -705,8 +705,8 @@ Almost every GIMPLE statement will contain a reference to a variable ...@@ -705,8 +705,8 @@ Almost every GIMPLE statement will contain a reference to a variable
or memory location. Since statements come in different shapes and or memory location. Since statements come in different shapes and
sizes, their operands are going to be located at various spots inside sizes, their operands are going to be located at various spots inside
the statement's tree. To facilitate access to the statement's the statement's tree. To facilitate access to the statement's
operands, they are organized into arrays associated inside each operands, they are organized into lists associated inside each
statement's annotation. Each element in an operand array is a pointer statement's annotation. Each element in an operand list is a pointer
to a @code{VAR_DECL}, @code{PARM_DECL} or @code{SSA_NAME} tree node. to a @code{VAR_DECL}, @code{PARM_DECL} or @code{SSA_NAME} tree node.
This provides a very convenient way of examining and replacing This provides a very convenient way of examining and replacing
operands. operands.
...@@ -810,98 +810,58 @@ function is converted into SSA form. This will be used to link all ...@@ -810,98 +810,58 @@ function is converted into SSA form. This will be used to link all
the non-killing definitions to prevent optimizations from making the non-killing definitions to prevent optimizations from making
incorrect assumptions about them. incorrect assumptions about them.
Operands are collected by @file{tree-ssa-operands.c}. They are stored Operands are updated as soon as the statement is finished via a call
inside each statement's annotation and can be accessed with to @code{update_stmt}. If statement elements are changed via
@code{DEF_OPS}, @code{USE_OPS}, @code{V_MAY_DEF_OPS}, @code{SET_USE} or @code{SET_DEF}, then no further action is required
@code{V_MUST_DEF_OPS} and @code{VUSE_OPS}. The following are all the (ie, those macros take care of updating the statement). If changes
accessor macros available to access USE operands. To access all the are made by manipulating the statement's tree directly, then a call
other operand arrays, just change the name accordingly. Note that must be made to @code{update_stmt} when complete. Calling one of the
this interface to the operands is deprecated, and is slated for @code{bsi_insert} routines or @code{bsi_replace} performs an implicit
removal in a future version of gcc. The preferred interface is the call to @code{update_stmt}.
operand iterator interface. Unless you need to discover the number of
operands of a given type on a statement, you are strongly urged not to
use this interface.
@defmac USE_OPS (@var{ann})
Returns the array of operands used by the statement with annotation
@var{ann}.
@end defmac
@defmac STMT_USE_OPS (@var{stmt})
Alternate version of USE_OPS that takes the statement @var{stmt} as
input.
@end defmac
@defmac NUM_USES (@var{ops}) @subsection Operand Iterators And Access Routines
Return the number of USE operands in array @var{ops}. @cindex Operand Iterators
@end defmac @cindex Operand Access Routines
@defmac USE_OP_PTR (@var{ops}, @var{i}) Operands are collected by @file{tree-ssa-operands.c}. They are stored
Return a pointer to the @var{i}th operand in array @var{ops}. inside each statement's annotation and can be accessed through either the
@end defmac operand iterators or an access routine.
@defmac USE_OP (@var{ops}, @var{i}) The following access routines are available for examining operands:
Return the @var{i}th operand in array @var{ops}.
@end defmac
The following function shows how to print all the operands of a given @enumerate
statement: @item @code{SINGLE_SSA_@{USE,DEF,TREE@}_OPERAND}: These accessors will return
NULL unless there is exactly one operand mathcing the specified flags. If
there is exactly one operand, the operand is returned as either a @code{tree},
@code{def_operand_p}, or @code{use_operand_p}.
@smallexample @smallexample
void tree t = SINGLE_SSA_TREE_OPERAND (stmt, flags);
print_ops (tree stmt) use_operand_p u = SINGLE_SSA_USE_OPERAND (stmt, SSA_ALL_VIRTUAL_USES);
@{ def_operand_p d = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_ALL_DEFS);
vuse_optype vuses; @end smallexample
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
def_optype defs;
use_optype uses;
stmt_ann_t ann;
size_t i;
ann = stmt_ann (stmt);
defs = DEF_OPS (ann);
for (i = 0; i < NUM_DEFS (defs); i++)
print_generic_expr (stderr, DEF_OP (defs, i), 0);
uses = USE_OPS (ann);
for (i = 0; i < NUM_USES (uses); i++)
print_generic_expr (stderr, USE_OP (uses, 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);
print_generic_expr (stderr, V_MAY_DEF_RESULT (v_may_defs, i), 0);
@}
v_must_defs = V_MUST_DEF_OPS (ann); @item @code{ZERO_SSA_OPERANDS}: This macro returns true if there are no
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) operands matching the specified flags.
print_generic_expr (stderr, V_MUST_DEF_OP (v_must_defs, i), 0);
vuses = VUSE_OPS (ann); @smallexample
for (i = 0; i < NUM_VUSES (vuses); i++) if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
print_generic_expr (stderr, VUSE_OP (vuses, i), 0); return;
@}
@end smallexample @end smallexample
Operands are updated as soon as the statement is finished via a call @item @code{NUM_SSA_OPERANDS}: This macro Returns the number of operands
to @code{update_stmt}. If statement elements are changed via matching 'flags'. This actually executes a loop to perform the count, so
@code{SET_USE} or @code{SET_DEF}, then no further action is required only use this if it is really needed.
(ie, those macros take care of updating the statement). If changes
are made by manipulating the statement's tree directly, then a call @smallexample
must be made to @code{update_stmt} when complete. Calling one of the int count = NUM_SSA_OPERANDS (stmt, flags)
@code{bsi_insert} routines or @code{bsi_replace} performs an implicit @end smallexample
call to @code{update_stmt}. @end enumerate
@subsection Operand Iterators
@cindex Operand Iterators
There is an alternative to iterating over the operands in a statement. If you wish to iterate over some or all operands, use the
It is especially useful when you wish to perform the same operation on @code{FOR_EACH_SSA_@{USE,DEF,TREE@}_OPERAND} iterator. For example, to print
more than one type of operand. The previous example could be all the operands for a statement:
rewritten as follows:
@smallexample @smallexample
void void
...@@ -911,11 +871,13 @@ print_ops (tree stmt) ...@@ -911,11 +871,13 @@ print_ops (tree stmt)
tree var; tree var;
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_OPERANDS) FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_OPERANDS)
print_generic_expr (stderr, var, 0); print_generic_expr (stderr, var, TDF_SLIM);
@} @}
@end smallexample @end smallexample
How to choose the appropriate iterator:
@enumerate @enumerate
@item Determine whether you are need to see the operand pointers, or just the @item Determine whether you are need to see the operand pointers, or just the
trees, and choose the appropriate macro: trees, and choose the appropriate macro:
...@@ -966,7 +928,7 @@ So if you want to look at the use pointers for all the @code{USE} and ...@@ -966,7 +928,7 @@ So if you want to look at the use pointers for all the @code{USE} and
@} @}
@end smallexample @end smallexample
The @code{_TREE_} macro is basically the same as the @code{USE} and The @code{TREE} macro is basically the same as the @code{USE} and
@code{DEF} macros, only with the use or def dereferenced via @code{DEF} macros, only with the use or def dereferenced via
@code{USE_FROM_PTR (use_p)} and @code{DEF_FROM_PTR (def_p)}. Since we @code{USE_FROM_PTR (use_p)} and @code{DEF_FROM_PTR (def_p)}. Since we
aren't using operand pointers, use and defs flags can be mixed. aren't using operand pointers, use and defs flags can be mixed.
...@@ -1002,7 +964,7 @@ this one. ...@@ -1002,7 +964,7 @@ this one.
@code{V_MUST_DEF}s are broken into two flags, one for the @code{V_MUST_DEF}s are broken into two flags, one for the
@code{DEF} portion (@code{SSA_OP_VMUSTDEF}) and one for the kill portion @code{DEF} portion (@code{SSA_OP_VMUSTDEF}) and one for the kill portion
(@code{SSA_OP_VMUSTDEFKILL}). If all you want to look at are the (@code{SSA_OP_VMUSTKILL}). If all you want to look at are the
@code{V_MUST_DEF}s together, there is a fourth iterator macro for this, @code{V_MUST_DEF}s together, there is a fourth iterator macro for this,
which returns both a def_operand_p and a use_operand_p for each which returns both a def_operand_p and a use_operand_p for each
@code{V_MUST_DEF} in the statement. Note that you don't need any flags for @code{V_MUST_DEF} in the statement. Note that you don't need any flags for
...@@ -1023,6 +985,46 @@ this one. ...@@ -1023,6 +985,46 @@ this one.
There are many examples in the code as well, as well as the There are many examples in the code as well, as well as the
documentation in @file{tree-ssa-operands.h}. documentation in @file{tree-ssa-operands.h}.
There are also a couple of variants on the stmt iterators regarding PHI
nodes.
@code{FOR_EACH_PHI_ARG} Works exactly like
@code{FOR_EACH_SSA_USE_OPERAND}, except it works over @code{PHI} arguments
instead of statement operands.
@smallexample
/* Look at every virtual PHI use. */
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_VIRTUAL_USES)
@{
my_code;
@}
/* Look at every real PHI use. */
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_USES)
my_code;
/* Look at every every PHI use. */
FOR_EACH_PHI_ARG (use_p, phi_stmt, iter, SSA_OP_ALL_USES)
my_code;
@end smallexample
@code{FOR_EACH_PHI_OR_STMT_@{USE,DEF@}} works exactly like
@code{FOR_EACH_SSA_@{USE,DEF@}_OPERAND}, except it will function on
either a statement or a @code{PHI} node. These should be used when it is
appropriate but they are not quite as efficient as the individual
@code{FOR_EACH_PHI} and @code{FOR_EACH_SSA} routines.
@smallexample
FOR_EACH_PHI_OR_STMT_USE (use_operand_p, stmt, iter, flags)
@{
my_code;
@}
FOR_EACH_PHI_OR_STMT_DEF (def_operand_p, phi, iter, flags)
@{
my_code;
@}
@end smallexample
@subsection Immediate Uses @subsection Immediate Uses
@cindex Immediate Uses @cindex Immediate Uses
......
...@@ -1266,7 +1266,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth, ...@@ -1266,7 +1266,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
int stepint; int stepint;
int extra = 0; int extra = 0;
tree lboundvar, uboundvar, uboundresult; tree lboundvar, uboundvar, uboundresult;
use_optype uses;
/* Find out induction var and exit condition. */ /* Find out induction var and exit condition. */
inductionvar = find_induction_var_from_exit_cond (loop); inductionvar = find_induction_var_from_exit_cond (loop);
...@@ -1295,9 +1294,8 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth, ...@@ -1295,9 +1294,8 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
phi = SSA_NAME_DEF_STMT (inductionvar); phi = SSA_NAME_DEF_STMT (inductionvar);
if (TREE_CODE (phi) != PHI_NODE) if (TREE_CODE (phi) != PHI_NODE)
{ {
uses = STMT_USE_OPS (phi); phi = SINGLE_SSA_TREE_OPERAND (phi, SSA_OP_USE);
if (!phi)
if (!uses)
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -1307,7 +1305,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth, ...@@ -1307,7 +1305,6 @@ gcc_loop_to_lambda_loop (struct loop *loop, int depth,
return NULL; return NULL;
} }
phi = USE_OP (uses, 0);
phi = SSA_NAME_DEF_STMT (phi); phi = SSA_NAME_DEF_STMT (phi);
if (TREE_CODE (phi) != PHI_NODE) if (TREE_CODE (phi) != PHI_NODE)
{ {
...@@ -1972,12 +1969,11 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest, ...@@ -1972,12 +1969,11 @@ lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
tree oldiv_def; tree oldiv_def;
tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv); tree oldiv_stmt = SSA_NAME_DEF_STMT (oldiv);
gcc_assert (TREE_CODE (oldiv_stmt) == PHI_NODE
|| NUM_DEFS (STMT_DEF_OPS (oldiv_stmt)) == 1);
if (TREE_CODE (oldiv_stmt) == PHI_NODE) if (TREE_CODE (oldiv_stmt) == PHI_NODE)
oldiv_def = PHI_RESULT (oldiv_stmt); oldiv_def = PHI_RESULT (oldiv_stmt);
else else
oldiv_def = DEF_OP (STMT_DEF_OPS (oldiv_stmt), 0); oldiv_def = SINGLE_SSA_TREE_OPERAND (oldiv_stmt, SSA_OP_DEF);
gcc_assert (oldiv_def != NULL_TREE);
FOR_EACH_IMM_USE_SAFE (imm_use, imm_iter, oldiv_def) FOR_EACH_IMM_USE_SAFE (imm_use, imm_iter, oldiv_def)
{ {
...@@ -2069,16 +2065,11 @@ phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def) ...@@ -2069,16 +2065,11 @@ phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def)
static bool static bool
stmt_uses_phi_result (tree stmt, tree phi_result) stmt_uses_phi_result (tree stmt, tree phi_result)
{ {
use_optype uses = STMT_USE_OPS (stmt); tree use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
/* This is conservatively true, because we only want SIMPLE bumpers /* This is conservatively true, because we only want SIMPLE bumpers
of the form x +- constant for our pass. */ of the form x +- constant for our pass. */
if (NUM_USES (uses) != 1) return (use == phi_result);
return false;
if (USE_OP (uses, 0) == phi_result)
return true;
return false;
} }
/* STMT is a bumper stmt for LOOP if the version it defines is used in the /* STMT is a bumper stmt for LOOP if the version it defines is used in the
...@@ -2092,13 +2083,13 @@ stmt_is_bumper_for_loop (struct loop *loop, tree stmt) ...@@ -2092,13 +2083,13 @@ stmt_is_bumper_for_loop (struct loop *loop, tree stmt)
{ {
tree use; tree use;
tree def; tree def;
def_optype defs = STMT_DEF_OPS (stmt);
imm_use_iterator iter; imm_use_iterator iter;
use_operand_p use_p; use_operand_p use_p;
if (NUM_DEFS (defs) != 1) def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
if (!def)
return false; return false;
def = DEF_OP (defs, 0);
FOR_EACH_IMM_USE_FAST (use_p, iter, def) FOR_EACH_IMM_USE_FAST (use_p, iter, def)
{ {
use = USE_STMT (use_p); use = USE_STMT (use_p);
...@@ -2179,12 +2170,13 @@ perfect_nest_p (struct loop *loop) ...@@ -2179,12 +2170,13 @@ perfect_nest_p (struct loop *loop)
static void static void
replace_uses_of_x_with_y (tree stmt, tree x, tree y) replace_uses_of_x_with_y (tree stmt, tree x, tree y)
{ {
use_optype uses = STMT_USE_OPS (stmt); ssa_op_iter iter;
size_t i; use_operand_p use_p;
for (i = 0; i < NUM_USES (uses); i++)
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{ {
if (USE_OP (uses, i) == x) if (USE_FROM_PTR (use_p) == x)
SET_USE_OP (uses, i, y); SET_USE (use_p, y);
} }
} }
...@@ -2193,11 +2185,12 @@ replace_uses_of_x_with_y (tree stmt, tree x, tree y) ...@@ -2193,11 +2185,12 @@ replace_uses_of_x_with_y (tree stmt, tree x, tree y)
static bool static bool
stmt_uses_op (tree stmt, tree op) stmt_uses_op (tree stmt, tree op)
{ {
use_optype uses = STMT_USE_OPS (stmt); ssa_op_iter iter;
size_t i; tree use;
for (i = 0; i < NUM_USES (uses); i++)
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{ {
if (USE_OP (uses, i) == op) if (use == op)
return true; return true;
} }
return false; return false;
......
...@@ -2231,14 +2231,11 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs) ...@@ -2231,14 +2231,11 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
tree stmt = bsi_stmt (bsi); tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt);
if (TREE_CODE (stmt) != MODIFY_EXPR) if (TREE_CODE (stmt) != MODIFY_EXPR)
continue; continue;
if (!VUSE_OPS (ann) if (ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
&& !V_MUST_DEF_OPS (ann)
&& !V_MAY_DEF_OPS (ann))
continue; continue;
/* In the GIMPLE representation, a modify expression /* In the GIMPLE representation, a modify expression
...@@ -2269,8 +2266,7 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs) ...@@ -2269,8 +2266,7 @@ find_data_references_in_loop (struct loop *loop, varray_type *datarefs)
} }
/* When there are no defs in the loop, the loop is parallel. */ /* When there are no defs in the loop, the loop is parallel. */
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0 if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
|| NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
bb->loop_father->parallel_p = false; bb->loop_father->parallel_p = false;
} }
......
...@@ -482,15 +482,13 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED, ...@@ -482,15 +482,13 @@ collect_dfa_stats_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
{ {
case STMT_ANN: case STMT_ANN:
{ {
stmt_ann_t ann = (stmt_ann_t) t->common.ann;
dfa_stats_p->num_stmt_anns++; dfa_stats_p->num_stmt_anns++;
dfa_stats_p->num_defs += NUM_DEFS (DEF_OPS (ann)); dfa_stats_p->num_defs += NUM_SSA_OPERANDS (t, SSA_OP_DEF);
dfa_stats_p->num_uses += NUM_USES (USE_OPS (ann)); dfa_stats_p->num_uses += NUM_SSA_OPERANDS (t, SSA_OP_USE);
dfa_stats_p->num_v_may_defs += dfa_stats_p->num_v_may_defs += NUM_SSA_OPERANDS (t, SSA_OP_VMAYDEF);
NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)); dfa_stats_p->num_vuses += NUM_SSA_OPERANDS (t, SSA_OP_VUSE);
dfa_stats_p->num_vuses += NUM_VUSES (VUSE_OPS (ann)); dfa_stats_p->num_v_must_defs +=
dfa_stats_p->num_v_must_defs += NUM_SSA_OPERANDS (t, SSA_OP_VMUSTDEF);
NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann));
break; break;
} }
...@@ -642,8 +640,8 @@ mark_new_vars_to_rename (tree stmt) ...@@ -642,8 +640,8 @@ mark_new_vars_to_rename (tree stmt)
We flag them in a separate bitmap because we don't really want to We flag them in a separate bitmap because we don't really want to
rename them if there are not any newly exposed symbols in the rename them if there are not any newly exposed symbols in the
statement operands. */ statement operands. */
v_may_defs_before = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)); v_may_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
v_must_defs_before = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)); v_must_defs_before = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter,
SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF) SSA_OP_VMAYDEF | SSA_OP_VUSE | SSA_OP_VMUSTDEF)
...@@ -657,8 +655,8 @@ mark_new_vars_to_rename (tree stmt) ...@@ -657,8 +655,8 @@ mark_new_vars_to_rename (tree stmt)
exposed variables. */ exposed variables. */
update_stmt (stmt); update_stmt (stmt);
v_may_defs_after = NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)); v_may_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF);
v_must_defs_after = NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)); v_must_defs_after = NUM_SSA_OPERANDS (stmt, SSA_OP_VMUSTDEF);
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS) FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_ALL_OPERANDS)
if (DECL_P (val)) if (DECL_P (val))
......
...@@ -264,9 +264,9 @@ struct var_ann_d GTY(()) ...@@ -264,9 +264,9 @@ struct var_ann_d GTY(())
typedef struct immediate_use_iterator_d typedef struct immediate_use_iterator_d
{ {
ssa_imm_use_t *imm_use; ssa_use_operand_t *imm_use;
ssa_imm_use_t *end_p; ssa_use_operand_t *end_p;
ssa_imm_use_t iter_node; ssa_use_operand_t iter_node;
} imm_use_iterator; } imm_use_iterator;
...@@ -315,7 +315,7 @@ struct stmt_ann_d GTY(()) ...@@ -315,7 +315,7 @@ struct stmt_ann_d GTY(())
basic_block GTY ((skip (""))) bb; basic_block GTY ((skip (""))) bb;
/* Operand cache for stmt. */ /* Operand cache for stmt. */
struct stmt_operands_d operands; struct stmt_operands_d GTY ((skip (""))) operands;
/* Set of variables that have had their address taken in the statement. */ /* Set of variables that have had their address taken in the statement. */
bitmap addresses_taken; bitmap addresses_taken;
...@@ -362,10 +362,6 @@ static inline int get_lineno (tree); ...@@ -362,10 +362,6 @@ static inline int get_lineno (tree);
static inline const char *get_filename (tree); static inline const char *get_filename (tree);
static inline bool is_exec_stmt (tree); static inline bool is_exec_stmt (tree);
static inline bool is_label_stmt (tree); static inline bool is_label_stmt (tree);
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);
static inline bitmap addresses_taken (tree); static inline bitmap addresses_taken (tree);
static inline void set_default_def (tree, tree); static inline void set_default_def (tree, tree);
static inline tree default_def (tree); static inline tree default_def (tree);
...@@ -765,10 +761,10 @@ void print_value_expressions (FILE *, tree); ...@@ -765,10 +761,10 @@ void print_value_expressions (FILE *, tree);
/* In tree-vn.c */ /* In tree-vn.c */
bool expressions_equal_p (tree, tree); bool expressions_equal_p (tree, tree);
tree get_value_handle (tree); tree get_value_handle (tree);
hashval_t vn_compute (tree, hashval_t, vuse_optype); hashval_t vn_compute (tree, hashval_t, tree);
tree vn_lookup_or_add (tree, vuse_optype); tree vn_lookup_or_add (tree, tree);
void vn_add (tree, tree, vuse_optype); void vn_add (tree, tree, tree);
tree vn_lookup (tree, vuse_optype); tree vn_lookup (tree, tree);
void vn_init (void); void vn_init (void);
void vn_delete (void); void vn_delete (void);
......
...@@ -616,7 +616,7 @@ add_new_name_mapping (tree new, tree old) ...@@ -616,7 +616,7 @@ add_new_name_mapping (tree new, tree old)
for every variable in the function. For every statement S in block for every variable in the function. For every statement S in block
BB: BB:
1- Variables defined by S in DEF_OPS(S) are marked in the bitmap 1- Variables defined by S in the DEFS of S are marked in the bitmap
WALK_DATA->GLOBAL_DATA->KILLS. WALK_DATA->GLOBAL_DATA->KILLS.
2- If S uses a variable VAR and there is no preceding kill of VAR, 2- If S uses a variable VAR and there is no preceding kill of VAR,
...@@ -648,7 +648,7 @@ mark_def_sites (struct dom_walk_data *walk_data, ...@@ -648,7 +648,7 @@ mark_def_sites (struct dom_walk_data *walk_data,
/* If a variable is used before being set, then the variable is live /* If a variable is used before being set, then the variable is live
across a block boundary, so mark it live-on-entry to BB. */ across a block boundary, so mark it live-on-entry to BB. */
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTDEFKILL) SSA_OP_USE | SSA_OP_VUSE | SSA_OP_VMUSTKILL)
{ {
tree sym = USE_FROM_PTR (use_p); tree sym = USE_FROM_PTR (use_p);
gcc_assert (DECL_P (sym)); gcc_assert (DECL_P (sym));
......
...@@ -1444,12 +1444,8 @@ add_dependance (temp_expr_table_p tab, int version, tree var) ...@@ -1444,12 +1444,8 @@ add_dependance (temp_expr_table_p tab, int version, tree var)
static bool static bool
check_replaceable (temp_expr_table_p tab, tree stmt) check_replaceable (temp_expr_table_p tab, tree stmt)
{ {
stmt_ann_t ann;
vuse_optype vuseops;
def_optype defs;
use_optype uses;
tree var, def; tree var, def;
int num_use_ops, version; int version;
var_map map = tab->map; var_map map = tab->map;
ssa_op_iter iter; ssa_op_iter iter;
tree call_expr; tree call_expr;
...@@ -1457,22 +1453,16 @@ check_replaceable (temp_expr_table_p tab, tree stmt) ...@@ -1457,22 +1453,16 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
if (TREE_CODE (stmt) != MODIFY_EXPR) if (TREE_CODE (stmt) != MODIFY_EXPR)
return false; return false;
ann = stmt_ann (stmt);
defs = DEF_OPS (ann);
/* Punt if there is more than 1 def, or more than 1 use. */ /* Punt if there is more than 1 def, or more than 1 use. */
if (NUM_DEFS (defs) != 1) def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
return false; if (!def)
def = DEF_OP (defs, 0);
if (version_ref_count (map, def) != 1)
return false; return false;
/* There must be no V_MAY_DEFS. */ if (version_ref_count (map, def) != 1)
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) != 0)
return false; return false;
/* There must be no V_MUST_DEFS. */ /* There must be no V_MAY_DEFS or V_MUST_DEFS. */
if (NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) != 0) if (!(ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))))
return false; return false;
/* Float expressions must go through memory if float-store is on. */ /* Float expressions must go through memory if float-store is on. */
...@@ -1488,21 +1478,6 @@ check_replaceable (temp_expr_table_p tab, tree stmt) ...@@ -1488,21 +1478,6 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
return false; return false;
} }
uses = USE_OPS (ann);
num_use_ops = NUM_USES (uses);
vuseops = VUSE_OPS (ann);
/* Any expression which has no virtual operands and no real operands
should have been propagated if it's possible to do anything with them.
If this happens here, it probably exists that way for a reason, so we
won't touch it. An example is:
b_4 = &tab
There are no virtual uses nor any real uses, so we just leave this
alone to be safe. */
if (num_use_ops == 0 && NUM_VUSES (vuseops) == 0)
return false;
version = SSA_NAME_VERSION (def); version = SSA_NAME_VERSION (def);
/* Add this expression to the dependency list for each use partition. */ /* Add this expression to the dependency list for each use partition. */
...@@ -1512,7 +1487,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt) ...@@ -1512,7 +1487,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
} }
/* If there are VUSES, add a dependence on virtual defs. */ /* If there are VUSES, add a dependence on virtual defs. */
if (NUM_VUSES (vuseops) != 0) if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
{ {
add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]), add_value_to_list (tab, (value_expr_p *)&(tab->version_info[version]),
VIRTUAL_PARTITION (tab)); VIRTUAL_PARTITION (tab));
...@@ -1687,12 +1662,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb) ...@@ -1687,12 +1662,8 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
free_value_expr (tab, p); free_value_expr (tab, p);
} }
/* A V_MAY_DEF kills any expression using a virtual operand. */ /* A V_{MAY,MUST}_DEF kills any expression using a virtual operand. */
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0) if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
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); kill_virtual_exprs (tab, true);
} }
} }
...@@ -1743,7 +1714,8 @@ dump_replaceable_exprs (FILE *f, tree *expr) ...@@ -1743,7 +1714,8 @@ dump_replaceable_exprs (FILE *f, tree *expr)
if (expr[x]) if (expr[x])
{ {
stmt = expr[x]; stmt = expr[x];
var = DEF_OP (STMT_DEF_OPS (stmt), 0); var = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
gcc_assert (var != NULL_TREE);
print_generic_expr (f, var, TDF_SLIM); print_generic_expr (f, var, TDF_SLIM);
fprintf (f, " replace with --> "); fprintf (f, " replace with --> ");
print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM); print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
...@@ -1874,13 +1846,11 @@ rewrite_trees (var_map map, tree *values) ...@@ -1874,13 +1846,11 @@ rewrite_trees (var_map map, tree *values)
{ {
for (si = bsi_start (bb); !bsi_end_p (si); ) for (si = bsi_start (bb); !bsi_end_p (si); )
{ {
size_t num_uses, num_defs;
use_optype uses;
def_optype defs;
tree stmt = bsi_stmt (si); tree stmt = bsi_stmt (si);
use_operand_p use_p; use_operand_p use_p, copy_use_p;
def_operand_p def_p; def_operand_p def_p;
int remove = 0, is_copy = 0; bool remove = false, is_copy = false;
int num_uses = 0;
stmt_ann_t ann; stmt_ann_t ann;
ssa_op_iter iter; ssa_op_iter iter;
...@@ -1889,44 +1859,46 @@ rewrite_trees (var_map map, tree *values) ...@@ -1889,44 +1859,46 @@ rewrite_trees (var_map map, tree *values)
if (TREE_CODE (stmt) == MODIFY_EXPR if (TREE_CODE (stmt) == MODIFY_EXPR
&& (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)) && (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME))
is_copy = 1; is_copy = true;
uses = USE_OPS (ann); copy_use_p = NULL_USE_OPERAND_P;
num_uses = NUM_USES (uses);
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE) FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{ {
if (replace_use_variable (map, use_p, values)) if (replace_use_variable (map, use_p, values))
changed = true; changed = true;
copy_use_p = use_p;
num_uses++;
} }
defs = DEF_OPS (ann); if (num_uses != 1)
num_defs = NUM_DEFS (defs); is_copy = false;
/* Mark this stmt for removal if it is the list of replaceable def_p = SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF);
expressions. */
if (values && num_defs == 1) if (def_p != NULL)
{
tree def = DEF_OP (defs, 0);
tree val;
val = values[SSA_NAME_VERSION (def)];
if (val)
remove = 1;
}
if (!remove)
{ {
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF) /* Mark this stmt for removal if it is the list of replaceable
expressions. */
if (values && values[SSA_NAME_VERSION (DEF_FROM_PTR (def_p))])
remove = true;
else
{ {
if (replace_def_variable (map, def_p, NULL)) if (replace_def_variable (map, def_p, NULL))
changed = true; changed = true;
/* If both SSA_NAMEs coalesce to the same variable, /* If both SSA_NAMEs coalesce to the same variable,
mark the now redundant copy for removal. */ mark the now redundant copy for removal. */
if (is_copy if (is_copy)
&& num_uses == 1 {
&& (DEF_FROM_PTR (def_p) == USE_OP (uses, 0))) gcc_assert (copy_use_p != NULL_USE_OPERAND_P);
remove = 1; if (DEF_FROM_PTR (def_p) == USE_FROM_PTR (copy_use_p))
remove = true;
}
} }
} }
else
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
if (replace_def_variable (map, def_p, NULL))
changed = true;
/* Remove any stmts marked for removal. */ /* Remove any stmts marked for removal. */
if (remove) if (remove)
......
...@@ -226,7 +226,7 @@ make_phi_node (tree var, int len) ...@@ -226,7 +226,7 @@ make_phi_node (tree var, int len)
for (i = 0; i < capacity; i++) for (i = 0; i < capacity; i++)
{ {
ssa_imm_use_t * imm; use_operand_p imm;
imm = &(PHI_ARG_IMM_USE_NODE (phi, i)); imm = &(PHI_ARG_IMM_USE_NODE (phi, i));
imm->use = &(PHI_ARG_DEF_TREE (phi, i)); imm->use = &(PHI_ARG_DEF_TREE (phi, i));
imm->prev = NULL; imm->prev = NULL;
...@@ -247,7 +247,7 @@ release_phi_node (tree phi) ...@@ -247,7 +247,7 @@ release_phi_node (tree phi)
for (x = 0; x < PHI_NUM_ARGS (phi); x++) for (x = 0; x < PHI_NUM_ARGS (phi); x++)
{ {
ssa_imm_use_t * imm; use_operand_p imm;
imm = &(PHI_ARG_IMM_USE_NODE (phi, x)); imm = &(PHI_ARG_IMM_USE_NODE (phi, x));
delink_imm_use (imm); delink_imm_use (imm);
} }
...@@ -282,7 +282,7 @@ resize_phi_node (tree *phi, int len) ...@@ -282,7 +282,7 @@ resize_phi_node (tree *phi, int len)
for (i = 0; i < PHI_NUM_ARGS (new_phi); i++) for (i = 0; i < PHI_NUM_ARGS (new_phi); i++)
{ {
ssa_imm_use_t *imm, *old_imm; use_operand_p imm, old_imm;
imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i)); imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
old_imm = &(PHI_ARG_IMM_USE_NODE (*phi, i)); old_imm = &(PHI_ARG_IMM_USE_NODE (*phi, i));
imm->use = &(PHI_ARG_DEF_TREE (new_phi, i)); imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
...@@ -293,7 +293,7 @@ resize_phi_node (tree *phi, int len) ...@@ -293,7 +293,7 @@ resize_phi_node (tree *phi, int len)
for (i = PHI_NUM_ARGS (new_phi); i < len; i++) for (i = PHI_NUM_ARGS (new_phi); i < len; i++)
{ {
ssa_imm_use_t * imm; use_operand_p imm;
imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i)); imm = &(PHI_ARG_IMM_USE_NODE (new_phi, i));
imm->use = &(PHI_ARG_DEF_TREE (new_phi, i)); imm->use = &(PHI_ARG_DEF_TREE (new_phi, i));
imm->prev = NULL; imm->prev = NULL;
......
...@@ -2098,6 +2098,9 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) ...@@ -2098,6 +2098,9 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
use_operand_p kill_p; use_operand_p kill_p;
ssa_op_iter iter; ssa_op_iter iter;
if (!ssa_operands_active ())
return;
FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter) FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
{ {
pp_string (buffer, "# "); pp_string (buffer, "# ");
......
...@@ -897,9 +897,7 @@ sra_walk_function (const struct sra_walk_fns *fns) ...@@ -897,9 +897,7 @@ sra_walk_function (const struct sra_walk_fns *fns)
/* If the statement has no virtual operands, then it doesn't /* If the statement has no virtual operands, then it doesn't
make any structure references that we care about. */ make any structure references that we care about. */
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0 if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE)))
&& NUM_VUSES (VUSE_OPS (ann)) == 0
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
continue; continue;
switch (TREE_CODE (stmt)) switch (TREE_CODE (stmt))
......
...@@ -457,9 +457,7 @@ likely_value (tree stmt) ...@@ -457,9 +457,7 @@ likely_value (tree stmt)
if (!do_store_ccp if (!do_store_ccp
&& (ann->makes_aliased_stores && (ann->makes_aliased_stores
|| ann->makes_aliased_loads || ann->makes_aliased_loads
|| NUM_VUSES (VUSE_OPS (ann)) > 0 || !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)))
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0))
return VARYING; return VARYING;
...@@ -495,8 +493,8 @@ likely_value (tree stmt) ...@@ -495,8 +493,8 @@ likely_value (tree stmt)
} }
if (found_constant if (found_constant
|| NUM_USES (USE_OPS (ann)) == 0 || ZERO_SSA_OPERANDS (stmt, SSA_OP_USE)
|| NUM_VUSES (VUSE_OPS (ann)) == 0) || ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
return CONSTANT; return CONSTANT;
return UNDEFINED; return UNDEFINED;
...@@ -934,17 +932,18 @@ ccp_fold (tree stmt) ...@@ -934,17 +932,18 @@ ccp_fold (tree stmt)
== FUNCTION_DECL) == FUNCTION_DECL)
&& DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))) && DECL_BUILT_IN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
{ {
use_optype uses = STMT_USE_OPS (stmt); if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_USE))
if (NUM_USES (uses) != 0)
{ {
tree *orig; tree *orig, var;
tree fndecl, arglist; tree fndecl, arglist;
size_t i; size_t i = 0;
ssa_op_iter iter;
use_operand_p var_p;
/* Preserve the original values of every operand. */ /* Preserve the original values of every operand. */
orig = xmalloc (sizeof (tree) * NUM_USES (uses)); orig = xmalloc (sizeof (tree) * NUM_SSA_OPERANDS (stmt, SSA_OP_USE));
for (i = 0; i < NUM_USES (uses); i++) FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
orig[i] = USE_OP (uses, i); orig[i++] = var;
/* Substitute operands with their values and try to fold. */ /* Substitute operands with their values and try to fold. */
replace_uses_in (stmt, NULL, const_val); replace_uses_in (stmt, NULL, const_val);
...@@ -953,8 +952,9 @@ ccp_fold (tree stmt) ...@@ -953,8 +952,9 @@ ccp_fold (tree stmt)
retval = fold_builtin (fndecl, arglist, false); retval = fold_builtin (fndecl, arglist, false);
/* Restore operands to their original form. */ /* Restore operands to their original form. */
for (i = 0; i < NUM_USES (uses); i++) i = 0;
SET_USE_OP (uses, i, orig[i]); FOR_EACH_SSA_USE_OPERAND (var_p, stmt, iter, SSA_OP_USE)
SET_USE (var_p, orig[i++]);
free (orig); free (orig);
} }
} }
...@@ -1188,9 +1188,6 @@ visit_cond_stmt (tree stmt, edge *taken_edge_p) ...@@ -1188,9 +1188,6 @@ visit_cond_stmt (tree stmt, edge *taken_edge_p)
static enum ssa_prop_result static enum ssa_prop_result
ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p) ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
{ {
stmt_ann_t ann;
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
tree def; tree def;
ssa_op_iter iter; ssa_op_iter iter;
...@@ -1201,10 +1198,6 @@ ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p) ...@@ -1201,10 +1198,6 @@ ccp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
ann = stmt_ann (stmt);
v_must_defs = V_MUST_DEF_OPS (ann);
v_may_defs = V_MAY_DEF_OPS (ann);
if (TREE_CODE (stmt) == MODIFY_EXPR) if (TREE_CODE (stmt) == MODIFY_EXPR)
{ {
/* If the statement is an assignment that produces a single /* If the statement is an assignment that produces a single
...@@ -2206,18 +2199,19 @@ convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr) ...@@ -2206,18 +2199,19 @@ convert_to_gimple_builtin (block_stmt_iterator *si_p, tree expr)
tmp = get_initialized_tmp_var (expr, &stmts, NULL); tmp = get_initialized_tmp_var (expr, &stmts, NULL);
pop_gimplify_context (NULL); pop_gimplify_context (NULL);
if (EXPR_HAS_LOCATION (stmt))
annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
/* The replacement can expose previously unreferenced variables. */ /* The replacement can expose previously unreferenced variables. */
for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti)) for (ti = tsi_start (stmts); !tsi_end_p (ti); tsi_next (&ti))
{ {
tree new_stmt = tsi_stmt (ti);
find_new_referenced_vars (tsi_stmt_ptr (ti)); find_new_referenced_vars (tsi_stmt_ptr (ti));
mark_new_vars_to_rename (tsi_stmt (ti)); bsi_insert_before (si_p, new_stmt, BSI_NEW_STMT);
mark_new_vars_to_rename (bsi_stmt (*si_p));
bsi_next (si_p);
} }
if (EXPR_HAS_LOCATION (stmt))
annotate_all_with_locus (&stmts, EXPR_LOCATION (stmt));
bsi_insert_before (si_p, stmts, BSI_SAME_STMT);
return tmp; return tmp;
} }
......
...@@ -360,9 +360,7 @@ stmt_may_generate_copy (tree stmt) ...@@ -360,9 +360,7 @@ stmt_may_generate_copy (tree stmt)
/* If we are not doing store copy-prop, statements with loads and/or /* If we are not doing store copy-prop, statements with loads and/or
stores will never generate a useful copy. */ stores will never generate a useful copy. */
if (!do_store_copy_prop if (!do_store_copy_prop
&& (NUM_VUSES (VUSE_OPS (ann)) > 0 && !ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0))
return false; return false;
/* Otherwise, the only statements that generate useful copies are /* Otherwise, the only statements that generate useful copies are
...@@ -596,26 +594,31 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p) ...@@ -596,26 +594,31 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
{ {
enum ssa_prop_result retval; enum ssa_prop_result retval;
tree cond; tree cond;
use_optype uses; use_operand_p use_p;
ssa_op_iter iter;
unsigned num;
cond = COND_EXPR_COND (stmt); cond = COND_EXPR_COND (stmt);
uses = STMT_USE_OPS (stmt);
retval = SSA_PROP_VARYING; retval = SSA_PROP_VARYING;
num = NUM_SSA_OPERANDS (stmt, SSA_OP_USE);
/* The only conditionals that we may be able to compute statically /* The only conditionals that we may be able to compute statically
are predicates involving at least one SSA_NAME. */ are predicates involving at least one SSA_NAME. */
if (COMPARISON_CLASS_P (cond) if (COMPARISON_CLASS_P (cond)
&& NUM_USES (uses) >= 1) && num >= 1)
{ {
unsigned i; unsigned i;
tree *orig; tree *orig;
/* Save the original operands. */ /* Save the original operands. */
orig = xmalloc (sizeof (tree) * NUM_USES (uses)); orig = xmalloc (sizeof (tree) * num);
for (i = 0; i < NUM_USES (uses); i++) i = 0;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
{ {
orig[i] = USE_OP (uses, i); tree use = USE_FROM_PTR (use_p);
SET_USE_OP (uses, i, get_last_copy_of (USE_OP (uses, i))); orig[i++] = use;
SET_USE (use_p, get_last_copy_of (use));
} }
/* See if we can determine the predicate's value. */ /* See if we can determine the predicate's value. */
...@@ -638,8 +641,9 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p) ...@@ -638,8 +641,9 @@ copy_prop_visit_cond_stmt (tree stmt, edge *taken_edge_p)
} }
/* Restore the original operands. */ /* Restore the original operands. */
for (i = 0; i < NUM_USES (uses); i++) i = 0;
SET_USE_OP (uses, i, orig[i]); FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
SET_USE (use_p, orig[i++]);
free (orig); free (orig);
} }
......
...@@ -124,8 +124,8 @@ struct expr_hash_elt ...@@ -124,8 +124,8 @@ struct expr_hash_elt
/* The expression (rhs) we want to record. */ /* The expression (rhs) we want to record. */
tree rhs; tree rhs;
/* The annotation if this element corresponds to a statement. */ /* The stmt pointer if this element corresponds to a statement. */
stmt_ann_t ann; tree stmt;
/* The hash value for RHS/ann. */ /* The hash value for RHS/ann. */
hashval_t hash; hashval_t hash;
...@@ -675,36 +675,26 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -675,36 +675,26 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
else else
{ {
/* Copy the operands. */ /* Copy the operands. */
stmt_ann_t ann = stmt_ann (stmt); tree *copy;
use_optype uses = USE_OPS (ann); ssa_op_iter iter;
vuse_optype vuses = VUSE_OPS (ann); use_operand_p use_p;
tree *uses_copy = xmalloc (NUM_USES (uses) * sizeof (tree)); unsigned int num, i = 0;
tree *vuses_copy = xmalloc (NUM_VUSES (vuses) * sizeof (tree));
unsigned int i;
/* Make a copy of the uses into USES_COPY, then cprop into num = NUM_SSA_OPERANDS (stmt, (SSA_OP_USE | SSA_OP_VUSE));
the use operands. */ copy = xcalloc (num, sizeof (tree));
for (i = 0; i < NUM_USES (uses); i++)
{
tree tmp = NULL;
uses_copy[i] = USE_OP (uses, i); /* Make a copy of the uses & vuses into USES_COPY, then cprop into
if (TREE_CODE (USE_OP (uses, i)) == SSA_NAME) the operands. */
tmp = SSA_NAME_VALUE (USE_OP (uses, i)); FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
SET_USE_OP (uses, i, tmp);
}
/* Similarly for virtual uses. */
for (i = 0; i < NUM_VUSES (vuses); i++)
{ {
tree tmp = NULL; tree tmp = NULL;
tree use = USE_FROM_PTR (use_p);
vuses_copy[i] = VUSE_OP (vuses, i); copy[i++] = use;
if (TREE_CODE (VUSE_OP (vuses, i)) == SSA_NAME) if (TREE_CODE (use) == SSA_NAME)
tmp = SSA_NAME_VALUE (VUSE_OP (vuses, i)); tmp = SSA_NAME_VALUE (use);
if (tmp && TREE_CODE (tmp) != VALUE_HANDLE) if (tmp && TREE_CODE (tmp) != VALUE_HANDLE)
SET_VUSE_OP (vuses, i, tmp); SET_USE (use_p, tmp);
} }
/* Try to fold/lookup the new expression. Inserting the /* Try to fold/lookup the new expression. Inserting the
...@@ -715,15 +705,13 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e) ...@@ -715,15 +705,13 @@ thread_across_edge (struct dom_walk_data *walk_data, edge e)
&& !is_gimple_min_invariant (cached_lhs)) && !is_gimple_min_invariant (cached_lhs))
cached_lhs = lookup_avail_expr (stmt, false); cached_lhs = lookup_avail_expr (stmt, false);
/* Restore the statement's original uses/defs. */
for (i = 0; i < NUM_USES (uses); i++)
SET_USE_OP (uses, i, uses_copy[i]);
for (i = 0; i < NUM_VUSES (vuses); i++) /* Restore the statement's original uses/defs. */
SET_VUSE_OP (vuses, i, vuses_copy[i]); i = 0;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE | SSA_OP_VUSE)
SET_USE (use_p, copy[i++]);
free (uses_copy); free (copy);
free (vuses_copy);
} }
/* Record the context sensitive equivalence if we were able /* Record the context sensitive equivalence if we were able
...@@ -885,32 +873,32 @@ initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element) ...@@ -885,32 +873,32 @@ initialize_hash_element (tree expr, tree lhs, struct expr_hash_elt *element)
we want to record the expression the statement evaluates. */ we want to record the expression the statement evaluates. */
if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR) if (COMPARISON_CLASS_P (expr) || TREE_CODE (expr) == TRUTH_NOT_EXPR)
{ {
element->ann = NULL; element->stmt = NULL;
element->rhs = expr; element->rhs = expr;
} }
else if (TREE_CODE (expr) == COND_EXPR) else if (TREE_CODE (expr) == COND_EXPR)
{ {
element->ann = stmt_ann (expr); element->stmt = expr;
element->rhs = COND_EXPR_COND (expr); element->rhs = COND_EXPR_COND (expr);
} }
else if (TREE_CODE (expr) == SWITCH_EXPR) else if (TREE_CODE (expr) == SWITCH_EXPR)
{ {
element->ann = stmt_ann (expr); element->stmt = expr;
element->rhs = SWITCH_COND (expr); element->rhs = SWITCH_COND (expr);
} }
else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0)) else if (TREE_CODE (expr) == RETURN_EXPR && TREE_OPERAND (expr, 0))
{ {
element->ann = stmt_ann (expr); element->stmt = expr;
element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1); element->rhs = TREE_OPERAND (TREE_OPERAND (expr, 0), 1);
} }
else if (TREE_CODE (expr) == GOTO_EXPR) else if (TREE_CODE (expr) == GOTO_EXPR)
{ {
element->ann = stmt_ann (expr); element->stmt = expr;
element->rhs = GOTO_DESTINATION (expr); element->rhs = GOTO_DESTINATION (expr);
} }
else else
{ {
element->ann = stmt_ann (expr); element->stmt = expr;
element->rhs = TREE_OPERAND (expr, 1); element->rhs = TREE_OPERAND (expr, 1);
} }
...@@ -2608,7 +2596,6 @@ static bool ...@@ -2608,7 +2596,6 @@ static bool
eliminate_redundant_computations (struct dom_walk_data *walk_data, eliminate_redundant_computations (struct dom_walk_data *walk_data,
tree stmt, stmt_ann_t ann) tree stmt, stmt_ann_t ann)
{ {
v_may_def_optype v_may_defs = V_MAY_DEF_OPS (ann);
tree *expr_p, def = NULL_TREE; tree *expr_p, def = NULL_TREE;
bool insert = true; bool insert = true;
tree cached_lhs; tree cached_lhs;
...@@ -2623,7 +2610,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data, ...@@ -2623,7 +2610,7 @@ eliminate_redundant_computations (struct dom_walk_data *walk_data,
|| ! def || ! def
|| TREE_CODE (def) != SSA_NAME || TREE_CODE (def) != SSA_NAME
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def) || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (def)
|| NUM_V_MAY_DEFS (v_may_defs) != 0 || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF)
/* Do not record equivalences for increments of ivs. This would create /* Do not record equivalences for increments of ivs. This would create
overlapping live ranges for a very questionable gain. */ overlapping live ranges for a very questionable gain. */
|| simple_iv_increment_p (stmt)) || simple_iv_increment_p (stmt))
...@@ -2804,7 +2791,7 @@ record_equivalences_from_stmt (tree stmt, ...@@ -2804,7 +2791,7 @@ record_equivalences_from_stmt (tree stmt,
/* Build a new statement with the RHS and LHS exchanged. */ /* Build a new statement with the RHS and LHS exchanged. */
new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs); new = build (MODIFY_EXPR, TREE_TYPE (stmt), rhs, lhs);
create_ssa_artficial_load_stmt (&(ann->operands), new); create_ssa_artficial_load_stmt (new, stmt);
/* Finally enter the statement into the available expression /* Finally enter the statement into the available expression
table. */ table. */
...@@ -3391,11 +3378,11 @@ vrp_eq (const void *p1, const void *p2) ...@@ -3391,11 +3378,11 @@ vrp_eq (const void *p1, const void *p2)
static hashval_t static hashval_t
avail_expr_hash (const void *p) avail_expr_hash (const void *p)
{ {
stmt_ann_t ann = ((struct expr_hash_elt *)p)->ann; tree stmt = ((struct expr_hash_elt *)p)->stmt;
tree rhs = ((struct expr_hash_elt *)p)->rhs; tree rhs = ((struct expr_hash_elt *)p)->rhs;
tree vuse;
ssa_op_iter iter;
hashval_t val = 0; hashval_t val = 0;
size_t i;
vuse_optype vuses;
/* iterative_hash_expr knows how to deal with any expression and /* iterative_hash_expr knows how to deal with any expression and
deals with commutative operators as well, so just use it instead deals with commutative operators as well, so just use it instead
...@@ -3405,16 +3392,15 @@ avail_expr_hash (const void *p) ...@@ -3405,16 +3392,15 @@ avail_expr_hash (const void *p)
/* If the hash table entry is not associated with a statement, then we /* If the hash table entry is not associated with a statement, then we
can just hash the expression and not worry about virtual operands can just hash the expression and not worry about virtual operands
and such. */ and such. */
if (!ann) if (!stmt || !stmt_ann (stmt))
return val; return val;
/* Add the SSA version numbers of every vuse operand. This is important /* Add the SSA version numbers of every vuse operand. This is important
because compound variables like arrays are not renamed in the because compound variables like arrays are not renamed in the
operands. Rather, the rename is done on the virtual variable operands. Rather, the rename is done on the virtual variable
representing all the elements of the array. */ representing all the elements of the array. */
vuses = VUSE_OPS (ann); FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
for (i = 0; i < NUM_VUSES (vuses); i++) val = iterative_hash_expr (vuse, val);
val = iterative_hash_expr (VUSE_OP (vuses, i), val);
return val; return val;
} }
...@@ -3428,13 +3414,13 @@ real_avail_expr_hash (const void *p) ...@@ -3428,13 +3414,13 @@ real_avail_expr_hash (const void *p)
static int static int
avail_expr_eq (const void *p1, const void *p2) avail_expr_eq (const void *p1, const void *p2)
{ {
stmt_ann_t ann1 = ((struct expr_hash_elt *)p1)->ann; tree stmt1 = ((struct expr_hash_elt *)p1)->stmt;
tree rhs1 = ((struct expr_hash_elt *)p1)->rhs; tree rhs1 = ((struct expr_hash_elt *)p1)->rhs;
stmt_ann_t ann2 = ((struct expr_hash_elt *)p2)->ann; tree stmt2 = ((struct expr_hash_elt *)p2)->stmt;
tree rhs2 = ((struct expr_hash_elt *)p2)->rhs; tree rhs2 = ((struct expr_hash_elt *)p2)->rhs;
/* If they are the same physical expression, return true. */ /* If they are the same physical expression, return true. */
if (rhs1 == rhs2 && ann1 == ann2) if (rhs1 == rhs2 && stmt1 == stmt2)
return true; return true;
/* If their codes are not equal, then quit now. */ /* If their codes are not equal, then quit now. */
...@@ -3447,36 +3433,10 @@ avail_expr_eq (const void *p1, const void *p2) ...@@ -3447,36 +3433,10 @@ avail_expr_eq (const void *p1, const void *p2)
|| lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2))) || lang_hooks.types_compatible_p (TREE_TYPE (rhs1), TREE_TYPE (rhs2)))
&& operand_equal_p (rhs1, rhs2, OEP_PURE_SAME)) && operand_equal_p (rhs1, rhs2, OEP_PURE_SAME))
{ {
vuse_optype ops1 = NULL; bool ret = compare_ssa_operands_equal (stmt1, stmt2, SSA_OP_VUSE);
vuse_optype ops2 = NULL; gcc_assert (!ret || ((struct expr_hash_elt *)p1)->hash
size_t num_ops1 = 0;
size_t num_ops2 = 0;
size_t i;
if (ann1)
{
ops1 = VUSE_OPS (ann1);
num_ops1 = NUM_VUSES (ops1);
}
if (ann2)
{
ops2 = VUSE_OPS (ann2);
num_ops2 = NUM_VUSES (ops2);
}
/* If the number of virtual uses is different, then we consider
them not equal. */
if (num_ops1 != num_ops2)
return false;
for (i = 0; i < num_ops1; i++)
if (VUSE_OP (ops1, i) != VUSE_OP (ops2, i))
return false;
gcc_assert (((struct expr_hash_elt *)p1)->hash
== ((struct expr_hash_elt *)p2)->hash); == ((struct expr_hash_elt *)p2)->hash);
return true; return ret;
} }
return false; return false;
......
...@@ -167,16 +167,10 @@ dse_optimize_stmt (struct dom_walk_data *walk_data, ...@@ -167,16 +167,10 @@ dse_optimize_stmt (struct dom_walk_data *walk_data,
struct dse_global_data *dse_gd = walk_data->global_data; struct dse_global_data *dse_gd = walk_data->global_data;
tree stmt = bsi_stmt (bsi); tree stmt = bsi_stmt (bsi);
stmt_ann_t ann = stmt_ann (stmt); stmt_ann_t ann = stmt_ann (stmt);
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
v_may_defs = V_MAY_DEF_OPS (ann);
v_must_defs = V_MUST_DEF_OPS (ann);
/* If this statement has no virtual defs, then there is nothing /* If this statement has no virtual defs, then there is nothing
to do. */ to do. */
if (NUM_V_MAY_DEFS (v_may_defs) == 0 if (ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF)))
&& NUM_V_MUST_DEFS (v_must_defs) == 0)
return; return;
/* We know we have virtual definitions. If this is a MODIFY_EXPR that's /* We know we have virtual definitions. If this is a MODIFY_EXPR that's
......
...@@ -1578,25 +1578,13 @@ fail: ...@@ -1578,25 +1578,13 @@ fail:
static void static void
find_invariants_stmt (struct ivopts_data *data, tree stmt) find_invariants_stmt (struct ivopts_data *data, tree stmt)
{ {
use_optype uses = NULL; ssa_op_iter iter;
unsigned i, n; use_operand_p use_p;
tree op; tree op;
if (TREE_CODE (stmt) == PHI_NODE) FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
n = PHI_NUM_ARGS (stmt);
else
{
uses = STMT_USE_OPS (stmt);
n = NUM_USES (uses);
}
for (i = 0; i < n; i++)
{ {
if (TREE_CODE (stmt) == PHI_NODE) op = USE_FROM_PTR (use_p);
op = PHI_ARG_DEF (stmt, i);
else
op = USE_OP (uses, i);
record_invariant (data, op, false); record_invariant (data, op, false);
} }
} }
...@@ -1608,8 +1596,8 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt) ...@@ -1608,8 +1596,8 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
{ {
struct iv *iv; struct iv *iv;
tree op, lhs, rhs; tree op, lhs, rhs;
use_optype uses = NULL; ssa_op_iter iter;
unsigned i, n; use_operand_p use_p;
find_invariants_stmt (data, stmt); find_invariants_stmt (data, stmt);
...@@ -1677,20 +1665,9 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt) ...@@ -1677,20 +1665,9 @@ find_interesting_uses_stmt (struct ivopts_data *data, tree stmt)
return; return;
} }
if (TREE_CODE (stmt) == PHI_NODE) FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_USE)
n = PHI_NUM_ARGS (stmt);
else
{
uses = STMT_USE_OPS (stmt);
n = NUM_USES (uses);
}
for (i = 0; i < n; i++)
{ {
if (TREE_CODE (stmt) == PHI_NODE) op = USE_FROM_PTR (use_p);
op = PHI_ARG_DEF (stmt, i);
else
op = USE_OP (uses, i);
if (TREE_CODE (op) != SSA_NAME) if (TREE_CODE (op) != SSA_NAME)
continue; continue;
...@@ -5577,22 +5554,11 @@ protect_loop_closed_ssa_form_use (edge exit, use_operand_p op_p) ...@@ -5577,22 +5554,11 @@ protect_loop_closed_ssa_form_use (edge exit, use_operand_p op_p)
static void static void
protect_loop_closed_ssa_form (edge exit, tree stmt) protect_loop_closed_ssa_form (edge exit, tree stmt)
{ {
use_optype uses; ssa_op_iter iter;
vuse_optype vuses; use_operand_p use_p;
v_may_def_optype v_may_defs;
unsigned i;
uses = STMT_USE_OPS (stmt);
for (i = 0; i < NUM_USES (uses); i++)
protect_loop_closed_ssa_form_use (exit, USE_OP_PTR (uses, i));
vuses = STMT_VUSE_OPS (stmt);
for (i = 0; i < NUM_VUSES (vuses); i++)
protect_loop_closed_ssa_form_use (exit, VUSE_OP_PTR (vuses, i));
v_may_defs = STMT_V_MAY_DEF_OPS (stmt); FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++) protect_loop_closed_ssa_form_use (exit, use_p);
protect_loop_closed_ssa_form_use (exit, V_MAY_DEF_OP_PTR (v_may_defs, i));
} }
/* STMTS compute a value of a phi argument OP on EXIT of a loop. Arrange things /* STMTS compute a value of a phi argument OP on EXIT of a loop. Arrange things
......
...@@ -1081,8 +1081,8 @@ static tree ...@@ -1081,8 +1081,8 @@ static tree
chain_of_csts_start (struct loop *loop, tree x) chain_of_csts_start (struct loop *loop, tree x)
{ {
tree stmt = SSA_NAME_DEF_STMT (x); tree stmt = SSA_NAME_DEF_STMT (x);
tree use;
basic_block bb = bb_for_stmt (stmt); basic_block bb = bb_for_stmt (stmt);
use_optype uses;
if (!bb if (!bb
|| !flow_bb_inside_loop_p (loop, bb)) || !flow_bb_inside_loop_p (loop, bb))
...@@ -1099,19 +1099,16 @@ chain_of_csts_start (struct loop *loop, tree x) ...@@ -1099,19 +1099,16 @@ chain_of_csts_start (struct loop *loop, tree x)
if (TREE_CODE (stmt) != MODIFY_EXPR) if (TREE_CODE (stmt) != MODIFY_EXPR)
return NULL_TREE; return NULL_TREE;
if (NUM_VUSES (STMT_VUSE_OPS (stmt)) > 0) if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
return NULL_TREE; return NULL_TREE;
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0) if (SINGLE_SSA_DEF_OPERAND (stmt, SSA_OP_DEF) == NULL_DEF_OPERAND_P)
return NULL_TREE; return NULL_TREE;
if (NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
return NULL_TREE; use = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_USE);
if (NUM_DEFS (STMT_DEF_OPS (stmt)) > 1) if (use == NULL_USE_OPERAND_P)
return NULL_TREE;
uses = STMT_USE_OPS (stmt);
if (NUM_USES (uses) != 1)
return NULL_TREE; return NULL_TREE;
return chain_of_csts_start (loop, USE_OP (uses, 0)); return chain_of_csts_start (loop, use);
} }
/* Determines whether the expression X is derived from a result of a phi node /* Determines whether the expression X is derived from a result of a phi node
...@@ -1164,8 +1161,8 @@ static tree ...@@ -1164,8 +1161,8 @@ static tree
get_val_for (tree x, tree base) get_val_for (tree x, tree base)
{ {
tree stmt, nx, val; tree stmt, nx, val;
use_optype uses;
use_operand_p op; use_operand_p op;
ssa_op_iter iter;
if (!x) if (!x)
return base; return base;
...@@ -1174,16 +1171,19 @@ get_val_for (tree x, tree base) ...@@ -1174,16 +1171,19 @@ get_val_for (tree x, tree base)
if (TREE_CODE (stmt) == PHI_NODE) if (TREE_CODE (stmt) == PHI_NODE)
return base; return base;
uses = STMT_USE_OPS (stmt); FOR_EACH_SSA_USE_OPERAND (op, stmt, iter, SSA_OP_USE)
op = USE_OP_PTR (uses, 0); {
nx = USE_FROM_PTR (op);
nx = USE_FROM_PTR (op); val = get_val_for (nx, base);
val = get_val_for (nx, base); SET_USE (op, val);
SET_USE (op, val); val = fold (TREE_OPERAND (stmt, 1));
val = fold (TREE_OPERAND (stmt, 1)); SET_USE (op, nx);
SET_USE (op, nx); /* only iterate loop once. */
return val;
}
return val; /* Should never reach here. */
gcc_unreachable();
} }
/* Tries to count the number of iterations of LOOP till it exits by EXIT /* Tries to count the number of iterations of LOOP till it exits by EXIT
......
...@@ -113,10 +113,9 @@ tree_ssa_unswitch_loops (struct loops *loops) ...@@ -113,10 +113,9 @@ tree_ssa_unswitch_loops (struct loops *loops)
static tree static tree
tree_may_unswitch_on (basic_block bb, struct loop *loop) tree_may_unswitch_on (basic_block bb, struct loop *loop)
{ {
tree stmt, def, cond; tree stmt, def, cond, use;
basic_block def_bb; basic_block def_bb;
use_optype uses; ssa_op_iter iter;
unsigned i;
/* BB must end in a simple conditional jump. */ /* BB must end in a simple conditional jump. */
stmt = last_stmt (bb); stmt = last_stmt (bb);
...@@ -124,10 +123,9 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop) ...@@ -124,10 +123,9 @@ tree_may_unswitch_on (basic_block bb, struct loop *loop)
return NULL_TREE; return NULL_TREE;
/* Condition must be invariant. */ /* Condition must be invariant. */
uses = STMT_USE_OPS (stmt); FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
for (i = 0; i < NUM_USES (uses); i++)
{ {
def = SSA_NAME_DEF_STMT (USE_OP (uses, i)); def = SSA_NAME_DEF_STMT (use);
def_bb = bb_for_stmt (def); def_bb = bb_for_stmt (def);
if (def_bb if (def_bb
&& flow_bb_inside_loop_p (loop, def_bb)) && flow_bb_inside_loop_p (loop, def_bb))
......
/* SSA operand allocation and finalizing.
Copyright (C) 2005 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
/* This file contains common code which is used by each of the 5 operand
types. Macros are defined to specify the varying componenets.
FINALIZE_FUNC - name of finalize function.
FINALIZE_ALLOC - name of allocation routine.
FINALIZE_FREE - name of free list.
FINALIZE_TYPE - type of node.
FINALIZE_OPS - Lead element in list.
FINALIZE_USE_PTR - How to get the use_operand_p, if this is a use operand.
FINALIZE_INITIALIZE - How to initialize an element.
FINALIZE_ELEM - How to retreive an element.
FINALIZE_BASE - How to retreive the base variable of an element.
FINALIZE_BASE_TYPE - Type of the base variable.
FINALIZE_OPBUILD - Opbuild array for these nodes.
FINALIZE_OPBUILD_ELEM - How to get an element from the opbuild list.
FINALIZE_OPBUILD_BASE - How to get an element base from the opbuild list.
FINALIZE_BASE_ZERO - How to zero an element. */
/* This routine will either pick up a node from the free list, or allocate a
new one if need be. */
static inline FINALIZE_TYPE *
FINALIZE_ALLOC (void)
{
FINALIZE_TYPE *ret;
if (FINALIZE_FREE)
{
ret = FINALIZE_FREE;
FINALIZE_FREE = FINALIZE_FREE->next;
}
else
ret = (FINALIZE_TYPE *)ssa_operand_alloc (sizeof (FINALIZE_TYPE));
return ret;
}
/* This routine will take the new operands from FINALIZE_OPBUILD and turn them
into the new operands for STMT. All required linking and deleting is u
performed here. */
static inline void
FINALIZE_FUNC (tree stmt)
{
int new_i;
FINALIZE_TYPE *old_ops, *ptr, *last;
FINALIZE_BASE_TYPE old_base;
FINALIZE_TYPE new_list;
new_list.next = NULL;
last = &new_list;
old_ops = FINALIZE_OPS (stmt);
if (old_ops)
old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
else
old_base = FINALIZE_BASE_ZERO;
new_i = opbuild_first (&FINALIZE_OPBUILD);
while (old_ops && new_i != OPBUILD_LAST)
{
FINALIZE_BASE_TYPE new_base = FINALIZE_OPBUILD_BASE (new_i);
if (old_base == new_base)
{
/* if variables are the same, reuse this node. */
last->next = old_ops;
last = old_ops;
#ifdef FINALIZE_USE_PTR
correct_use_link (FINALIZE_USE_PTR (last), stmt);
#endif
old_ops = old_ops->next;
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
}
else
if (old_base < new_base)
{
/* if old is less than new, old goes to the free list. */
#ifdef FINALIZE_USE_PTR
use_operand_p use_p = FINALIZE_USE_PTR (old_ops);
delink_imm_use (use_p);
#endif
ptr = old_ops;
old_ops = old_ops->next;
ptr->next = FINALIZE_FREE;
FINALIZE_FREE = ptr;
}
else
{
/* This is a new operand. */
ptr = FINALIZE_ALLOC ();
FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
last->next = ptr;
last = ptr;
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i);
}
if (old_ops)
old_base = FINALIZE_BASE (FINALIZE_ELEM (old_ops));
}
/* If there is anything remaining in the opbuild list, simply emit them. */
for ( ;
new_i != OPBUILD_LAST;
new_i = opbuild_next (&FINALIZE_OPBUILD, new_i))
{
ptr = FINALIZE_ALLOC ();
FINALIZE_INITIALIZE (ptr, FINALIZE_OPBUILD_ELEM (new_i), stmt);
last->next = ptr;
last = ptr;
}
last->next = NULL;
/* If there is anything in the old list, free them. */
if (old_ops)
{
#ifdef FINALIZE_USE_PTR
for (ptr = old_ops; ptr; ptr = ptr->next)
{
use_operand_p use_p = FINALIZE_USE_PTR (ptr);
delink_imm_use (use_p);
}
#endif
old_ops->next = FINALIZE_FREE;
FINALIZE_FREE = old_ops;
}
/* NOw set the stmt's operands. */
FINALIZE_OPS (stmt) = new_list.next;
#ifdef ENABLE_CHECKING
{
unsigned x = 0;
for (ptr = FINALIZE_OPS (stmt); ptr; ptr = ptr->next)
x++;
gcc_assert (x == opbuild_num_elems (&FINALIZE_OPBUILD));
}
#endif
}
#undef FINALIZE_FUNC
#undef FINALIZE_ALLOC
#undef FINALIZE_FREE
#undef FINALIZE_TYPE
#undef FINALIZE_OPS
#undef FINALIZE_USE_PTR
#undef FINALIZE_INITIALIZE
#undef FINALIZE_ELEM
#undef FINALIZE_BASE
#undef FINALIZE_BASE_TYPE
#undef FINALIZE_OPBUILD
#undef FINALIZE_OPBUILD_ELEM
#undef FINALIZE_OPBUILD_BASE
#undef FINALIZE_BASE_ZERO
...@@ -1758,17 +1758,17 @@ is_undefined_value (tree expr) ...@@ -1758,17 +1758,17 @@ is_undefined_value (tree expr)
any). They are used when computing the hash value for EXPR. */ any). They are used when computing the hash value for EXPR. */
static inline void static inline void
add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1, add_to_sets (tree var, tree expr, tree stmt, bitmap_set_t s1,
bitmap_set_t s2) bitmap_set_t s2)
{ {
tree val = vn_lookup_or_add (expr, vuses); tree val = vn_lookup_or_add (expr, stmt);
/* VAR and EXPR may be the same when processing statements for which /* VAR and EXPR may be the same when processing statements for which
we are not computing value numbers (e.g., non-assignments, or we are not computing value numbers (e.g., non-assignments, or
statements that make aliased stores). In those cases, we are statements that make aliased stores). In those cases, we are
only interested in making VAR available as its own value. */ only interested in making VAR available as its own value. */
if (var != expr) if (var != expr)
vn_add (var, val, NULL); vn_add (var, val, NULL_TREE);
if (s1) if (s1)
bitmap_insert_into_set (s1, var); bitmap_insert_into_set (s1, var);
...@@ -1785,9 +1785,7 @@ add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1, ...@@ -1785,9 +1785,7 @@ add_to_sets (tree var, tree expr, vuse_optype vuses, bitmap_set_t s1,
Insert EXPR's operands into the EXP_GEN set for BLOCK. */ Insert EXPR's operands into the EXP_GEN set for BLOCK. */
static inline tree static inline tree
create_value_expr_from (tree expr, basic_block block, create_value_expr_from (tree expr, basic_block block, tree stmt)
vuse_optype vuses)
{ {
int i; int i;
enum tree_code code = TREE_CODE (expr); enum tree_code code = TREE_CODE (expr);
...@@ -1829,9 +1827,9 @@ create_value_expr_from (tree expr, basic_block block, ...@@ -1829,9 +1827,9 @@ create_value_expr_from (tree expr, basic_block block,
/* Recursively value-numberize reference ops */ /* Recursively value-numberize reference ops */
if (REFERENCE_CLASS_P (op)) if (REFERENCE_CLASS_P (op))
{ {
tree tempop = create_value_expr_from (op, block, vuses); tree tempop = create_value_expr_from (op, block, stmt);
op = tempop ? tempop : op; op = tempop ? tempop : op;
val = vn_lookup_or_add (op, vuses); val = vn_lookup_or_add (op, stmt);
} }
else else
/* Create a value handle for OP and add it to VEXPR. */ /* Create a value handle for OP and add it to VEXPR. */
...@@ -1922,7 +1920,8 @@ compute_avail (void) ...@@ -1922,7 +1920,8 @@ compute_avail (void)
for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (block); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
stmt_ann_t ann; stmt_ann_t ann;
size_t j; ssa_op_iter iter;
tree op;
stmt = bsi_stmt (bsi); stmt = bsi_stmt (bsi);
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
...@@ -1938,7 +1937,6 @@ compute_avail (void) ...@@ -1938,7 +1937,6 @@ compute_avail (void)
{ {
tree lhs = TREE_OPERAND (stmt, 0); tree lhs = TREE_OPERAND (stmt, 0);
tree rhs = TREE_OPERAND (stmt, 1); tree rhs = TREE_OPERAND (stmt, 1);
vuse_optype vuses = STMT_VUSE_OPS (stmt);
STRIP_USELESS_TYPE_CONVERSION (rhs); STRIP_USELESS_TYPE_CONVERSION (rhs);
if (UNARY_CLASS_P (rhs) if (UNARY_CLASS_P (rhs)
...@@ -1950,10 +1948,10 @@ compute_avail (void) ...@@ -1950,10 +1948,10 @@ compute_avail (void)
create a duplicate expression with the operands create a duplicate expression with the operands
replaced with the value handles of the original replaced with the value handles of the original
RHS. */ RHS. */
tree newt = create_value_expr_from (rhs, block, vuses); tree newt = create_value_expr_from (rhs, block, stmt);
if (newt) if (newt)
{ {
add_to_sets (lhs, newt, vuses, TMP_GEN (block), add_to_sets (lhs, newt, stmt, TMP_GEN (block),
AVAIL_OUT (block)); AVAIL_OUT (block));
value_insert_into_set (EXP_GEN (block), newt); value_insert_into_set (EXP_GEN (block), newt);
continue; continue;
...@@ -1968,7 +1966,7 @@ compute_avail (void) ...@@ -1968,7 +1966,7 @@ compute_avail (void)
/* Compute a value number for the RHS of the statement /* Compute a value number for the RHS of the statement
and add its value to the AVAIL_OUT set for the block. and add its value to the AVAIL_OUT set for the block.
Add the LHS to TMP_GEN. */ Add the LHS to TMP_GEN. */
add_to_sets (lhs, rhs, vuses, TMP_GEN (block), add_to_sets (lhs, rhs, stmt, TMP_GEN (block),
AVAIL_OUT (block)); AVAIL_OUT (block));
if (TREE_CODE (rhs) == SSA_NAME if (TREE_CODE (rhs) == SSA_NAME
...@@ -1981,18 +1979,11 @@ compute_avail (void) ...@@ -1981,18 +1979,11 @@ compute_avail (void)
/* For any other statement that we don't recognize, simply /* For any other statement that we don't recognize, simply
make the names generated by the statement available in make the names generated by the statement available in
AVAIL_OUT and TMP_GEN. */ AVAIL_OUT and TMP_GEN. */
for (j = 0; j < NUM_DEFS (STMT_DEF_OPS (stmt)); j++) FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
{ add_to_sets (op, op, NULL, TMP_GEN (block), AVAIL_OUT (block));
tree def = DEF_OP (STMT_DEF_OPS (stmt), j);
add_to_sets (def, def, NULL, TMP_GEN (block),
AVAIL_OUT (block));
}
for (j = 0; j < NUM_USES (STMT_USE_OPS (stmt)); j++) FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
{ add_to_sets (op, op, NULL, NULL , AVAIL_OUT (block));
tree use = USE_OP (STMT_USE_OPS (stmt), j);
add_to_sets (use, use, NULL, NULL, AVAIL_OUT (block));
}
} }
/* Put the dominator children of BLOCK on the worklist of blocks /* Put the dominator children of BLOCK on the worklist of blocks
......
...@@ -678,12 +678,14 @@ ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt, ...@@ -678,12 +678,14 @@ ssa_propagate (ssa_prop_visit_stmt_fn visit_stmt,
tree tree
first_vdef (tree stmt) first_vdef (tree stmt)
{ {
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) > 0) ssa_op_iter iter;
return V_MAY_DEF_RESULT (STMT_V_MAY_DEF_OPS (stmt), 0); tree op;
else if (NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) > 0)
return V_MUST_DEF_RESULT (STMT_V_MUST_DEF_OPS (stmt), 0); /* Simply return the first operand we arrive at. */
else FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_DEFS)
gcc_unreachable (); return (op);
gcc_unreachable ();
} }
...@@ -700,8 +702,7 @@ stmt_makes_single_load (tree stmt) ...@@ -700,8 +702,7 @@ stmt_makes_single_load (tree stmt)
if (TREE_CODE (stmt) != MODIFY_EXPR) if (TREE_CODE (stmt) != MODIFY_EXPR)
return false; return false;
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0 if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VUSE))
&& NUM_VUSES (STMT_VUSE_OPS (stmt)) == 0)
return false; return false;
rhs = TREE_OPERAND (stmt, 1); rhs = TREE_OPERAND (stmt, 1);
...@@ -726,8 +727,7 @@ stmt_makes_single_store (tree stmt) ...@@ -726,8 +727,7 @@ stmt_makes_single_store (tree stmt)
if (TREE_CODE (stmt) != MODIFY_EXPR) if (TREE_CODE (stmt) != MODIFY_EXPR)
return false; return false;
if (NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0 if (ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
&& NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) == 0)
return false; return false;
lhs = TREE_OPERAND (stmt, 0); lhs = TREE_OPERAND (stmt, 0);
......
...@@ -138,16 +138,10 @@ all_immediate_uses_same_place (tree stmt) ...@@ -138,16 +138,10 @@ all_immediate_uses_same_place (tree stmt)
bool bool
is_hidden_global_store (tree stmt) is_hidden_global_store (tree stmt)
{ {
stmt_ann_t ann = stmt_ann (stmt);
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
/* Check virtual definitions. If we get here, the only virtual /* Check virtual definitions. If we get here, the only virtual
definitions we should see are those generated by assignment definitions we should see are those generated by assignment
statements. */ statements. */
v_may_defs = V_MAY_DEF_OPS (ann); if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
v_must_defs = V_MUST_DEF_OPS (ann);
if (NUM_V_MAY_DEFS (v_may_defs) > 0 || NUM_V_MUST_DEFS (v_must_defs) > 0)
{ {
tree lhs; tree lhs;
...@@ -324,13 +318,13 @@ statement_sink_location (tree stmt, basic_block frombb) ...@@ -324,13 +318,13 @@ statement_sink_location (tree stmt, basic_block frombb)
*/ */
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
if (NUM_VUSES (STMT_VUSE_OPS (stmt)) != 0 if (stmt_ends_bb_p (stmt)
|| stmt_ends_bb_p (stmt)
|| TREE_SIDE_EFFECTS (rhs) || TREE_SIDE_EFFECTS (rhs)
|| TREE_CODE (rhs) == EXC_PTR_EXPR || TREE_CODE (rhs) == EXC_PTR_EXPR
|| TREE_CODE (rhs) == FILTER_EXPR || TREE_CODE (rhs) == FILTER_EXPR
|| is_hidden_global_store (stmt) || is_hidden_global_store (stmt)
|| ann->has_volatile_ops) || ann->has_volatile_ops
|| !ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE))
return NULL; return NULL;
FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS) FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_ALL_DEFS)
...@@ -397,18 +391,10 @@ statement_sink_location (tree stmt, basic_block frombb) ...@@ -397,18 +391,10 @@ statement_sink_location (tree stmt, basic_block frombb)
} }
/* Note that at this point, all uses must be in the same statement, so it /* Note that at this point, all uses must be in the same statement, so it
doesn't matter which def op we choose. */ doesn't matter which def op we choose, pick the first one. */
if (STMT_DEF_OPS (stmt) == NULL) FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
{ break;
if (STMT_V_MAY_DEF_OPS (stmt) != NULL)
def = V_MAY_DEF_RESULT (STMT_V_MAY_DEF_OPS (stmt), 0);
else if (STMT_V_MUST_DEF_OPS (stmt) != NULL)
def = V_MUST_DEF_RESULT (STMT_V_MUST_DEF_OPS (stmt), 0);
else
gcc_unreachable ();
}
else
def = DEF_OP (STMT_DEF_OPS (stmt), 0);
sinkbb = find_bb_for_arg (use, def); sinkbb = find_bb_for_arg (use, def);
if (!sinkbb) if (!sinkbb)
......
...@@ -709,8 +709,8 @@ verify_ssa (bool check_modified_stmt) ...@@ -709,8 +709,8 @@ verify_ssa (bool check_modified_stmt)
if (check_modified_stmt && stmt_modified_p (stmt)) if (check_modified_stmt && stmt_modified_p (stmt))
{ {
error ("Stmt (0x%x) marked modified after optimization pass : ", error ("Stmt (%p) marked modified after optimization pass : ",
(unsigned long)stmt); (void *)stmt);
print_generic_stmt (stderr, stmt, TDF_VOPS); print_generic_stmt (stderr, stmt, TDF_VOPS);
goto err; goto err;
} }
...@@ -725,8 +725,7 @@ verify_ssa (bool check_modified_stmt) ...@@ -725,8 +725,7 @@ verify_ssa (bool check_modified_stmt)
if (base_address if (base_address
&& SSA_VAR_P (base_address) && SSA_VAR_P (base_address)
&& NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0 && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF|SSA_OP_VMUSTDEF))
&& NUM_V_MUST_DEFS (STMT_V_MUST_DEF_OPS (stmt)) == 0)
{ {
error ("Statement makes a memory store, but has no " error ("Statement makes a memory store, but has no "
"V_MAY_DEFS nor V_MUST_DEFS"); "V_MAY_DEFS nor V_MUST_DEFS");
...@@ -737,7 +736,7 @@ verify_ssa (bool check_modified_stmt) ...@@ -737,7 +736,7 @@ verify_ssa (bool check_modified_stmt)
if (stmt_ann (stmt)->makes_aliased_stores if (stmt_ann (stmt)->makes_aliased_stores
&& NUM_V_MAY_DEFS (STMT_V_MAY_DEF_OPS (stmt)) == 0) && ZERO_SSA_OPERANDS (stmt, SSA_OP_VMAYDEF))
{ {
error ("Statement makes aliased stores, but has no V_MAY_DEFS"); error ("Statement makes aliased stores, but has no V_MAY_DEFS");
print_generic_stmt (stderr, stmt, TDF_VOPS); print_generic_stmt (stderr, stmt, TDF_VOPS);
...@@ -806,12 +805,23 @@ delete_tree_ssa (void) ...@@ -806,12 +805,23 @@ delete_tree_ssa (void)
basic_block bb; basic_block bb;
block_stmt_iterator bsi; block_stmt_iterator bsi;
/* Release any ssa_names still in use. */
for (i = 0; i < num_ssa_names; i++)
{
tree var = ssa_name (i);
if (var && TREE_CODE (var) == SSA_NAME)
{
SSA_NAME_IMM_USE_NODE (var).prev = &(SSA_NAME_IMM_USE_NODE (var));
SSA_NAME_IMM_USE_NODE (var).next = &(SSA_NAME_IMM_USE_NODE (var));
}
release_ssa_name (var);
}
/* Remove annotations from every tree in the function. */ /* Remove annotations from every tree in the function. */
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
tree stmt = bsi_stmt (bsi); tree stmt = bsi_stmt (bsi);
release_defs (stmt);
ggc_free (stmt->common.ann); ggc_free (stmt->common.ann);
stmt->common.ann = NULL; stmt->common.ann = NULL;
} }
...@@ -943,9 +953,7 @@ stmt_references_memory_p (tree stmt) ...@@ -943,9 +953,7 @@ stmt_references_memory_p (tree stmt)
if (ann->has_volatile_ops) if (ann->has_volatile_ops)
return true; return true;
return (NUM_VUSES (VUSE_OPS (ann)) > 0 return (!ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS));
|| NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) > 0
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) > 0);
} }
/* Internal helper for walk_use_def_chains. VAR, FN and DATA are as /* Internal helper for walk_use_def_chains. VAR, FN and DATA are as
......
...@@ -121,7 +121,7 @@ tree ...@@ -121,7 +121,7 @@ tree
make_ssa_name (tree var, tree stmt) make_ssa_name (tree var, tree stmt)
{ {
tree t; tree t;
ssa_imm_use_t *imm; use_operand_p imm;
gcc_assert (DECL_P (var) gcc_assert (DECL_P (var)
|| TREE_CODE (var) == INDIRECT_REF); || TREE_CODE (var) == INDIRECT_REF);
...@@ -205,7 +205,7 @@ release_ssa_name (tree var) ...@@ -205,7 +205,7 @@ release_ssa_name (tree var)
{ {
tree saved_ssa_name_var = SSA_NAME_VAR (var); tree saved_ssa_name_var = SSA_NAME_VAR (var);
int saved_ssa_name_version = SSA_NAME_VERSION (var); int saved_ssa_name_version = SSA_NAME_VERSION (var);
ssa_imm_use_t *imm = &(SSA_NAME_IMM_USE_NODE (var)); use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_imm_links (stderr, var); verify_imm_links (stderr, var);
......
...@@ -413,9 +413,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -413,9 +413,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
/* If the statement has virtual or volatile operands, fail. */ /* If the statement has virtual or volatile operands, fail. */
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
if (NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) if (!ZERO_SSA_OPERANDS (stmt, (SSA_OP_VUSE | SSA_OP_VIRTUAL_DEFS))
|| NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann))
|| NUM_VUSES (VUSE_OPS (ann))
|| ann->has_volatile_ops) || ann->has_volatile_ops)
return; return;
} }
...@@ -679,13 +677,13 @@ eliminate_tail_call (struct tailcall *t) ...@@ -679,13 +677,13 @@ eliminate_tail_call (struct tailcall *t)
basic_block bb, first; basic_block bb, first;
edge e; edge e;
tree phi; tree phi;
stmt_ann_t ann;
v_may_def_optype v_may_defs;
unsigned i;
block_stmt_iterator bsi; block_stmt_iterator bsi;
use_operand_p mayuse;
def_operand_p maydef;
ssa_op_iter iter;
tree orig_stmt;
stmt = bsi_stmt (t->call_bsi); stmt = orig_stmt = bsi_stmt (t->call_bsi);
ann = stmt_ann (stmt);
bb = t->call_block; bb = t->call_block;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -748,10 +746,9 @@ eliminate_tail_call (struct tailcall *t) ...@@ -748,10 +746,9 @@ eliminate_tail_call (struct tailcall *t)
} }
/* Add phi nodes for the call clobbered variables. */ /* Add phi nodes for the call clobbered variables. */
v_may_defs = V_MAY_DEF_OPS (ann); FOR_EACH_SSA_MAYDEF_OPERAND (maydef, mayuse, orig_stmt, iter)
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
{ {
param = SSA_NAME_VAR (V_MAY_DEF_RESULT (v_may_defs, i)); param = SSA_NAME_VAR (DEF_FROM_PTR (maydef));
for (phi = phi_nodes (first); phi; phi = PHI_CHAIN (phi)) for (phi = phi_nodes (first); phi; phi = PHI_CHAIN (phi))
if (param == SSA_NAME_VAR (PHI_RESULT (phi))) if (param == SSA_NAME_VAR (PHI_RESULT (phi)))
break; break;
...@@ -782,7 +779,7 @@ eliminate_tail_call (struct tailcall *t) ...@@ -782,7 +779,7 @@ eliminate_tail_call (struct tailcall *t)
gcc_assert (EDGE_COUNT (first->preds) <= 2); gcc_assert (EDGE_COUNT (first->preds) <= 2);
} }
add_phi_arg (phi, V_MAY_DEF_OP (v_may_defs, i), e); add_phi_arg (phi, USE_FROM_PTR (mayuse), e);
} }
/* Update the values of accumulators. */ /* Update the values of accumulators. */
......
...@@ -1943,29 +1943,25 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) ...@@ -1943,29 +1943,25 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
bool is_read = false; bool is_read = false;
tree stmt = bsi_stmt (si); tree stmt = bsi_stmt (si);
stmt_vec_info stmt_info = vinfo_for_stmt (stmt); stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
v_may_def_optype v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
v_must_def_optype v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
vuse_optype vuses = STMT_VUSE_OPS (stmt);
varray_type *datarefs = NULL; varray_type *datarefs = NULL;
int nvuses, nv_may_defs, nv_must_defs;
tree memref = NULL; tree memref = NULL;
tree scalar_type, vectype; tree scalar_type, vectype;
tree base, offset, misalign, step, tag; tree base, offset, misalign, step, tag;
struct ptr_info_def *ptr_info; struct ptr_info_def *ptr_info;
bool base_aligned; bool base_aligned;
subvar_t subvars = NULL; subvar_t subvars = NULL;
bool no_vuse, no_vmaymust;
/* Assumption: there exists a data-ref in stmt, if and only if /* Assumption: there exists a data-ref in stmt, if and only if
it has vuses/vdefs. */ it has vuses/vdefs. */
if (!vuses && !v_may_defs && !v_must_defs) no_vuse = ZERO_SSA_OPERANDS (stmt, SSA_OP_VUSE);
no_vmaymust = ZERO_SSA_OPERANDS (stmt,
SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF);
if (no_vuse && no_vmaymust)
continue; continue;
nvuses = NUM_VUSES (vuses); if (!no_vuse && !no_vmaymust)
nv_may_defs = NUM_V_MAY_DEFS (v_may_defs);
nv_must_defs = NUM_V_MUST_DEFS (v_must_defs);
if (nvuses && (nv_may_defs || nv_must_defs))
{ {
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC)) if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
{ {
...@@ -1985,7 +1981,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo) ...@@ -1985,7 +1981,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo)
return false; return false;
} }
if (vuses) if (!no_vuse)
{ {
memref = TREE_OPERAND (stmt, 1); memref = TREE_OPERAND (stmt, 1);
datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo)); datarefs = &(LOOP_VINFO_DATAREF_READS (loop_vinfo));
...@@ -2106,49 +2102,29 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt) ...@@ -2106,49 +2102,29 @@ vect_mark_relevant (VEC(tree,heap) **worklist, tree stmt)
static bool static bool
vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo) vect_stmt_relevant_p (tree stmt, loop_vec_info loop_vinfo)
{ {
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo); struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
ssa_op_iter op_iter; ssa_op_iter op_iter;
imm_use_iterator imm_iter; imm_use_iterator imm_iter;
use_operand_p use_p; use_operand_p use_p;
tree var; def_operand_p def_p;
/* cond stmt other than loop exit cond. */ /* cond stmt other than loop exit cond. */
if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo))) if (is_ctrl_stmt (stmt) && (stmt != LOOP_VINFO_EXIT_COND (loop_vinfo)))
return true; return true;
/* changing memory. */ /* changing memory. */
if (TREE_CODE (stmt) == PHI_NODE) if (TREE_CODE (stmt) != PHI_NODE)
{ if (!ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
if (!is_gimple_reg (PHI_RESULT (stmt))) {
return false; if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, PHI_RESULT (stmt)) fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
{ return true;
basic_block bb = bb_for_stmt (USE_STMT (use_p)); }
if (!flow_bb_inside_loop_p (loop, bb))
{
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
return true;
}
}
return false;
}
v_may_defs = STMT_V_MAY_DEF_OPS (stmt);
v_must_defs = STMT_V_MUST_DEF_OPS (stmt);
if (v_may_defs || v_must_defs)
{
if (vect_print_dump_info (REPORT_DETAILS, UNKNOWN_LOC))
fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
return true;
}
/* uses outside the loop. */ /* uses outside the loop. */
FOR_EACH_SSA_TREE_OPERAND (var, stmt, op_iter, SSA_OP_DEF) FOR_EACH_PHI_OR_STMT_DEF (def_p, stmt, op_iter, SSA_OP_DEF)
{ {
FOR_EACH_IMM_USE_FAST (use_p, imm_iter, var) FOR_EACH_IMM_USE_FAST (use_p, imm_iter, DEF_FROM_PTR (def_p))
{ {
basic_block bb = bb_for_stmt (USE_STMT (use_p)); basic_block bb = bb_for_stmt (USE_STMT (use_p));
if (!flow_bb_inside_loop_p (loop, bb)) if (!flow_bb_inside_loop_p (loop, bb))
...@@ -2188,11 +2164,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) ...@@ -2188,11 +2164,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo); basic_block *bbs = LOOP_VINFO_BBS (loop_vinfo);
unsigned int nbbs = loop->num_nodes; unsigned int nbbs = loop->num_nodes;
block_stmt_iterator si; block_stmt_iterator si;
tree stmt; tree stmt, use;
stmt_ann_t ann; ssa_op_iter iter;
unsigned int i; unsigned int i;
int j; int j;
use_optype use_ops;
stmt_vec_info stmt_info; stmt_vec_info stmt_info;
basic_block bb; basic_block bb;
tree phi; tree phi;
...@@ -2291,12 +2266,8 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo) ...@@ -2291,12 +2266,8 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
} }
} }
ann = stmt_ann (stmt); FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
use_ops = USE_OPS (ann);
for (i = 0; i < NUM_USES (use_ops); i++)
{ {
tree use = USE_OP (use_ops, i);
/* We are only interested in uses that need to be vectorized. Uses /* We are only interested in uses that need to be vectorized. Uses
that are used for address computation are not considered relevant. that are used for address computation are not considered relevant.
......
...@@ -1499,13 +1499,12 @@ update_vuses_to_preheader (tree stmt, struct loop *loop) ...@@ -1499,13 +1499,12 @@ update_vuses_to_preheader (tree stmt, struct loop *loop)
{ {
basic_block header_bb = loop->header; basic_block header_bb = loop->header;
edge preheader_e = loop_preheader_edge (loop); edge preheader_e = loop_preheader_edge (loop);
vuse_optype vuses = STMT_VUSE_OPS (stmt); ssa_op_iter iter;
int nvuses = NUM_VUSES (vuses); use_operand_p use_p;
int i;
for (i = 0; i < nvuses; i++) FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VUSE)
{ {
tree ssa_name = VUSE_OP (vuses, i); tree ssa_name = USE_FROM_PTR (use_p);
tree def_stmt = SSA_NAME_DEF_STMT (ssa_name); tree def_stmt = SSA_NAME_DEF_STMT (ssa_name);
tree name_var = SSA_NAME_VAR (ssa_name); tree name_var = SSA_NAME_VAR (ssa_name);
basic_block bb = bb_for_stmt (def_stmt); basic_block bb = bb_for_stmt (def_stmt);
...@@ -1524,8 +1523,7 @@ update_vuses_to_preheader (tree stmt, struct loop *loop) ...@@ -1524,8 +1523,7 @@ update_vuses_to_preheader (tree stmt, struct loop *loop)
{ {
if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var) if (SSA_NAME_VAR (PHI_RESULT (phi)) == name_var)
{ {
SET_VUSE_OP (vuses, i, SET_USE (use_p, PHI_ARG_DEF (phi, preheader_e->dest_idx));
PHI_ARG_DEF (phi, preheader_e->dest_idx));
updated = true; updated = true;
break; break;
} }
......
...@@ -215,12 +215,8 @@ rename_variables_in_bb (basic_block bb) ...@@ -215,12 +215,8 @@ rename_variables_in_bb (basic_block bb)
tree phi; tree phi;
block_stmt_iterator bsi; block_stmt_iterator bsi;
tree stmt; tree stmt;
stmt_ann_t ann; use_operand_p use_p;
use_optype uses; ssa_op_iter iter;
vuse_optype vuses;
v_may_def_optype v_may_defs;
v_must_def_optype v_must_defs;
unsigned i;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
struct loop *loop = bb->loop_father; struct loop *loop = bb->loop_father;
...@@ -228,23 +224,9 @@ rename_variables_in_bb (basic_block bb) ...@@ -228,23 +224,9 @@ rename_variables_in_bb (basic_block bb)
for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
{ {
stmt = bsi_stmt (bsi); stmt = bsi_stmt (bsi);
ann = stmt_ann (stmt); FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
(SSA_OP_ALL_USES | SSA_OP_ALL_KILLS))
uses = USE_OPS (ann); rename_use_op (use_p);
for (i = 0; i < NUM_USES (uses); i++)
rename_use_op (USE_OP_PTR (uses, i));
vuses = VUSE_OPS (ann);
for (i = 0; i < NUM_VUSES (vuses); i++)
rename_use_op (VUSE_OP_PTR (vuses, i));
v_may_defs = V_MAY_DEF_OPS (ann);
for (i = 0; i < NUM_V_MAY_DEFS (v_may_defs); i++)
rename_use_op (V_MAY_DEF_OP_PTR (v_may_defs, i));
v_must_defs = V_MUST_DEF_OPS (ann);
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
} }
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
......
...@@ -48,8 +48,8 @@ typedef struct val_expr_pair_d ...@@ -48,8 +48,8 @@ typedef struct val_expr_pair_d
/* Associated expression. */ /* Associated expression. */
tree e; tree e;
/* Virtual uses in E. */ /* for comparing Virtual uses in E. */
vuse_optype vuses; tree stmt;
/* E's hash value. */ /* E's hash value. */
hashval_t hashcode; hashval_t hashcode;
...@@ -79,13 +79,13 @@ make_value_handle (tree type) ...@@ -79,13 +79,13 @@ make_value_handle (tree type)
VAL can be used to iterate by passing previous value numbers (it is VAL can be used to iterate by passing previous value numbers (it is
used by iterative_hash_expr). used by iterative_hash_expr).
VUSES is the set of virtual use operands associated with EXPR. It STMT is the stmt associated with EXPR for comparing virtual operands. */
may be NULL if EXPR has no virtual operands. */
hashval_t hashval_t
vn_compute (tree expr, hashval_t val, vuse_optype vuses) vn_compute (tree expr, hashval_t val, tree stmt)
{ {
size_t i; ssa_op_iter iter;
tree vuse;
/* EXPR must not be a statement. We are only interested in value /* EXPR must not be a statement. We are only interested in value
numbering expressions on the RHS of assignments. */ numbering expressions on the RHS of assignments. */
...@@ -97,8 +97,9 @@ vn_compute (tree expr, hashval_t val, vuse_optype vuses) ...@@ -97,8 +97,9 @@ vn_compute (tree expr, hashval_t val, vuse_optype vuses)
/* If the expression has virtual uses, incorporate them into the /* If the expression has virtual uses, incorporate them into the
hash value computed for EXPR. */ hash value computed for EXPR. */
for (i = 0; i < NUM_VUSES (vuses); i++) if (stmt)
val = iterative_hash_expr (VUSE_OP (vuses, i), val); FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
val = iterative_hash_expr (vuse, val);
return val; return val;
} }
...@@ -146,22 +147,15 @@ val_expr_pair_hash (const void *p) ...@@ -146,22 +147,15 @@ val_expr_pair_hash (const void *p)
static int static int
val_expr_pair_expr_eq (const void *p1, const void *p2) val_expr_pair_expr_eq (const void *p1, const void *p2)
{ {
bool ret;
const val_expr_pair_t ve1 = (val_expr_pair_t) p1; const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
const val_expr_pair_t ve2 = (val_expr_pair_t) p2; const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
size_t i;
if (! expressions_equal_p (ve1->e, ve2->e)) if (! expressions_equal_p (ve1->e, ve2->e))
return false; return false;
if (NUM_VUSES (ve1->vuses) != NUM_VUSES (ve2->vuses)) ret = compare_ssa_operands_equal (ve1->stmt, ve2->stmt, SSA_OP_VUSE);
return false; return ret;
for (i = 0; i < NUM_VUSES (ve1->vuses); i++)
if (! expressions_equal_p (VUSE_OP (ve1->vuses, i),
VUSE_OP (ve2->vuses, i)))
return false;
return true;
} }
...@@ -181,12 +175,11 @@ set_value_handle (tree e, tree v) ...@@ -181,12 +175,11 @@ set_value_handle (tree e, tree v)
/* Insert EXPR into VALUE_TABLE with value VAL, and add expression /* Insert EXPR into VALUE_TABLE with value VAL, and add expression
EXPR to the value set for value VAL. VUSES represent the virtual EXPR to the value set for value VAL. STMT represent the stmt
use operands associated with EXPR (if any). They are used when associated with EXPR. It is used when computing a hash value for EXPR. */
computing the hash value for EXPR. */
void void
vn_add (tree expr, tree val, vuse_optype vuses) vn_add (tree expr, tree val, tree stmt)
{ {
void **slot; void **slot;
val_expr_pair_t new_pair; val_expr_pair_t new_pair;
...@@ -194,8 +187,8 @@ vn_add (tree expr, tree val, vuse_optype vuses) ...@@ -194,8 +187,8 @@ vn_add (tree expr, tree val, vuse_optype vuses)
new_pair = xmalloc (sizeof (struct val_expr_pair_d)); new_pair = xmalloc (sizeof (struct val_expr_pair_d));
new_pair->e = expr; new_pair->e = expr;
new_pair->v = val; new_pair->v = val;
new_pair->vuses = vuses; new_pair->stmt = stmt;
new_pair->hashcode = vn_compute (expr, 0, vuses); new_pair->hashcode = vn_compute (expr, 0, stmt);
slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode, slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
INSERT); INSERT);
if (*slot) if (*slot)
...@@ -208,12 +201,12 @@ vn_add (tree expr, tree val, vuse_optype vuses) ...@@ -208,12 +201,12 @@ vn_add (tree expr, tree val, vuse_optype vuses)
/* Search in VALUE_TABLE for an existing instance of expression EXPR, /* Search in VALUE_TABLE for an existing instance of expression EXPR,
and return its value, or NULL if none has been set. VUSES and return its value, or NULL if none has been set. STMT
represent the virtual use operands associated with EXPR (if any). represent the stmt associated with EXPR. It is arused when computing the
They are used when computing the hash value for EXPR. */ hash value for EXPR. */
tree tree
vn_lookup (tree expr, vuse_optype vuses) vn_lookup (tree expr, tree stmt)
{ {
void **slot; void **slot;
struct val_expr_pair_d vep = {NULL, NULL, NULL, 0}; struct val_expr_pair_d vep = {NULL, NULL, NULL, 0};
...@@ -223,8 +216,8 @@ vn_lookup (tree expr, vuse_optype vuses) ...@@ -223,8 +216,8 @@ vn_lookup (tree expr, vuse_optype vuses)
return expr; return expr;
vep.e = expr; vep.e = expr;
vep.vuses = vuses; vep.stmt = stmt;
vep.hashcode = vn_compute (expr, 0, vuses); vep.hashcode = vn_compute (expr, 0, stmt);
slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT); slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
if (!slot) if (!slot)
return NULL_TREE; return NULL_TREE;
...@@ -235,14 +228,13 @@ vn_lookup (tree expr, vuse_optype vuses) ...@@ -235,14 +228,13 @@ vn_lookup (tree expr, vuse_optype vuses)
/* Like vn_lookup, but creates a new value for expression EXPR, if /* Like vn_lookup, but creates a new value for expression EXPR, if
EXPR doesn't already have a value. Return the existing/created EXPR doesn't already have a value. Return the existing/created
value for EXPR. VUSES represent the virtual use operands value for EXPR. STMT represent the stmt associated with EXPR. It is used
associated with EXPR (if any). They are used when computing the when computing the hash value for EXPR. */
hash value for EXPR. */
tree tree
vn_lookup_or_add (tree expr, vuse_optype vuses) vn_lookup_or_add (tree expr, tree stmt)
{ {
tree v = vn_lookup (expr, vuses); tree v = vn_lookup (expr, stmt);
if (v == NULL_TREE) if (v == NULL_TREE)
{ {
v = make_value_handle (TREE_TYPE (expr)); v = make_value_handle (TREE_TYPE (expr));
...@@ -256,7 +248,7 @@ vn_lookup_or_add (tree expr, vuse_optype vuses) ...@@ -256,7 +248,7 @@ vn_lookup_or_add (tree expr, vuse_optype vuses)
fprintf (dump_file, "\n"); fprintf (dump_file, "\n");
} }
vn_add (expr, v, vuses); vn_add (expr, v, stmt);
} }
set_value_handle (expr, v); set_value_handle (expr, v);
......
...@@ -1544,7 +1544,6 @@ maybe_add_assert_expr (basic_block bb) ...@@ -1544,7 +1544,6 @@ maybe_add_assert_expr (basic_block bb)
block_stmt_iterator si; block_stmt_iterator si;
tree last; tree last;
bool added; bool added;
use_optype uses;
/* Step 1. Mark all the SSA names used in BB in bitmap FOUND. */ /* Step 1. Mark all the SSA names used in BB in bitmap FOUND. */
added = false; added = false;
...@@ -1628,16 +1627,20 @@ maybe_add_assert_expr (basic_block bb) ...@@ -1628,16 +1627,20 @@ maybe_add_assert_expr (basic_block bb)
if (last if (last
&& TREE_CODE (last) == COND_EXPR && TREE_CODE (last) == COND_EXPR
&& !fp_predicate (COND_EXPR_COND (last)) && !fp_predicate (COND_EXPR_COND (last))
&& NUM_USES (uses = STMT_USE_OPS (last)) > 0) && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
{ {
edge e; edge e;
edge_iterator ei; edge_iterator ei;
tree op, cond; tree op, cond;
basic_block son; basic_block son;
ssa_op_iter iter;
cond = COND_EXPR_COND (last); cond = COND_EXPR_COND (last);
op = USE_OP (uses, 0); /* Get just the first use operand. */
FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
break;
gcc_assert (op != NULL);
/* Do not attempt to infer anything in names that flow through /* Do not attempt to infer anything in names that flow through
abnormal edges. */ abnormal edges. */
...@@ -1819,14 +1822,11 @@ stmt_interesting_for_vrp (tree stmt) ...@@ -1819,14 +1822,11 @@ stmt_interesting_for_vrp (tree stmt)
else if (TREE_CODE (stmt) == MODIFY_EXPR) else if (TREE_CODE (stmt) == MODIFY_EXPR)
{ {
tree lhs = TREE_OPERAND (stmt, 0); tree lhs = TREE_OPERAND (stmt, 0);
stmt_ann_t ann = stmt_ann (stmt);
if (TREE_CODE (lhs) == SSA_NAME if (TREE_CODE (lhs) == SSA_NAME
&& (INTEGRAL_TYPE_P (TREE_TYPE (lhs)) && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
|| POINTER_TYPE_P (TREE_TYPE (lhs))) || POINTER_TYPE_P (TREE_TYPE (lhs)))
&& NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0 && ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
&& NUM_VUSES (VUSE_OPS (ann)) == 0
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
return true; return true;
} }
else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR) else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
...@@ -2080,9 +2080,7 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p) ...@@ -2080,9 +2080,7 @@ vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
ann = stmt_ann (stmt); ann = stmt_ann (stmt);
if (TREE_CODE (stmt) == MODIFY_EXPR if (TREE_CODE (stmt) == MODIFY_EXPR
&& NUM_V_MAY_DEFS (V_MAY_DEF_OPS (ann)) == 0 && ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
&& NUM_VUSES (VUSE_OPS (ann)) == 0
&& NUM_V_MUST_DEFS (V_MUST_DEF_OPS (ann)) == 0)
return vrp_visit_assignment (stmt, output_p); return vrp_visit_assignment (stmt, output_p);
else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR) else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
return vrp_visit_cond_stmt (stmt, taken_edge_p); return vrp_visit_cond_stmt (stmt, taken_edge_p);
......
...@@ -1355,13 +1355,13 @@ struct value_range_def; ...@@ -1355,13 +1355,13 @@ struct value_range_def;
/* Immediate use linking structure. This structure is used for maintaining /* Immediate use linking structure. This structure is used for maintaining
a doubly linked list of uses of an SSA_NAME. */ a doubly linked list of uses of an SSA_NAME. */
typedef struct ssa_imm_use_d GTY(()) typedef struct ssa_use_operand_d GTY(())
{ {
struct ssa_imm_use_d* GTY((skip(""))) prev; struct ssa_use_operand_d* GTY((skip(""))) prev;
struct ssa_imm_use_d* GTY((skip(""))) next; struct ssa_use_operand_d* GTY((skip(""))) next;
tree GTY((skip(""))) stmt; tree GTY((skip(""))) stmt;
tree *GTY((skip(""))) use; tree *GTY((skip(""))) use;
} ssa_imm_use_t; } ssa_use_operand_t;
/* Return the immediate_use information for an SSA_NAME. */ /* Return the immediate_use information for an SSA_NAME. */
#define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses #define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
...@@ -1393,7 +1393,7 @@ struct tree_ssa_name GTY(()) ...@@ -1393,7 +1393,7 @@ struct tree_ssa_name GTY(())
PTR GTY((skip)) aux; PTR GTY((skip)) aux;
/* Immediate uses list for this SSA_NAME. */ /* Immediate uses list for this SSA_NAME. */
struct ssa_imm_use_d imm_uses; struct ssa_use_operand_d imm_uses;
}; };
/* In a PHI_NODE node. */ /* In a PHI_NODE node. */
...@@ -1424,7 +1424,7 @@ struct phi_arg_d GTY(()) ...@@ -1424,7 +1424,7 @@ struct phi_arg_d GTY(())
{ {
/* imm_use MUST be the first element in struct because we do some /* imm_use MUST be the first element in struct because we do some
pointer arithmetic with it. See phi_arg_index_from_use. */ pointer arithmetic with it. See phi_arg_index_from_use. */
struct ssa_imm_use_d imm_use; struct ssa_use_operand_d imm_use;
tree def; tree def;
bool nonzero; bool nonzero;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment