Commit 52328bf6 by Daniel Berlin Committed by Daniel Berlin

re PR tree-optimization/17133 (wrong code with -ftree-lim)

2004-10-27  Daniel Berlin <dberlin@dberlin.org>

	Fix PR tree-optimization/17133

	* tree-cfg.c (rewrite_to_new_ssa_names_bb): Also rewrite must
	def kill operand.

	* tree-flow-inline.h: V_MUST_DEF_OP became V_MUST_DEF_RESULT.
	(get_v_must_def_result_ptr): Modify for new structure of
	v_must_defs array.
	(get_v_must_def_kill_ptr): New.
	(op_iter_next_use): Add support for the kill that occurs in V_MUST_DEFs.
	(op_iter_next_tree): Ditto. Also V_MAY_DEF_OP became V_MAY_DEF_RESULT.
	(op_iter_next_def): V_MAY_DEF_OP became V_MAY_DEF_RESULT.
	(op_iter_init): Initialize new mustu members.
	(op_iter_next_mustdef): New function.
	(op_iter_init_mustdef): Ditto.

	* tree-flow.h (rewrite_def_def_chains): New function.

	* tree-into-ssa.c (mark_def_sites): Handle mustdefkill operands.
	(ssa_mark_def_sites): Ditto.
	(rewrite_stmt): Ditto.
	(ssa_rewrite_stmt): Ditto.
	(rewrite_blocks): Factor out from rewrite_into_ssa.
	(mark_def_block_sites): Ditto.
	(rewrite_def_def_chains): New function, just rewrites def-def
	chains without phi node insertion.

	* tree-pass.h (TODO_fix_def_def_chains): New todo flag.

	* tree-optimize.c (execute_todo): Handle TODO_fix_def_def_chains.

	* tree-pretty-print.c (dump_vops): Print out MUST_DEF's so that
	they include the rhs now.

	* tree-ssa-ccp.c (visit_assignment): V_MUST_DEF_OP became
	V_MUST_DEF_RESULT.

	* tree-ssa-dce.c (mark_operand_necessary): Add phionly argument.
	Update callers.
	(mark_really_necessary_kill_operand_phis): New function.
	(perform_tree_ssa_dce): Call it.
	(pass_dce): Add TODO_fix_def_def_chains.
	(pass_cd_dce): Ditto.

	* tree-ssa-loop-im.c (determine_max_movement): Look at kills as
	well.
	(rewrite_mem_refs): Ditto.

	* tree-ssa-loop-manip.c (find_uses_to_rename_stmt): Look at kills
	as well.

	* tree-ssa-operands.c (allocate_v_may_def_optype):
	v_may_def_operand_type_t became v_def_use_operand_type_t.
	(allocate_v_must_def_optype) Ditto.
	(finalize_ssa_v_must_defs): Update for new operand type, as well
	as setting the use portion as well.
	(copy_virtual_operands): Copy the kill operand as well.
	(create_ssa_artficial_load_stmt): V_MUST_DEF_OP became
	V_MUST_DEF_RESULT.

	* tree-ssa-operands.h (v_may_def_operand_type): Renamed to
	v_def_use_operand_type.
	(v_must_def_optype_d): Use v_def_use_operand_type.
	(V_MUST_DEF_OP_*): Renamed to V_MUST_DEF_RESULT_*
	(V_MUST_DEF_KILL_*): New macros.
	(struct ssa_operand_iterator_d): Add num_v_mustu and v_mustu_i
	members.
	Rename existing must_i and num_v_must members to mustd_i and
	num_v_mustd.
	(SSA_OP_VMUSTDEFKILL): New flag.
	(SSA_OP_VIRTUAL_KILLS): New flag.
	(SSA_OP_ALL_OPERANDS): Add in SSA_OP_ALL_KILLS.
	(SSA_OP_ALL_KILLS): New flag.
	(FOR_EACH_SSA_MUSTDEF_OPERAND): New macro.

	* tree-ssa.c (verify_ssa): Verify virtual kills as well.

	* tree-vectorizer.c (vect_create_data_ref_ptr): V_MUST_DEF_OP
	became V_MUST_DEF_RESULT.
	(rename_variables_in_bb): Rename kill pointer as well.

	* tree-dfa.c (compute_immediate_uses_for_stmt): Add kills into the
	immediate uses.

From-SVN: r89695
parent 47a3c2dc
2004-10-27 Daniel Berlin <dberlin@dberlin.org>
Fix PR tree-optimization/17133
* tree-cfg.c (rewrite_to_new_ssa_names_bb): Also rewrite must
def kill operand.
* tree-flow-inline.h: V_MUST_DEF_OP became V_MUST_DEF_RESULT.
(get_v_must_def_result_ptr): Modify for new structure of
v_must_defs array.
(get_v_must_def_kill_ptr): New.
(op_iter_next_use): Add support for the kill that occurs in V_MUST_DEFs.
(op_iter_next_tree): Ditto. Also V_MAY_DEF_OP became V_MAY_DEF_RESULT.
(op_iter_next_def): V_MAY_DEF_OP became V_MAY_DEF_RESULT.
(op_iter_init): Initialize new mustu members.
(op_iter_next_mustdef): New function.
(op_iter_init_mustdef): Ditto.
* tree-flow.h (rewrite_def_def_chains): New function.
* tree-into-ssa.c (mark_def_sites): Handle mustdefkill operands.
(ssa_mark_def_sites): Ditto.
(rewrite_stmt): Ditto.
(ssa_rewrite_stmt): Ditto.
(rewrite_blocks): Factor out from rewrite_into_ssa.
(mark_def_block_sites): Ditto.
(rewrite_def_def_chains): New function, just rewrites def-def
chains without phi node insertion.
* tree-pass.h (TODO_fix_def_def_chains): New todo flag.
* tree-optimize.c (execute_todo): Handle TODO_fix_def_def_chains.
* tree-pretty-print.c (dump_vops): Print out MUST_DEF's so that
they include the rhs now.
* tree-ssa-ccp.c (visit_assignment): V_MUST_DEF_OP became
V_MUST_DEF_RESULT.
* tree-ssa-dce.c (mark_operand_necessary): Add phionly argument.
Update callers.
(mark_really_necessary_kill_operand_phis): New function.
(perform_tree_ssa_dce): Call it.
(pass_dce): Add TODO_fix_def_def_chains.
(pass_cd_dce): Ditto.
* tree-ssa-loop-im.c (determine_max_movement): Look at kills as
well.
(rewrite_mem_refs): Ditto.
* tree-ssa-loop-manip.c (find_uses_to_rename_stmt): Look at kills
as well.
* tree-ssa-operands.c (allocate_v_may_def_optype):
v_may_def_operand_type_t became v_def_use_operand_type_t.
(allocate_v_must_def_optype) Ditto.
(finalize_ssa_v_must_defs): Update for new operand type, as well
as setting the use portion as well.
(copy_virtual_operands): Copy the kill operand as well.
(create_ssa_artficial_load_stmt): V_MUST_DEF_OP became
V_MUST_DEF_RESULT.
* tree-ssa-operands.h (v_may_def_operand_type): Renamed to
v_def_use_operand_type.
(v_must_def_optype_d): Use v_def_use_operand_type.
(V_MUST_DEF_OP_*): Renamed to V_MUST_DEF_RESULT_*
(V_MUST_DEF_KILL_*): New macros.
(struct ssa_operand_iterator_d): Add num_v_mustu and v_mustu_i
members.
Rename existing must_i and num_v_must members to mustd_i and
num_v_mustd.
(SSA_OP_VMUSTDEFKILL): New flag.
(SSA_OP_VIRTUAL_KILLS): New flag.
(SSA_OP_ALL_OPERANDS): Add in SSA_OP_ALL_KILLS.
(SSA_OP_ALL_KILLS): New flag.
(FOR_EACH_SSA_MUSTDEF_OPERAND): New macro.
* tree-ssa.c (verify_ssa): Verify virtual kills as well.
* tree-vectorizer.c (vect_create_data_ref_ptr): V_MUST_DEF_OP
became V_MUST_DEF_RESULT.
(rename_variables_in_bb): Rename kill pointer as well.
* tree-dfa.c (compute_immediate_uses_for_stmt): Add kills into the
immediate uses.
2004-10-27 Richard Sandiford <rsandifo@redhat.com> 2004-10-27 Richard Sandiford <rsandifo@redhat.com>
* dbxout.c (dbxout_source_line): Move declaration of begin_label to * dbxout.c (dbxout_source_line): Move declaration of begin_label to
......
...@@ -4542,8 +4542,12 @@ rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map) ...@@ -4542,8 +4542,12 @@ rewrite_to_new_ssa_names_bb (basic_block bb, htab_t map)
v_must_defs = V_MUST_DEF_OPS (ann); v_must_defs = V_MUST_DEF_OPS (ann);
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
rewrite_to_new_ssa_names_def {
(V_MUST_DEF_OP_PTR (v_must_defs, i), stmt, map); rewrite_to_new_ssa_names_def
(V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt, map);
rewrite_to_new_ssa_names_use
(V_MUST_DEF_KILL_PTR (v_must_defs, i), map);
}
} }
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
......
...@@ -312,7 +312,14 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree)) ...@@ -312,7 +312,14 @@ compute_immediate_uses_for_stmt (tree stmt, int flags, bool (*calc_for)(tree))
if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use))) if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
add_immediate_use (imm_rdef_stmt, stmt); add_immediate_use (imm_rdef_stmt, stmt);
} }
}
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_ALL_KILLS)
{
tree imm_rdef_stmt = SSA_NAME_DEF_STMT (use);
if (!IS_EMPTY_STMT (imm_rdef_stmt) && (!calc_for || calc_for (use)))
add_immediate_use (imm_rdef_stmt, stmt);
}
}
} }
......
...@@ -267,14 +267,25 @@ get_vuse_op_ptr(vuse_optype vuses, unsigned int index) ...@@ -267,14 +267,25 @@ get_vuse_op_ptr(vuse_optype vuses, unsigned int index)
return op; return op;
} }
/* Return a def_operand_p that is the V_MUST_DEF_OP for the /* Return a def_operand_p that is the V_MUST_DEF_RESULT for the
V_MUST_DEF at INDEX in the V_MUST_DEFS array. */ V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
static inline def_operand_p static inline def_operand_p
get_v_must_def_op_ptr (v_must_def_optype v_must_defs, unsigned int index) get_v_must_def_result_ptr (v_must_def_optype v_must_defs, unsigned int index)
{ {
def_operand_p op; def_operand_p op;
gcc_assert (index < v_must_defs->num_v_must_defs); gcc_assert (index < v_must_defs->num_v_must_defs);
op.def = &(v_must_defs->v_must_defs[index]); op.def = &(v_must_defs->v_must_defs[index].def);
return op;
}
/* Return a use_operand_p that is the V_MUST_DEF_KILL for the
V_MUST_DEF at INDEX in the V_MUST_DEFS array. */
static inline use_operand_p
get_v_must_def_kill_ptr (v_must_def_optype v_must_defs, unsigned int index)
{
use_operand_p op;
gcc_assert (index < v_must_defs->num_v_must_defs);
op.use = &(v_must_defs->v_must_defs[index].use);
return op; return op;
} }
...@@ -670,7 +681,12 @@ op_iter_next_use (ssa_op_iter *ptr) ...@@ -670,7 +681,12 @@ op_iter_next_use (ssa_op_iter *ptr)
if (ptr->v_mayu_i < ptr->num_v_mayu) if (ptr->v_mayu_i < ptr->num_v_mayu)
{ {
return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops, return V_MAY_DEF_OP_PTR (ptr->ops->v_may_def_ops,
(ptr->v_mayu_i)++); (ptr->v_mayu_i)++);
}
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
return V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops,
(ptr->v_mustu_i)++);
} }
ptr->done = true; ptr->done = true;
return NULL_USE_OPERAND_P; return NULL_USE_OPERAND_P;
...@@ -684,10 +700,10 @@ op_iter_next_def (ssa_op_iter *ptr) ...@@ -684,10 +700,10 @@ op_iter_next_def (ssa_op_iter *ptr)
{ {
return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++); return DEF_OP_PTR (ptr->ops->def_ops, (ptr->def_i)++);
} }
if (ptr->v_must_i < ptr->num_v_must) if (ptr->v_mustd_i < ptr->num_v_mustd)
{ {
return V_MUST_DEF_OP_PTR (ptr->ops->v_must_def_ops, return V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops,
(ptr->v_must_i)++); (ptr->v_mustd_i)++);
} }
if (ptr->v_mayd_i < ptr->num_v_mayd) if (ptr->v_mayd_i < ptr->num_v_mayd)
{ {
...@@ -714,14 +730,18 @@ op_iter_next_tree (ssa_op_iter *ptr) ...@@ -714,14 +730,18 @@ op_iter_next_tree (ssa_op_iter *ptr)
{ {
return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++); return V_MAY_DEF_OP (ptr->ops->v_may_def_ops, (ptr->v_mayu_i)++);
} }
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
return V_MUST_DEF_KILL (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
}
if (ptr->def_i < ptr->num_def) if (ptr->def_i < ptr->num_def)
{ {
return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++); return DEF_OP (ptr->ops->def_ops, (ptr->def_i)++);
} }
if (ptr->v_must_i < ptr->num_v_must) if (ptr->v_mustd_i < ptr->num_v_mustd)
{ {
return V_MUST_DEF_OP (ptr->ops->v_must_def_ops, return V_MUST_DEF_RESULT (ptr->ops->v_must_def_ops,
(ptr->v_must_i)++); (ptr->v_mustd_i)++);
} }
if (ptr->v_mayd_i < ptr->num_v_mayd) if (ptr->v_mayd_i < ptr->num_v_mayd)
{ {
...@@ -749,14 +769,17 @@ op_iter_init (ssa_op_iter *ptr, tree stmt, int flags) ...@@ -749,14 +769,17 @@ op_iter_init (ssa_op_iter *ptr, tree stmt, int flags)
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0; ? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF) ptr->num_v_mayd = (flags & SSA_OP_VMAYDEF)
? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0; ? NUM_V_MAY_DEFS (ops->v_may_def_ops) : 0;
ptr->num_v_must = (flags & SSA_OP_VMUSTDEF) ptr->num_v_mustu = (flags & SSA_OP_VMUSTDEFKILL)
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
ptr->num_v_mustd = (flags & SSA_OP_VMUSTDEF)
? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0; ? NUM_V_MUST_DEFS (ops->v_must_def_ops) : 0;
ptr->def_i = 0; ptr->def_i = 0;
ptr->use_i = 0; ptr->use_i = 0;
ptr->vuse_i = 0; ptr->vuse_i = 0;
ptr->v_mayu_i = 0; ptr->v_mayu_i = 0;
ptr->v_mayd_i = 0; ptr->v_mayd_i = 0;
ptr->v_must_i = 0; ptr->v_mustu_i = 0;
ptr->v_mustd_i = 0;
} }
/* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return /* Initialize iterator PTR to the use operands in STMT based on FLAGS. Return
...@@ -786,6 +809,25 @@ op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags) ...@@ -786,6 +809,25 @@ op_iter_init_tree (ssa_op_iter *ptr, tree stmt, int flags)
return op_iter_next_tree (ptr); return op_iter_next_tree (ptr);
} }
/* Get the next iterator mustdef value for PTR, returning the mustdef values in
KILL and DEF. */
static inline void
op_iter_next_mustdef (use_operand_p *kill, def_operand_p *def, ssa_op_iter *ptr)
{
if (ptr->v_mustu_i < ptr->num_v_mustu)
{
*def = V_MUST_DEF_RESULT_PTR (ptr->ops->v_must_def_ops, ptr->v_mustu_i);
*kill = V_MUST_DEF_KILL_PTR (ptr->ops->v_must_def_ops, (ptr->v_mustu_i)++);
return;
}
else
{
*def = NULL_DEF_OPERAND_P;
*kill = NULL_USE_OPERAND_P;
}
ptr->done = true;
return;
}
/* Get the next iterator maydef value for PTR, returning the maydef values in /* Get the next iterator maydef value for PTR, returning the maydef values in
USE and DEF. */ USE and DEF. */
static inline void static inline void
...@@ -815,4 +857,14 @@ op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use, ...@@ -815,4 +857,14 @@ op_iter_init_maydef (ssa_op_iter *ptr, tree stmt, use_operand_p *use,
op_iter_init (ptr, stmt, SSA_OP_VMAYUSE); op_iter_init (ptr, stmt, SSA_OP_VMAYUSE);
op_iter_next_maydef (use, def, ptr); op_iter_next_maydef (use, def, ptr);
} }
/* Initialize iterator PTR to the operands in STMT. Return the first operands
in KILL and DEF. */
static inline void
op_iter_init_mustdef (ssa_op_iter *ptr, tree stmt, use_operand_p *kill,
def_operand_p *def)
{
op_iter_init (ptr, stmt, SSA_OP_VMUSTDEFKILL);
op_iter_next_mustdef (kill, def, ptr);
}
#endif /* _TREE_FLOW_INLINE_H */ #endif /* _TREE_FLOW_INLINE_H */
...@@ -583,6 +583,7 @@ extern void kill_redundant_phi_nodes (void); ...@@ -583,6 +583,7 @@ extern void kill_redundant_phi_nodes (void);
/* In tree-into-ssa.c */ /* In tree-into-ssa.c */
extern void rewrite_into_ssa (bool); extern void rewrite_into_ssa (bool);
extern void rewrite_ssa_into_ssa (void); extern void rewrite_ssa_into_ssa (void);
extern void rewrite_def_def_chains (void);
void compute_global_livein (bitmap, bitmap); void compute_global_livein (bitmap, bitmap);
tree duplicate_ssa_name (tree, tree); tree duplicate_ssa_name (tree, tree);
......
...@@ -420,6 +420,11 @@ execute_todo (int properties, unsigned int flags) ...@@ -420,6 +420,11 @@ execute_todo (int properties, unsigned int flags)
rewrite_into_ssa (false); rewrite_into_ssa (false);
bitmap_clear (vars_to_rename); bitmap_clear (vars_to_rename);
} }
if (flags & TODO_fix_def_def_chains)
{
rewrite_def_def_chains ();
bitmap_clear (vars_to_rename);
}
if ((flags & TODO_dump_func) && dump_file) if ((flags & TODO_dump_func) && dump_file)
{ {
......
...@@ -106,6 +106,7 @@ struct dump_file_info ...@@ -106,6 +106,7 @@ struct dump_file_info
#define TODO_verify_ssa (1 << 3) #define TODO_verify_ssa (1 << 3)
#define TODO_verify_flow (1 << 4) #define TODO_verify_flow (1 << 4)
#define TODO_verify_stmts (1 << 5) #define TODO_verify_stmts (1 << 5)
#define TODO_fix_def_def_chains (1 << 6) /* rewrite def-def chains */
#define TODO_verify_all \ #define TODO_verify_all \
(TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts) (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts)
......
...@@ -2131,9 +2131,10 @@ newline_and_indent (pretty_printer *buffer, int spc) ...@@ -2131,9 +2131,10 @@ newline_and_indent (pretty_printer *buffer, int spc)
static void static void
dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
{ {
tree use, def; tree use;
use_operand_p use_p; use_operand_p use_p;
def_operand_p def_p; def_operand_p def_p;
use_operand_p kill_p;
ssa_op_iter iter; ssa_op_iter iter;
FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter) FOR_EACH_SSA_MAYDEF_OPERAND (def_p, use_p, stmt, iter)
...@@ -2148,10 +2149,14 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags) ...@@ -2148,10 +2149,14 @@ dump_vops (pretty_printer *buffer, tree stmt, int spc, int flags)
newline_and_indent (buffer, spc); newline_and_indent (buffer, spc);
} }
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_VMUSTDEF) FOR_EACH_SSA_MUSTDEF_OPERAND (def_p, kill_p, stmt, iter)
{ {
pp_string (buffer, "# V_MUST_DEF <"); pp_string (buffer, "# ");
dump_generic_node (buffer, def, spc + 2, flags, false); dump_generic_node (buffer, DEF_FROM_PTR (def_p),
spc + 2, flags, false);
pp_string (buffer, " = V_MUST_DEF <");
dump_generic_node (buffer, USE_FROM_PTR (kill_p),
spc + 2, flags, false);
pp_string (buffer, ">;"); pp_string (buffer, ">;");
newline_and_indent (buffer, spc); newline_and_indent (buffer, spc);
} }
......
...@@ -1041,7 +1041,7 @@ visit_assignment (tree stmt, tree *output_p) ...@@ -1041,7 +1041,7 @@ visit_assignment (tree stmt, tree *output_p)
{ {
/* If we make it here, then stmt only has one definition: /* If we make it here, then stmt only has one definition:
a V_MUST_DEF. */ a V_MUST_DEF. */
lhs = V_MUST_DEF_OP (v_must_defs, 0); lhs = V_MUST_DEF_RESULT (v_must_defs, 0);
} }
if (TREE_CODE (rhs) == SSA_NAME) if (TREE_CODE (rhs) == SSA_NAME)
......
...@@ -112,7 +112,7 @@ static void find_control_dependence (struct edge_list *, int); ...@@ -112,7 +112,7 @@ static void find_control_dependence (struct edge_list *, int);
static inline basic_block find_pdom (basic_block); static inline basic_block find_pdom (basic_block);
static inline void mark_stmt_necessary (tree, bool); static inline void mark_stmt_necessary (tree, bool);
static inline void mark_operand_necessary (tree); static inline void mark_operand_necessary (tree, bool);
static void mark_stmt_if_obviously_necessary (tree, bool); static void mark_stmt_if_obviously_necessary (tree, bool);
static void find_obviously_necessary_stmts (struct edge_list *); static void find_obviously_necessary_stmts (struct edge_list *);
...@@ -234,10 +234,11 @@ mark_stmt_necessary (tree stmt, bool add_to_worklist) ...@@ -234,10 +234,11 @@ mark_stmt_necessary (tree stmt, bool add_to_worklist)
VARRAY_PUSH_TREE (worklist, stmt); VARRAY_PUSH_TREE (worklist, stmt);
} }
/* Mark the statement defining operand OP as necessary. */ /* Mark the statement defining operand OP as necessary. PHIONLY is true
if we should only mark it necessary if it is a phi node. */
static inline void static inline void
mark_operand_necessary (tree op) mark_operand_necessary (tree op, bool phionly)
{ {
tree stmt; tree stmt;
int ver; int ver;
...@@ -253,7 +254,8 @@ mark_operand_necessary (tree op) ...@@ -253,7 +254,8 @@ mark_operand_necessary (tree op)
gcc_assert (stmt); gcc_assert (stmt);
if (NECESSARY (stmt) if (NECESSARY (stmt)
|| IS_EMPTY_STMT (stmt)) || IS_EMPTY_STMT (stmt)
|| (phionly && TREE_CODE (stmt) != PHI_NODE))
return; return;
NECESSARY (stmt) = 1; NECESSARY (stmt) = 1;
...@@ -592,7 +594,7 @@ propagate_necessity (struct edge_list *el) ...@@ -592,7 +594,7 @@ propagate_necessity (struct edge_list *el)
{ {
tree arg = PHI_ARG_DEF (i, k); tree arg = PHI_ARG_DEF (i, k);
if (TREE_CODE (arg) == SSA_NAME) if (TREE_CODE (arg) == SSA_NAME)
mark_operand_necessary (arg); mark_operand_necessary (arg, false);
} }
if (aggressive) if (aggressive)
...@@ -624,11 +626,79 @@ propagate_necessity (struct edge_list *el) ...@@ -624,11 +626,79 @@ propagate_necessity (struct edge_list *el)
links). */ links). */
FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES) FOR_EACH_SSA_TREE_OPERAND (use, i, iter, SSA_OP_ALL_USES)
mark_operand_necessary (use); mark_operand_necessary (use, false);
} }
} }
} }
/* Propagate necessity around virtual phi nodes used in kill operands.
The reason this isn't done during propagate_necessity is because we don't
want to keep phis around that are just there for must-defs, unless we
absolutely have to. After we've rewritten the reaching definitions to be
correct in the previous part of the fixup routine, we can simply propagate
around the information about which of these virtual phi nodes are really
used, and set the NECESSARY flag accordingly.
Note that we do the minimum here to ensure that we keep alive the phis that
are actually used in the corrected SSA form. In particular, some of these
phis may now have all of the same operand, and will be deleted by some
other pass. */
static void
mark_really_necessary_kill_operand_phis (void)
{
basic_block bb;
int i;
/* Seed the worklist with the new virtual phi arguments and virtual
uses */
FOR_EACH_BB (bb)
{
block_stmt_iterator bsi;
tree phi;
for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
{
if (!is_gimple_reg (PHI_RESULT (phi)) && NECESSARY (phi))
{
for (i = 0; i < PHI_NUM_ARGS (phi); i++)
mark_operand_necessary (PHI_ARG_DEF (phi, i), true);
}
}
for (bsi = bsi_last (bb); !bsi_end_p (bsi); bsi_prev (&bsi))
{
tree stmt = bsi_stmt (bsi);
if (NECESSARY (stmt))
{
use_operand_p use_p;
ssa_op_iter iter;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
{
tree use = USE_FROM_PTR (use_p);
mark_operand_necessary (use, true);
}
}
}
}
/* Mark all virtual phis still in use as necessary, and all of their
arguments that are phis as necessary. */
while (VARRAY_ACTIVE_SIZE (worklist) > 0)
{
tree use = VARRAY_TOP_TREE (worklist);
VARRAY_POP (worklist);
for (i = 0; i < PHI_NUM_ARGS (use); i++)
mark_operand_necessary (PHI_ARG_DEF (use, i), true);
}
}
/* Eliminate unnecessary statements. Any instruction not marked as necessary /* Eliminate unnecessary statements. Any instruction not marked as necessary
contributes nothing to the program, and can be deleted. */ contributes nothing to the program, and can be deleted. */
...@@ -640,7 +710,7 @@ eliminate_unnecessary_stmts (void) ...@@ -640,7 +710,7 @@ eliminate_unnecessary_stmts (void)
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nEliminating unnecessary statements:\n"); fprintf (dump_file, "\nEliminating unnecessary statements:\n");
clear_special_calls (); clear_special_calls ();
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
...@@ -650,23 +720,23 @@ eliminate_unnecessary_stmts (void) ...@@ -650,23 +720,23 @@ eliminate_unnecessary_stmts (void)
/* Remove dead statements. */ /* Remove dead statements. */
for (i = bsi_start (bb); ! bsi_end_p (i) ; ) for (i = bsi_start (bb); ! bsi_end_p (i) ; )
{ {
tree t = bsi_stmt (i); tree t = bsi_stmt (i);
stats.total++; stats.total++;
/* If `i' is not necessary then remove it. */ /* If `i' is not necessary then remove it. */
if (! NECESSARY (t)) if (! NECESSARY (t))
remove_dead_stmt (&i, bb); remove_dead_stmt (&i, bb);
else else
{ {
tree call = get_call_expr_in (t); tree call = get_call_expr_in (t);
if (call) if (call)
notice_special_calls (call); notice_special_calls (call);
bsi_next (&i); bsi_next (&i);
} }
} }
} }
} }
/* Remove dead PHI nodes from block BB. */ /* Remove dead PHI nodes from block BB. */
...@@ -711,6 +781,9 @@ static void ...@@ -711,6 +781,9 @@ static void
remove_dead_stmt (block_stmt_iterator *i, basic_block bb) remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
{ {
tree t = bsi_stmt (*i); tree t = bsi_stmt (*i);
def_operand_p def_p;
ssa_op_iter iter;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
{ {
...@@ -765,9 +838,16 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb) ...@@ -765,9 +838,16 @@ remove_dead_stmt (block_stmt_iterator *i, basic_block bb)
while (EDGE_COUNT (bb->succs) != 1) while (EDGE_COUNT (bb->succs) != 1)
remove_edge (EDGE_SUCC (bb, 1)); remove_edge (EDGE_SUCC (bb, 1));
} }
bsi_remove (i); FOR_EACH_SSA_DEF_OPERAND (def_p, t, iter,
release_defs (t); SSA_OP_VIRTUAL_DEFS | SSA_OP_VIRTUAL_KILLS)
{
tree def = DEF_FROM_PTR (def_p);
bitmap_set_bit (vars_to_rename,
var_ann (SSA_NAME_VAR (def))->uid);
}
bsi_remove (i);
release_defs (t);
} }
/* Print out removed statement statistics. */ /* Print out removed statement statistics. */
...@@ -875,6 +955,7 @@ perform_tree_ssa_dce (bool aggressive) ...@@ -875,6 +955,7 @@ perform_tree_ssa_dce (bool aggressive)
propagate_necessity (el); propagate_necessity (el);
mark_really_necessary_kill_operand_phis ();
eliminate_unnecessary_stmts (); eliminate_unnecessary_stmts ();
if (aggressive) if (aggressive)
...@@ -926,7 +1007,7 @@ struct tree_opt_pass pass_dce = ...@@ -926,7 +1007,7 @@ struct tree_opt_pass pass_dce =
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ TODO_fix_def_def_chains |TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */
0 /* letter */ 0 /* letter */
}; };
...@@ -943,7 +1024,7 @@ struct tree_opt_pass pass_cd_dce = ...@@ -943,7 +1024,7 @@ struct tree_opt_pass pass_cd_dce =
0, /* properties_provided */ 0, /* properties_provided */
0, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow, TODO_fix_def_def_chains | TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow,
/* todo_flags_finish */ /* todo_flags_finish */
0 /* letter */ 0 /* letter */
}; };
......
...@@ -436,7 +436,7 @@ determine_max_movement (tree stmt, bool must_preserve_exec) ...@@ -436,7 +436,7 @@ determine_max_movement (tree stmt, bool must_preserve_exec)
if (!add_dependency (val, lim_data, loop, true)) if (!add_dependency (val, lim_data, loop, true))
return false; return false;
FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES) FOR_EACH_SSA_TREE_OPERAND (val, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
if (!add_dependency (val, lim_data, loop, false)) if (!add_dependency (val, lim_data, loop, false))
return false; return false;
...@@ -1034,8 +1034,7 @@ rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs) ...@@ -1034,8 +1034,7 @@ rewrite_mem_refs (tree tmp_var, struct mem_ref *mem_refs)
for (; mem_refs; mem_refs = mem_refs->next) for (; mem_refs; mem_refs = mem_refs->next)
{ {
FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, FOR_EACH_SSA_TREE_OPERAND (var, mem_refs->stmt, iter, SSA_OP_ALL_VIRTUALS)
(SSA_OP_VIRTUAL_DEFS | SSA_OP_VUSE))
{ {
var = SSA_NAME_VAR (var); var = SSA_NAME_VAR (var);
bitmap_set_bit (vars_to_rename, var_ann (var)->uid); bitmap_set_bit (vars_to_rename, var_ann (var)->uid);
......
...@@ -254,7 +254,7 @@ find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks) ...@@ -254,7 +254,7 @@ find_uses_to_rename_stmt (tree stmt, bitmap *use_blocks)
get_stmt_operands (stmt); get_stmt_operands (stmt);
FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES) FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_ALL_USES | SSA_OP_ALL_KILLS)
find_uses_to_rename_use (bb, var, use_blocks); find_uses_to_rename_use (bb, var, use_blocks);
} }
......
...@@ -174,7 +174,7 @@ allocate_v_may_def_optype (unsigned num) ...@@ -174,7 +174,7 @@ allocate_v_may_def_optype (unsigned num)
v_may_def_optype v_may_def_ops; v_may_def_optype v_may_def_ops;
unsigned size; unsigned size;
size = sizeof (struct v_may_def_optype_d) size = sizeof (struct v_may_def_optype_d)
+ sizeof (v_may_def_operand_type_t) * (num - 1); + sizeof (v_def_use_operand_type_t) * (num - 1);
v_may_def_ops = ggc_alloc (size); v_may_def_ops = ggc_alloc (size);
v_may_def_ops->num_v_may_defs = num; v_may_def_ops->num_v_may_defs = num;
return v_may_def_ops; return v_may_def_ops;
...@@ -202,7 +202,7 @@ allocate_v_must_def_optype (unsigned num) ...@@ -202,7 +202,7 @@ allocate_v_must_def_optype (unsigned num)
{ {
v_must_def_optype v_must_def_ops; v_must_def_optype v_must_def_ops;
unsigned size; unsigned size;
size = sizeof (struct v_must_def_optype_d) + sizeof (tree) * (num - 1); size = sizeof (struct v_must_def_optype_d) + sizeof (v_def_use_operand_type_t) * (num - 1);
v_must_def_ops = ggc_alloc (size); v_must_def_ops = ggc_alloc (size);
v_must_def_ops->num_v_must_defs = num; v_must_def_ops->num_v_must_defs = num;
return v_must_def_ops; return v_must_def_ops;
...@@ -650,7 +650,7 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p, ...@@ -650,7 +650,7 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p,
build_diff = false; build_diff = false;
for (x = 0; x < num; x++) for (x = 0; x < num; x++)
{ {
tree var = old_ops->v_must_defs[x]; tree var = old_ops->v_must_defs[x].def;
if (TREE_CODE (var) == SSA_NAME) if (TREE_CODE (var) == SSA_NAME)
var = SSA_NAME_VAR (var); var = SSA_NAME_VAR (var);
if (var != VARRAY_TREE (build_v_must_defs, x)) if (var != VARRAY_TREE (build_v_must_defs, x))
...@@ -677,17 +677,21 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p, ...@@ -677,17 +677,21 @@ finalize_ssa_v_must_defs (v_must_def_optype *old_ops_p,
/* Look for VAR in the original vector. */ /* Look for VAR in the original vector. */
for (i = 0; i < old_num; i++) for (i = 0; i < old_num; i++)
{ {
result = old_ops->v_must_defs[i]; result = old_ops->v_must_defs[i].def;
if (TREE_CODE (result) == SSA_NAME) if (TREE_CODE (result) == SSA_NAME)
result = SSA_NAME_VAR (result); result = SSA_NAME_VAR (result);
if (result == var) if (result == var)
{ {
v_must_def_ops->v_must_defs[x] = old_ops->v_must_defs[i]; v_must_def_ops->v_must_defs[x].def = old_ops->v_must_defs[i].def;
v_must_def_ops->v_must_defs[x].use = old_ops->v_must_defs[i].use;
break; break;
} }
} }
if (i == old_num) if (i == old_num)
v_must_def_ops->v_must_defs[x] = var; {
v_must_def_ops->v_must_defs[x].def = var;
v_must_def_ops->v_must_defs[x].use = var;
}
} }
} }
VARRAY_POP_ALL (build_v_must_defs); VARRAY_POP_ALL (build_v_must_defs);
...@@ -1672,7 +1676,10 @@ copy_virtual_operands (tree dst, tree src) ...@@ -1672,7 +1676,10 @@ copy_virtual_operands (tree dst, tree src)
{ {
*v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs)); *v_must_defs_new = allocate_v_must_def_optype (NUM_V_MUST_DEFS (v_must_defs));
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
SET_V_MUST_DEF_OP (*v_must_defs_new, i, V_MUST_DEF_OP (v_must_defs, i)); {
SET_V_MUST_DEF_RESULT (*v_must_defs_new, i, V_MUST_DEF_RESULT (v_must_defs, i));
SET_V_MUST_DEF_KILL (*v_must_defs_new, i, V_MUST_DEF_KILL (v_must_defs, i));
}
} }
} }
...@@ -1701,7 +1708,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt) ...@@ -1701,7 +1708,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt)
free_vuses (&(ann->operands.vuse_ops)); free_vuses (&(ann->operands.vuse_ops));
free_v_may_defs (&(ann->operands.v_may_def_ops)); free_v_may_defs (&(ann->operands.v_may_def_ops));
free_v_must_defs (&(ann->operands.v_must_def_ops)); free_v_must_defs (&(ann->operands.v_must_def_ops));
/* For each VDEF on the original statement, we want to create a /* For each VDEF on the original statement, we want to create a
VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new VUSE of the V_MAY_DEF result or V_MUST_DEF op on the new
statement. */ statement. */
...@@ -1713,7 +1720,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt) ...@@ -1713,7 +1720,7 @@ create_ssa_artficial_load_stmt (stmt_operands_p old_ops, tree new_stmt)
for (j = 0; j < NUM_V_MUST_DEFS (old_ops->v_must_def_ops); j++) for (j = 0; j < NUM_V_MUST_DEFS (old_ops->v_must_def_ops); j++)
{ {
op = V_MUST_DEF_OP (old_ops->v_must_def_ops, j); op = V_MUST_DEF_RESULT (old_ops->v_must_def_ops, j);
append_vuse (op); append_vuse (op);
} }
......
...@@ -58,17 +58,17 @@ typedef struct use_optype_d GTY(()) ...@@ -58,17 +58,17 @@ typedef struct use_optype_d GTY(())
typedef use_optype_t *use_optype; typedef use_optype_t *use_optype;
/* Operand type which stores a def and a use tree. */ /* Operand type which stores a def and a use tree. */
typedef struct v_may_def_operand_type GTY(()) typedef struct v_def_use_operand_type GTY(())
{ {
tree def; tree def;
tree use; tree use;
} v_may_def_operand_type_t; } v_def_use_operand_type_t;
/* This represents the MAY_DEFS for a stmt. */ /* This represents the MAY_DEFS for a stmt. */
typedef struct v_may_def_optype_d GTY(()) typedef struct v_may_def_optype_d GTY(())
{ {
unsigned num_v_may_defs; unsigned num_v_may_defs;
struct v_may_def_operand_type GTY((length ("%h.num_v_may_defs"))) struct v_def_use_operand_type GTY((length ("%h.num_v_may_defs")))
v_may_defs[1]; v_may_defs[1];
} v_may_def_optype_t; } v_may_def_optype_t;
...@@ -87,7 +87,7 @@ typedef vuse_optype_t *vuse_optype; ...@@ -87,7 +87,7 @@ typedef vuse_optype_t *vuse_optype;
typedef struct v_must_def_optype_d GTY(()) typedef struct v_must_def_optype_d GTY(())
{ {
unsigned num_v_must_defs; unsigned num_v_must_defs;
tree GTY((length("%h.num_v_must_defs"))) v_must_defs[1]; v_def_use_operand_type_t GTY((length("%h.num_v_must_defs"))) v_must_defs[1];
} v_must_def_optype_t; } v_must_def_optype_t;
typedef v_must_def_optype_t *v_must_def_optype; typedef v_must_def_optype_t *v_must_def_optype;
...@@ -157,12 +157,14 @@ typedef stmt_operands_t *stmt_operands_p; ...@@ -157,12 +157,14 @@ typedef stmt_operands_t *stmt_operands_p;
#define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN) #define V_MUST_DEF_OPS(ANN) get_v_must_def_ops (ANN)
#define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT)) #define STMT_V_MUST_DEF_OPS(STMT) get_v_must_def_ops (stmt_ann (STMT))
#define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0) #define NUM_V_MUST_DEFS(OPS) ((OPS) ? (OPS)->num_v_must_defs : 0)
#define V_MUST_DEF_OP_PTR(OPS, I) get_v_must_def_op_ptr ((OPS), (I)) #define V_MUST_DEF_RESULT_PTR(OPS, I) get_v_must_def_result_ptr ((OPS), (I))
#define V_MUST_DEF_OP(OPS, I) \ #define V_MUST_DEF_RESULT(OPS, I) \
(DEF_FROM_PTR (V_MUST_DEF_OP_PTR ((OPS), (I)))) (DEF_FROM_PTR (V_MUST_DEF_RESULT_PTR ((OPS), (I))))
#define SET_V_MUST_DEF_OP(OPS, I, V) \ #define SET_V_MUST_DEF_RESULT(OPS, I, V) \
(SET_DEF (V_MUST_DEF_OP_PTR ((OPS), (I)), (V))) (SET_DEF (V_MUST_DEF_RESULT_PTR ((OPS), (I)), (V)))
#define V_MUST_DEF_KILL_PTR(OPS, I) get_v_must_def_kill_ptr ((OPS), (I))
#define V_MUST_DEF_KILL(OPS, I) (USE_FROM_PTR (V_MUST_DEF_KILL_PTR ((OPS), (I))))
#define SET_V_MUST_DEF_KILL(OPS, I, V) (SET_USE (V_MUST_DEF_KILL_PTR ((OPS), (I)), (V)))
#define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI) #define PHI_RESULT_PTR(PHI) get_phi_result_ptr (PHI)
#define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI)) #define PHI_RESULT(PHI) DEF_FROM_PTR (PHI_RESULT_PTR (PHI))
...@@ -199,13 +201,15 @@ typedef struct ssa_operand_iterator_d ...@@ -199,13 +201,15 @@ typedef struct ssa_operand_iterator_d
int num_vuse; int num_vuse;
int num_v_mayu; int num_v_mayu;
int num_v_mayd; int num_v_mayd;
int num_v_must; int num_v_mustu;
int num_v_mustd;
int use_i; int use_i;
int def_i; int def_i;
int vuse_i; int vuse_i;
int v_mayu_i; int v_mayu_i;
int v_mayd_i; int v_mayd_i;
int v_must_i; int v_mustu_i;
int v_mustd_i;
stmt_operands_p ops; stmt_operands_p ops;
bool done; bool done;
} ssa_op_iter; } ssa_op_iter;
...@@ -218,13 +222,17 @@ typedef struct ssa_operand_iterator_d ...@@ -218,13 +222,17 @@ typedef struct ssa_operand_iterator_d
#define SSA_OP_VMAYUSE 0x08 /* USE portion of V_MAY_DEFS. */ #define SSA_OP_VMAYUSE 0x08 /* USE portion of V_MAY_DEFS. */
#define SSA_OP_VMAYDEF 0x10 /* DEF portion of V_MAY_DEFS. */ #define SSA_OP_VMAYDEF 0x10 /* DEF portion of V_MAY_DEFS. */
#define SSA_OP_VMUSTDEF 0x20 /* V_MUST_DEF definitions. */ #define SSA_OP_VMUSTDEF 0x20 /* V_MUST_DEF definitions. */
#define SSA_OP_VMUSTDEFKILL 0x40 /* V_MUST_DEF kills. */
/* These are commonly grouped operand flags. */ /* These are commonly grouped operand flags. */
#define SSA_OP_VIRTUAL_USES (SSA_OP_VUSE | SSA_OP_VMAYUSE) #define SSA_OP_VIRTUAL_USES (SSA_OP_VUSE | SSA_OP_VMAYUSE)
#define SSA_OP_VIRTUAL_DEFS (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF) #define SSA_OP_VIRTUAL_DEFS (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF)
#define SSA_OP_VIRTUAL_KILLS (SSA_OP_VMUSTDEFKILL)
#define SSA_OP_ALL_VIRTUALS (SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS | SSA_OP_VIRTUAL_DEFS)
#define SSA_OP_ALL_USES (SSA_OP_VIRTUAL_USES | SSA_OP_USE) #define SSA_OP_ALL_USES (SSA_OP_VIRTUAL_USES | SSA_OP_USE)
#define SSA_OP_ALL_DEFS (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF) #define SSA_OP_ALL_DEFS (SSA_OP_VIRTUAL_DEFS | SSA_OP_DEF)
#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS) #define SSA_OP_ALL_KILLS (SSA_OP_VIRTUAL_KILLS)
#define SSA_OP_ALL_OPERANDS (SSA_OP_ALL_USES | SSA_OP_ALL_DEFS | SSA_OP_ALL_KILLS)
/* This macro executes a loop over the operands of STMT specified in FLAG, /* This macro executes a loop over the operands of STMT specified in FLAG,
returning each operand as a 'tree' in the variable TREEVAR. ITER is an returning each operand as a 'tree' in the variable TREEVAR. ITER is an
...@@ -258,4 +266,12 @@ typedef struct ssa_operand_iterator_d ...@@ -258,4 +266,12 @@ typedef struct ssa_operand_iterator_d
!op_iter_done (&(ITER)); \ !op_iter_done (&(ITER)); \
op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER))) op_iter_next_maydef (&(USEVAR), &(DEFVAR), &(ITER)))
/* This macro executes a loop over the V_MUST_DEF operands of STMT. The def
and kill for each V_MUST_DEF is returned in DEFVAR and KILLVAR.
ITER is an ssa_op_iter structure used to control the loop. */
#define FOR_EACH_SSA_MUSTDEF_OPERAND(DEFVAR, KILLVAR, STMT, ITER) \
for (op_iter_init_mustdef (&(ITER), STMT, &(KILLVAR), &(DEFVAR)); \
!op_iter_done (&(ITER)); \
op_iter_next_mustdef (&(KILLVAR), &(DEFVAR), &(ITER)))
#endif /* GCC_TREE_SSA_OPERANDS_H */ #endif /* GCC_TREE_SSA_OPERANDS_H */
...@@ -672,7 +672,7 @@ verify_ssa (void) ...@@ -672,7 +672,7 @@ verify_ssa (void)
{ {
tree stmt = bsi_stmt (bsi); tree stmt = bsi_stmt (bsi);
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES) FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
{ {
if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)], if (verify_use (bb, definition_block[SSA_NAME_VERSION (op)],
op, stmt, false, true, op, stmt, false, true,
...@@ -1082,7 +1082,8 @@ replace_immediate_uses (tree var, tree repl) ...@@ -1082,7 +1082,8 @@ replace_immediate_uses (tree var, tree repl)
} }
else else
{ {
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_VIRTUAL_USES) FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter,
SSA_OP_VIRTUAL_USES | SSA_OP_VIRTUAL_KILLS)
if (USE_FROM_PTR (use_p) == var) if (USE_FROM_PTR (use_p) == var)
propagate_value (use_p, repl); propagate_value (use_p, repl);
} }
...@@ -1464,3 +1465,4 @@ struct tree_opt_pass pass_late_warn_uninitialized = ...@@ -1464,3 +1465,4 @@ struct tree_opt_pass pass_late_warn_uninitialized =
0, /* todo_flags_finish */ 0, /* todo_flags_finish */
0 /* letter */ 0 /* letter */
}; };
...@@ -381,7 +381,10 @@ rename_variables_in_bb (basic_block bb) ...@@ -381,7 +381,10 @@ rename_variables_in_bb (basic_block bb)
v_must_defs = V_MUST_DEF_OPS (ann); v_must_defs = V_MUST_DEF_OPS (ann);
for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++) for (i = 0; i < NUM_V_MUST_DEFS (v_must_defs); i++)
rename_def_op (V_MUST_DEF_OP_PTR (v_must_defs, i), stmt); {
rename_use_op (V_MUST_DEF_KILL_PTR (v_must_defs, i));
rename_def_op (V_MUST_DEF_RESULT_PTR (v_must_defs, i), stmt);
}
} }
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
...@@ -1853,7 +1856,7 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset, ...@@ -1853,7 +1856,7 @@ vect_create_data_ref_ptr (tree stmt, block_stmt_iterator *bsi, tree offset,
} }
for (i = 0; i < nv_must_defs; i++) for (i = 0; i < nv_must_defs; i++)
{ {
tree def = V_MUST_DEF_OP (v_must_defs, i); tree def = V_MUST_DEF_RESULT (v_must_defs, i);
if (TREE_CODE (def) == SSA_NAME) if (TREE_CODE (def) == SSA_NAME)
bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid); bitmap_set_bit (vars_to_rename, var_ann (SSA_NAME_VAR (def))->uid);
} }
......
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