Add source_location support to PHI arguments.

2009-07-29  Andrew MacLeod  <amacleod@redhat.com>

	PR debug 26475
	* tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set
	location for phi arguments.
	(rewrite_update_phi_arguments): Find locations for reaching defs.
	* tree-ssa-threadupdate.c (create_edge_and_update_destination_phis):
	Add location to add_phi_arg calls.
	* tree-loop-districbution.c (update_phis_for_loop_copy): Add locations.
	* tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge,
	split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations.
	* tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call,
	create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations.
	* tree.h (struct phi_arg_d): Add location_t to PHI arguments.
	* tree-phinodes.c (make_phi_node): Initialize location.
	(resize_phi_node): Initialize location to UNKNOWN_LOCATION.
	(add_phi_arg): Add location parameter.
	(remove_phi_arg_num): Move location when moving phi argument.
	* omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set 
	location.
	* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop,
	slpeel_update_phi_nodes_for_guard1,
	slpeel_update_phi_nodes_for_guard2,
	slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations,
	vect_loop_versioning): Set locations.
	* tree-parloops.c (create_phi_for_local_result,
	transform_to_exit_first_loop, create_parallel_loop): Add locations.
	* gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present.
	* tree-vect-loop.c (get_initial_def_for_induction,
	vect_create_epilog_for_reduction, vect_finalize_reduction): Add
	locations.
	* tree-flow-inline.h (gimple_phi_arg_location): New.  Return locus.
	(gimple_phi_arg_location_from_edge): New.  Return locus from an edge.
	(gimple_phi_arg_set_location): New.  Set locus.
	(gimple_phi_arg_has_location): New.  Check for locus.
	(redirect_edge_var_map_location): New.  Return locus from var_map.
	* tree-vect-data-refs.c (vect_setup_realignment): Set location.
	* tree-ssa-phiopt.c (conditional_replacement): Set locus when
	combining PHI arguments.
	(cond_store_replacement): Set location.
	* cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible.
	* grpahite.c (add_loop_exit_phis, add_guard_exit_phis,
	scop_add_exit_phis_edge): Add locations.
	* tree-cfgcleanup.c (remove_forwarder_block,
	remove_forwarder_block_with_phi): Add locations.
	* tree-ssa-pre.c (insert_into_preds_of_block): Add locations.
	* tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add
	locations.
	* tree-ssa-dce.c (forward_edge_to_pdom): Add locations.
	* tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge,
	flush_pending_stmts): Add source location.
	* lambda-code.c (perfect_nestify): Maintain location stack with argument
	stack to preserve locations.
	* tree-vect-stmts.c (vectorizable_load): Add location.
	* tree-inline.c (copy_phis_for_bb): Copy locus.
	(setup_one_parameter): Add call locus to inlined parameter stmts.
	(initialize_inlined_parameters): Pass in call location as parameter
	assignment locus.
	(tree_function_versioning): Pass location to setup_one_parameter.
	* tree-ssa-phiprop.c (phiprop_insert_phi): Set locations.
	* tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for
	copy and edge lists.
	(insert_partition_copy_on_edge, insert_value_copy_on_edge,
	insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a 
	locus parameter and override the stmt default if provided.
	(new_elim_graph, clear_elim_graph, delete_elim_graph,
	elim_graph_add_edge, elim_graph_remove_succ_edge,
	FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build,
	elim_forward, elim_unvisited_predecessor, elim_backward, elim_create,
	eliminate_phi):  Add locus info in elimination graph for each edge and
	value copy.
	(insert_backedge_copies): Copy locus if present.
	* tree-flow.h (struct _edge_var_map): Add locus field.
	* tree-switch_conversions.c (fix_phi_nodes): Add locations.
	* tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block,
	add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add 
	locations.
	* ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations.

From-SVN: r150267
This commit is contained in:
Andrew MacLeod 2009-07-30 18:36:30 +00:00 committed by Andrew Macleod
parent 8a04f5d8b7
commit f5045c967e
32 changed files with 424 additions and 109 deletions

View File

@ -1,3 +1,82 @@
2009-07-30 Andrew MacLeod <amacleod@redhat.com>
PR debug/26475
* tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set
location for phi arguments.
(rewrite_update_phi_arguments): Find locations for reaching defs.
* tree-ssa-threadupdate.c (create_edge_and_update_destination_phis):
Add location to add_phi_arg calls.
* tree-loop-districbution.c (update_phis_for_loop_copy): Add locations.
* tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge,
split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations.
* tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call,
create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations.
* tree.h (struct phi_arg_d): Add location_t to PHI arguments.
* tree-phinodes.c (make_phi_node): Initialize location.
(resize_phi_node): Initialize location to UNKNOWN_LOCATION.
(add_phi_arg): Add location parameter.
(remove_phi_arg_num): Move location when moving phi argument.
* omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set
location.
* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop,
slpeel_update_phi_nodes_for_guard1,
slpeel_update_phi_nodes_for_guard2,
slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations,
vect_loop_versioning): Set locations.
* tree-parloops.c (create_phi_for_local_result,
transform_to_exit_first_loop, create_parallel_loop): Add locations.
* gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present.
* tree-vect-loop.c (get_initial_def_for_induction,
vect_create_epilog_for_reduction, vect_finalize_reduction): Add
locations.
* tree-flow-inline.h (gimple_phi_arg_location): New. Return locus.
(gimple_phi_arg_location_from_edge): New. Return locus from an edge.
(gimple_phi_arg_set_location): New. Set locus.
(gimple_phi_arg_has_location): New. Check for locus.
(redirect_edge_var_map_location): New. Return locus from var_map.
* tree-vect-data-refs.c (vect_setup_realignment): Set location.
* tree-ssa-phiopt.c (conditional_replacement): Set locus when
combining PHI arguments.
(cond_store_replacement): Set location.
* cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible.
* grpahite.c (add_loop_exit_phis, add_guard_exit_phis,
scop_add_exit_phis_edge): Add locations.
* tree-cfgcleanup.c (remove_forwarder_block,
remove_forwarder_block_with_phi): Add locations.
* tree-ssa-pre.c (insert_into_preds_of_block): Add locations.
* tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add
locations.
* tree-ssa-dce.c (forward_edge_to_pdom): Add locations.
* tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge,
flush_pending_stmts): Add source location.
* lambda-code.c (perfect_nestify): Maintain location stack with argument
stack to preserve locations.
* tree-vect-stmts.c (vectorizable_load): Add location.
* tree-inline.c (copy_phis_for_bb): Copy locus.
(setup_one_parameter): Add call locus to inlined parameter stmts.
(initialize_inlined_parameters): Pass in call location as parameter
assignment locus.
(tree_function_versioning): Pass location to setup_one_parameter.
* tree-ssa-phiprop.c (phiprop_insert_phi): Set locations.
* tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for
copy and edge lists.
(insert_partition_copy_on_edge, insert_value_copy_on_edge,
insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a
locus parameter and override the stmt default if provided.
(new_elim_graph, clear_elim_graph, delete_elim_graph,
elim_graph_add_edge, elim_graph_remove_succ_edge,
FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build,
elim_forward, elim_unvisited_predecessor, elim_backward, elim_create,
eliminate_phi): Add locus info in elimination graph for each edge and
value copy.
(insert_backedge_copies): Copy locus if present.
* tree-flow.h (struct _edge_var_map): Add locus field.
* tree-switch_conversions.c (fix_phi_nodes): Add locations.
* tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block,
add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add
locations.
* ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations.
2009-07-30 Martin Jambor <mjambor@suse.cz> 2009-07-30 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/40570 PR tree-optimization/40570

View File

@ -74,6 +74,9 @@ gimple_assign_rhs_to_tree (gimple stmt)
else else
gcc_unreachable (); gcc_unreachable ();
if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
SET_EXPR_LOCATION (t, gimple_location (stmt));
return t; return t;
} }

View File

@ -1150,6 +1150,22 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
} }
for (i = 0; i < gimple_phi_num_args (phi); i++) for (i = 0; i < gimple_phi_num_args (phi); i++)
{ {
if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i))
{
expanded_location xloc;
xloc = expand_location (gimple_phi_arg_location (phi, i));
pp_character (buffer, '[');
if (xloc.file)
{
pp_string (buffer, xloc.file);
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, xloc.line);
pp_string (buffer, ":");
pp_decimal_int (buffer, xloc.column);
pp_string (buffer, "] ");
}
dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags, dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
false); false);
pp_character (buffer, '('); pp_character (buffer, '(');

View File

@ -4555,7 +4555,7 @@ add_loop_exit_phis (void **slot, void *s)
tree res = create_new_def_for (gimple_phi_result (phi), phi, tree res = create_new_def_for (gimple_phi_result (phi), phi,
gimple_phi_result_ptr (phi)); gimple_phi_result_ptr (phi));
add_phi_arg (phi, new_name, single_pred_edge (bb)); add_phi_arg (phi, new_name, single_pred_edge (bb), UNKNOWN_LOCATION);
entry->new_name = res; entry->new_name = res;
*slot = entry; *slot = entry;
@ -4617,8 +4617,8 @@ add_guard_exit_phis (void **slot, void *s)
tree res = create_new_def_for (gimple_phi_result (phi), phi, tree res = create_new_def_for (gimple_phi_result (phi), phi,
gimple_phi_result_ptr (phi)); gimple_phi_result_ptr (phi));
add_phi_arg (phi, name1, true_edge); add_phi_arg (phi, name1, true_edge, UNKNOWN_LOCATION);
add_phi_arg (phi, name2, false_edge); add_phi_arg (phi, name2, false_edge, UNKNOWN_LOCATION);
entry->new_name = res; entry->new_name = res;
*slot = entry; *slot = entry;
@ -5141,8 +5141,8 @@ scop_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e)
create_new_def_for (gimple_phi_result (phi), phi, create_new_def_for (gimple_phi_result (phi), phi,
gimple_phi_result_ptr (phi)); gimple_phi_result_ptr (phi));
add_phi_arg (phi, use, false_e); add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION);
add_phi_arg (phi, use, true_e); add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION);
} }
/* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are /* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are

View File

@ -658,7 +658,7 @@ make_edge_and_fix_phis_of_dest (basic_block bb, edge e)
{ {
gimple phi = gsi_stmt (si); gimple phi = gsi_stmt (si);
arg = PHI_ARG_DEF_FROM_EDGE (phi, e); arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (phi, arg, new_e); add_phi_arg (phi, arg, new_e, gimple_phi_arg_location_from_edge (phi, e));
} }
return new_e; return new_e;

View File

@ -2343,6 +2343,10 @@ can_convert_to_perfect_nest (struct loop *loop)
return false; return false;
} }
DEF_VEC_I(source_location);
DEF_VEC_ALLOC_I(source_location,heap);
/* Transform the loop nest into a perfect nest, if possible. /* Transform the loop nest into a perfect nest, if possible.
LOOP is the loop nest to transform into a perfect nest LOOP is the loop nest to transform into a perfect nest
LBOUNDS are the lower bounds for the loops to transform LBOUNDS are the lower bounds for the loops to transform
@ -2400,6 +2404,7 @@ perfect_nestify (struct loop *loop,
gimple stmt; gimple stmt;
tree oldivvar, ivvar, ivvarinced; tree oldivvar, ivvar, ivvarinced;
VEC(tree,heap) *phis = NULL; VEC(tree,heap) *phis = NULL;
VEC(source_location,heap) *locations = NULL;
htab_t replacements = NULL; htab_t replacements = NULL;
/* Create the new loop. */ /* Create the new loop. */
@ -2412,8 +2417,11 @@ perfect_nestify (struct loop *loop,
{ {
phi = gsi_stmt (bsi); phi = gsi_stmt (bsi);
VEC_reserve (tree, heap, phis, 2); VEC_reserve (tree, heap, phis, 2);
VEC_reserve (source_location, heap, locations, 1);
VEC_quick_push (tree, phis, PHI_RESULT (phi)); VEC_quick_push (tree, phis, PHI_RESULT (phi));
VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0)); VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0));
VEC_quick_push (source_location, locations,
gimple_phi_arg_location (phi, 0));
} }
e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb); e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb);
@ -2426,10 +2434,12 @@ perfect_nestify (struct loop *loop,
{ {
tree def; tree def;
tree phiname; tree phiname;
source_location locus;
def = VEC_pop (tree, phis); def = VEC_pop (tree, phis);
phiname = VEC_pop (tree, phis); phiname = VEC_pop (tree, phis);
locus = VEC_pop (source_location, locations);
phi = create_phi_node (phiname, preheaderbb); phi = create_phi_node (phiname, preheaderbb);
add_phi_arg (phi, def, single_pred_edge (preheaderbb)); add_phi_arg (phi, def, single_pred_edge (preheaderbb), locus);
} }
flush_pending_stmts (e); flush_pending_stmts (e);
VEC_free (tree, heap, phis); VEC_free (tree, heap, phis);

View File

@ -3013,8 +3013,8 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
{ {
gimple phi = create_phi_node (tmp_join, bb); gimple phi = create_phi_node (tmp_join, bb);
SSA_NAME_DEF_STMT (tmp_join) = phi; SSA_NAME_DEF_STMT (tmp_join) = phi;
add_phi_arg (phi, tmp_then, e_then); add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
add_phi_arg (phi, tmp_else, e_else); add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
} }
val = tmp_join; val = tmp_join;
@ -4508,6 +4508,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
gsi_next (&psi), ++i) gsi_next (&psi), ++i)
{ {
gimple nphi; gimple nphi;
source_location locus;
phi = gsi_stmt (psi); phi = gsi_stmt (psi);
t = gimple_phi_result (phi); t = gimple_phi_result (phi);
@ -4516,12 +4517,15 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
SSA_NAME_DEF_STMT (t) = nphi; SSA_NAME_DEF_STMT (t) = nphi;
t = PHI_ARG_DEF_FROM_EDGE (phi, se); t = PHI_ARG_DEF_FROM_EDGE (phi, se);
locus = gimple_phi_arg_location_from_edge (phi, se);
/* A special case -- fd->loop.v is not yet computed in /* A special case -- fd->loop.v is not yet computed in
iter_part_bb, we need to use v_extra instead. */ iter_part_bb, we need to use v_extra instead. */
if (t == fd->loop.v) if (t == fd->loop.v)
t = v_extra; t = v_extra;
add_phi_arg (nphi, t, ene); add_phi_arg (nphi, t, ene, locus);
add_phi_arg (nphi, redirect_edge_var_map_def (vm), re); locus = redirect_edge_var_map_location (vm);
add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
} }
gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head)); gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
redirect_edge_var_map_clear (re); redirect_edge_var_map_clear (re);
@ -4536,8 +4540,10 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
/* Make phi node for trip. */ /* Make phi node for trip. */
phi = create_phi_node (trip_main, iter_part_bb); phi = create_phi_node (trip_main, iter_part_bb);
SSA_NAME_DEF_STMT (trip_main) = phi; SSA_NAME_DEF_STMT (trip_main) = phi;
add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb)); add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
add_phi_arg (phi, trip_init, single_succ_edge (entry_bb)); UNKNOWN_LOCATION);
add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
UNKNOWN_LOCATION);
} }
set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb); set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);

View File

@ -2886,7 +2886,7 @@ reinstall_phi_args (edge new_edge, edge old_edge)
gcc_assert (result == gimple_phi_result (phi)); gcc_assert (result == gimple_phi_result (phi));
add_phi_arg (phi, arg, new_edge); add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
} }
redirect_edge_var_map_clear (old_edge); redirect_edge_var_map_clear (old_edge);
@ -4840,7 +4840,8 @@ gimple_make_forwarder_block (edge fallthru)
new_phi = create_phi_node (var, bb); new_phi = create_phi_node (var, bb);
SSA_NAME_DEF_STMT (var) = new_phi; SSA_NAME_DEF_STMT (var) = new_phi;
gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi)); gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
add_phi_arg (new_phi, gimple_phi_result (phi), fallthru); add_phi_arg (new_phi, gimple_phi_result (phi), fallthru,
UNKNOWN_LOCATION);
} }
/* Add the arguments we have stored on edges. */ /* Add the arguments we have stored on edges. */
@ -5239,7 +5240,8 @@ add_phi_args_after_copy_edge (edge e_copy)
phi = gsi_stmt (psi); phi = gsi_stmt (psi);
phi_copy = gsi_stmt (psi_copy); phi_copy = gsi_stmt (psi_copy);
def = PHI_ARG_DEF_FROM_EDGE (phi, e); def = PHI_ARG_DEF_FROM_EDGE (phi, e);
add_phi_arg (phi_copy, def, e_copy); add_phi_arg (phi_copy, def, e_copy,
gimple_phi_arg_location_from_edge (phi, e));
} }
} }
@ -7058,7 +7060,7 @@ gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
phi1 = gsi_stmt (psi1); phi1 = gsi_stmt (psi1);
phi2 = gsi_stmt (psi2); phi2 = gsi_stmt (psi2);
def = PHI_ARG_DEF (phi2, e2->dest_idx); def = PHI_ARG_DEF (phi2, e2->dest_idx);
add_phi_arg (phi1, def, e); add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
} }
} }

View File

@ -401,7 +401,8 @@ remove_forwarder_block (basic_block bb)
gsi_next (&gsi)) gsi_next (&gsi))
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s); source_location l = gimple_phi_arg_location_from_edge (phi, succ);
add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l);
} }
} }
} }
@ -744,6 +745,7 @@ remove_forwarder_block_with_phi (basic_block bb)
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
tree def = gimple_phi_arg_def (phi, succ->dest_idx); tree def = gimple_phi_arg_def (phi, succ->dest_idx);
source_location locus = gimple_phi_arg_location_from_edge (phi, succ);
if (TREE_CODE (def) == SSA_NAME) if (TREE_CODE (def) == SSA_NAME)
{ {
@ -763,12 +765,13 @@ remove_forwarder_block_with_phi (basic_block bb)
if (def == old_arg) if (def == old_arg)
{ {
def = new_arg; def = new_arg;
locus = redirect_edge_var_map_location (vm);
break; break;
} }
} }
} }
add_phi_arg (phi, def, s); add_phi_arg (phi, def, s, locus);
} }
redirect_edge_var_map_clear (e); redirect_edge_var_map_clear (e);

View File

@ -455,6 +455,39 @@ gimple_phi_arg_edge (gimple gs, size_t i)
return EDGE_PRED (gimple_bb (gs), i); return EDGE_PRED (gimple_bb (gs), i);
} }
/* Return the source location of gimple argument I of phi node GS. */
static inline source_location
gimple_phi_arg_location (gimple gs, size_t i)
{
return gimple_phi_arg (gs, i)->locus;
}
/* Return the source location of the argument on edge E of phi node GS. */
static inline source_location
gimple_phi_arg_location_from_edge (gimple gs, edge e)
{
return gimple_phi_arg (gs, e->dest_idx)->locus;
}
/* Set the source location of gimple argument I of phi node GS to LOC. */
static inline void
gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc)
{
gimple_phi_arg (gs, i)->locus = loc;
}
/* Return TRUE if argument I of phi node GS has a location record. */
static inline bool
gimple_phi_arg_has_location (gimple gs, size_t i)
{
return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
}
/* Return the PHI nodes for basic block BB, or NULL if there are no /* Return the PHI nodes for basic block BB, or NULL if there are no
PHI nodes. */ PHI nodes. */
static inline gimple_seq static inline gimple_seq
@ -1196,6 +1229,14 @@ redirect_edge_var_map_result (edge_var_map *v)
return v->result; return v->result;
} }
/* Given an edge_var_map V, return the PHI arg location. */
static inline source_location
redirect_edge_var_map_location (edge_var_map *v)
{
return v->locus;
}
/* Return an SSA_NAME node for variable VAR defined in statement STMT /* Return an SSA_NAME node for variable VAR defined in statement STMT
in function cfun. */ in function cfun. */

View File

@ -579,7 +579,7 @@ extern void reserve_phi_args_for_new_edge (basic_block);
extern void add_phi_node_to_bb (gimple phi, basic_block bb); extern void add_phi_node_to_bb (gimple phi, basic_block bb);
extern gimple make_phi_node (tree var, int len); extern gimple make_phi_node (tree var, int len);
extern gimple create_phi_node (tree, basic_block); extern gimple create_phi_node (tree, basic_block);
extern void add_phi_arg (gimple, tree, edge); extern void add_phi_arg (gimple, tree, edge, source_location);
extern void remove_phi_args (edge); extern void remove_phi_args (edge);
extern void remove_phi_node (gimple_stmt_iterator *, bool); extern void remove_phi_node (gimple_stmt_iterator *, bool);
extern void remove_phi_nodes (basic_block); extern void remove_phi_nodes (basic_block);
@ -604,6 +604,7 @@ extern bool gimple_stmt_may_fallthru (gimple);
struct GTY(()) _edge_var_map { struct GTY(()) _edge_var_map {
tree result; /* PHI result. */ tree result; /* PHI result. */
tree def; /* PHI arg definition. */ tree def; /* PHI arg definition. */
source_location locus; /* PHI arg location. */
}; };
typedef struct _edge_var_map edge_var_map; typedef struct _edge_var_map edge_var_map;
@ -614,7 +615,7 @@ DEF_VEC_ALLOC_O(edge_var_map, heap);
typedef VEC(edge_var_map, heap) *edge_var_map_vector; typedef VEC(edge_var_map, heap) *edge_var_map_vector;
extern void init_tree_ssa (struct function *); extern void init_tree_ssa (struct function *);
extern void redirect_edge_var_map_add (edge, tree, tree); extern void redirect_edge_var_map_add (edge, tree, tree, source_location);
extern void redirect_edge_var_map_clear (edge); extern void redirect_edge_var_map_clear (edge);
extern void redirect_edge_var_map_dup (edge, edge); extern void redirect_edge_var_map_dup (edge, edge);
extern edge_var_map_vector redirect_edge_var_map_vector (edge); extern edge_var_map_vector redirect_edge_var_map_vector (edge);

View File

@ -1828,7 +1828,8 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
new_arg = force_gimple_operand (new_arg, &stmts, true, NULL); new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
gsi_insert_seq_on_edge_immediate (new_edge, stmts); gsi_insert_seq_on_edge_immediate (new_edge, stmts);
} }
add_phi_arg (new_phi, new_arg, new_edge); add_phi_arg (new_phi, new_arg, new_edge,
gimple_phi_arg_location_from_edge (phi, old_edge));
} }
} }
} }

View File

@ -1114,7 +1114,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
renamer will use the symbol on the LHS to get its renamer will use the symbol on the LHS to get its
reaching definition. */ reaching definition. */
FOR_EACH_EDGE (e, ei, bb->preds) FOR_EACH_EDGE (e, ei, bb->preds)
add_phi_arg (phi, var, e); add_phi_arg (phi, var, e, UNKNOWN_LOCATION);
} }
else else
{ {
@ -1320,9 +1320,12 @@ rewrite_add_phi_arguments (basic_block bb)
gsi_next (&gsi)) gsi_next (&gsi))
{ {
tree currdef; tree currdef;
gimple stmt;
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi))); currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
add_phi_arg (phi, currdef, e); stmt = SSA_NAME_DEF_STMT (currdef);
add_phi_arg (phi, currdef, e, gimple_location (stmt));
} }
} }
} }
@ -1857,7 +1860,7 @@ rewrite_update_phi_arguments (basic_block bb)
phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index); phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
for (i = 0; VEC_iterate (gimple, phis, i, phi); i++) for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
{ {
tree arg, lhs_sym; tree arg, lhs_sym, reaching_def = NULL;
use_operand_p arg_p; use_operand_p arg_p;
gcc_assert (rewrite_uses_p (phi)); gcc_assert (rewrite_uses_p (phi));
@ -1875,18 +1878,41 @@ rewrite_update_phi_arguments (basic_block bb)
/* When updating a PHI node for a recently introduced /* When updating a PHI node for a recently introduced
symbol we may find NULL arguments. That's why we symbol we may find NULL arguments. That's why we
take the symbol from the LHS of the PHI node. */ take the symbol from the LHS of the PHI node. */
SET_USE (arg_p, get_reaching_def (lhs_sym)); reaching_def = get_reaching_def (lhs_sym);
} }
else else
{ {
tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg); tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg);
if (symbol_marked_for_renaming (sym)) if (symbol_marked_for_renaming (sym))
SET_USE (arg_p, get_reaching_def (sym)); reaching_def = get_reaching_def (sym);
else if (is_old_name (arg)) else if (is_old_name (arg))
SET_USE (arg_p, get_reaching_def (arg)); reaching_def = get_reaching_def (arg);
} }
/* Update the argument if there is a reaching def. */
if (reaching_def)
{
gimple stmt;
source_location locus;
int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
SET_USE (arg_p, reaching_def);
stmt = SSA_NAME_DEF_STMT (reaching_def);
/* Single element PHI nodes behave like copies, so get the
location from the phi argument. */
if (gimple_code (stmt) == GIMPLE_PHI &&
gimple_phi_num_args (stmt) == 1)
locus = gimple_phi_arg_location (stmt, 0);
else
locus = gimple_location (stmt);
gimple_phi_arg_set_location (phi, arg_i, locus);
}
if (e->flags & EDGE_ABNORMAL) if (e->flags & EDGE_ABNORMAL)
SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1; SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
} }

View File

@ -97,17 +97,20 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
gsi_next (&si_new), gsi_next (&si_orig)) gsi_next (&si_new), gsi_next (&si_orig))
{ {
tree def; tree def;
source_location locus;
gimple phi_new = gsi_stmt (si_new); gimple phi_new = gsi_stmt (si_new);
gimple phi_orig = gsi_stmt (si_orig); gimple phi_orig = gsi_stmt (si_orig);
/* Add the first phi argument for the phi in NEW_LOOP (the one /* Add the first phi argument for the phi in NEW_LOOP (the one
associated with the entry of NEW_LOOP) */ associated with the entry of NEW_LOOP) */
def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e); def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
add_phi_arg (phi_new, def, new_loop_entry_e); locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e);
add_phi_arg (phi_new, def, new_loop_entry_e, locus);
/* Add the second phi argument for the phi in NEW_LOOP (the one /* Add the second phi argument for the phi in NEW_LOOP (the one
associated with the latch of NEW_LOOP) */ associated with the latch of NEW_LOOP) */
def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch); def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
if (TREE_CODE (def) == SSA_NAME) if (TREE_CODE (def) == SSA_NAME)
{ {
@ -122,7 +125,7 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
/* Could be an integer. */ /* Could be an integer. */
new_ssa_name = def; new_ssa_name = def;
add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop)); add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
} }
} }

View File

@ -36,6 +36,9 @@ along with GCC; see the file COPYING3. If not see
#include "ssaexpand.h" #include "ssaexpand.h"
DEF_VEC_I(source_location);
DEF_VEC_ALLOC_I(source_location,heap);
/* Used to hold all the components required to do SSA PHI elimination. /* Used to hold all the components required to do SSA PHI elimination.
The node and pred/succ list is a simple linear list of nodes and The node and pred/succ list is a simple linear list of nodes and
edges represented as pairs of nodes. edges represented as pairs of nodes.
@ -67,6 +70,9 @@ typedef struct _elim_graph {
/* The predecessor and successor edge list. */ /* The predecessor and successor edge list. */
VEC(int,heap) *edge_list; VEC(int,heap) *edge_list;
/* Source locus on each edge */
VEC(source_location,heap) *edge_locus;
/* Visited vector. */ /* Visited vector. */
sbitmap visited; sbitmap visited;
@ -82,6 +88,9 @@ typedef struct _elim_graph {
/* List of constant copies to emit. These are pushed on in pairs. */ /* List of constant copies to emit. These are pushed on in pairs. */
VEC(int,heap) *const_dests; VEC(int,heap) *const_dests;
VEC(tree,heap) *const_copies; VEC(tree,heap) *const_copies;
/* Source locations for any constant copies. */
VEC(source_location,heap) *copy_locus;
} *elim_graph; } *elim_graph;
@ -150,7 +159,7 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
/* Insert a copy instruction from partition SRC to DEST onto edge E. */ /* Insert a copy instruction from partition SRC to DEST onto edge E. */
static void static void
insert_partition_copy_on_edge (edge e, int dest, int src) insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
{ {
rtx seq; rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
@ -167,6 +176,9 @@ insert_partition_copy_on_edge (edge e, int dest, int src)
gcc_assert (SA.partition_to_pseudo[src]); gcc_assert (SA.partition_to_pseudo[src]);
set_location_for_edge (e); set_location_for_edge (e);
/* If a locus is provided, override the default. */
if (locus)
set_curr_insn_source_location (locus);
seq = emit_partition_copy (SA.partition_to_pseudo[dest], seq = emit_partition_copy (SA.partition_to_pseudo[dest],
SA.partition_to_pseudo[src], SA.partition_to_pseudo[src],
@ -180,7 +192,7 @@ insert_partition_copy_on_edge (edge e, int dest, int src)
onto edge E. */ onto edge E. */
static void static void
insert_value_copy_on_edge (edge e, int dest, tree src) insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
{ {
rtx seq, x; rtx seq, x;
enum machine_mode mode; enum machine_mode mode;
@ -197,6 +209,9 @@ insert_value_copy_on_edge (edge e, int dest, tree src)
gcc_assert (SA.partition_to_pseudo[dest]); gcc_assert (SA.partition_to_pseudo[dest]);
set_location_for_edge (e); set_location_for_edge (e);
/* If a locus is provided, override the default. */
if (locus)
set_curr_insn_source_location (locus);
start_sequence (); start_sequence ();
mode = GET_MODE (SA.partition_to_pseudo[dest]); mode = GET_MODE (SA.partition_to_pseudo[dest]);
@ -219,7 +234,8 @@ insert_value_copy_on_edge (edge e, int dest, tree src)
onto edge E. */ onto edge E. */
static void static void
insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp) insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
source_location locus)
{ {
rtx seq; rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
@ -233,7 +249,11 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
} }
gcc_assert (SA.partition_to_pseudo[dest]); gcc_assert (SA.partition_to_pseudo[dest]);
set_location_for_edge (e); set_location_for_edge (e);
/* If a locus is provided, override the default. */
if (locus)
set_curr_insn_source_location (locus);
seq = emit_partition_copy (SA.partition_to_pseudo[dest], seq = emit_partition_copy (SA.partition_to_pseudo[dest],
src, src,
@ -246,7 +266,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
onto edge E. */ onto edge E. */
static void static void
insert_part_to_rtx_on_edge (edge e, rtx dest, int src) insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
{ {
rtx seq; rtx seq;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
@ -260,7 +280,11 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src)
} }
gcc_assert (SA.partition_to_pseudo[src]); gcc_assert (SA.partition_to_pseudo[src]);
set_location_for_edge (e); set_location_for_edge (e);
/* If a locus is provided, override the default. */
if (locus)
set_curr_insn_source_location (locus);
seq = emit_partition_copy (dest, seq = emit_partition_copy (dest,
SA.partition_to_pseudo[src], SA.partition_to_pseudo[src],
@ -282,7 +306,9 @@ new_elim_graph (int size)
g->nodes = VEC_alloc (int, heap, 30); g->nodes = VEC_alloc (int, heap, 30);
g->const_dests = VEC_alloc (int, heap, 20); g->const_dests = VEC_alloc (int, heap, 20);
g->const_copies = VEC_alloc (tree, heap, 20); g->const_copies = VEC_alloc (tree, heap, 20);
g->copy_locus = VEC_alloc (source_location, heap, 10);
g->edge_list = VEC_alloc (int, heap, 20); g->edge_list = VEC_alloc (int, heap, 20);
g->edge_locus = VEC_alloc (source_location, heap, 10);
g->stack = VEC_alloc (int, heap, 30); g->stack = VEC_alloc (int, heap, 30);
g->visited = sbitmap_alloc (size); g->visited = sbitmap_alloc (size);
@ -298,6 +324,7 @@ clear_elim_graph (elim_graph g)
{ {
VEC_truncate (int, g->nodes, 0); VEC_truncate (int, g->nodes, 0);
VEC_truncate (int, g->edge_list, 0); VEC_truncate (int, g->edge_list, 0);
VEC_truncate (source_location, g->edge_locus, 0);
} }
@ -312,6 +339,9 @@ delete_elim_graph (elim_graph g)
VEC_free (tree, heap, g->const_copies); VEC_free (tree, heap, g->const_copies);
VEC_free (int, heap, g->const_dests); VEC_free (int, heap, g->const_dests);
VEC_free (int, heap, g->nodes); VEC_free (int, heap, g->nodes);
VEC_free (source_location, heap, g->copy_locus);
VEC_free (source_location, heap, g->edge_locus);
free (g); free (g);
} }
@ -343,10 +373,11 @@ elim_graph_add_node (elim_graph g, int node)
/* Add the edge PRED->SUCC to graph G. */ /* Add the edge PRED->SUCC to graph G. */
static inline void static inline void
elim_graph_add_edge (elim_graph g, int pred, int succ) elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus)
{ {
VEC_safe_push (int, heap, g->edge_list, pred); VEC_safe_push (int, heap, g->edge_list, pred);
VEC_safe_push (int, heap, g->edge_list, succ); VEC_safe_push (int, heap, g->edge_list, succ);
VEC_safe_push (source_location, heap, g->edge_locus, locus);
} }
@ -354,7 +385,7 @@ elim_graph_add_edge (elim_graph g, int pred, int succ)
return the successor node. -1 is returned if there is no such edge. */ return the successor node. -1 is returned if there is no such edge. */
static inline int static inline int
elim_graph_remove_succ_edge (elim_graph g, int node) elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus)
{ {
int y; int y;
unsigned x; unsigned x;
@ -364,8 +395,11 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
VEC_replace (int, g->edge_list, x, -1); VEC_replace (int, g->edge_list, x, -1);
y = VEC_index (int, g->edge_list, x + 1); y = VEC_index (int, g->edge_list, x + 1);
VEC_replace (int, g->edge_list, x + 1, -1); VEC_replace (int, g->edge_list, x + 1, -1);
*locus = VEC_index (source_location, g->edge_locus, x / 2);
VEC_replace (source_location, g->edge_locus, x / 2, UNKNOWN_LOCATION);
return y; return y;
} }
*locus = UNKNOWN_LOCATION;
return -1; return -1;
} }
@ -374,7 +408,7 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
edge list. VAR will hold the partition number found. CODE is the edge list. VAR will hold the partition number found. CODE is the
code fragment executed for every node found. */ code fragment executed for every node found. */
#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE) \ #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE) \
do { \ do { \
unsigned x_; \ unsigned x_; \
int y_; \ int y_; \
@ -384,6 +418,7 @@ do { \
if (y_ != (NODE)) \ if (y_ != (NODE)) \
continue; \ continue; \
(VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \
(LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
CODE; \ CODE; \
} \ } \
} while (0) } while (0)
@ -393,7 +428,7 @@ do { \
GRAPH. VAR will hold the partition number found. CODE is the GRAPH. VAR will hold the partition number found. CODE is the
code fragment executed for every node found. */ code fragment executed for every node found. */
#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE) \ #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE) \
do { \ do { \
unsigned x_; \ unsigned x_; \
int y_; \ int y_; \
@ -403,6 +438,7 @@ do { \
if (y_ != (NODE)) \ if (y_ != (NODE)) \
continue; \ continue; \
(VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \
(LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
CODE; \ CODE; \
} \ } \
} while (0) } while (0)
@ -432,6 +468,7 @@ eliminate_build (elim_graph g)
for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
source_location locus;
p0 = var_to_partition (g->map, gimple_phi_result (phi)); p0 = var_to_partition (g->map, gimple_phi_result (phi));
/* Ignore results which are not in partitions. */ /* Ignore results which are not in partitions. */
@ -439,6 +476,7 @@ eliminate_build (elim_graph g)
continue; continue;
Ti = PHI_ARG_DEF (phi, g->e->dest_idx); Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
locus = gimple_phi_arg_location_from_edge (phi, g->e);
/* If this argument is a constant, or a SSA_NAME which is being /* If this argument is a constant, or a SSA_NAME which is being
left in SSA form, just queue a copy to be emitted on this left in SSA form, just queue a copy to be emitted on this
@ -451,6 +489,7 @@ eliminate_build (elim_graph g)
on this edge. */ on this edge. */
VEC_safe_push (int, heap, g->const_dests, p0); VEC_safe_push (int, heap, g->const_dests, p0);
VEC_safe_push (tree, heap, g->const_copies, Ti); VEC_safe_push (tree, heap, g->const_copies, Ti);
VEC_safe_push (source_location, heap, g->copy_locus, locus);
} }
else else
{ {
@ -459,7 +498,7 @@ eliminate_build (elim_graph g)
{ {
eliminate_name (g, p0); eliminate_name (g, p0);
eliminate_name (g, pi); eliminate_name (g, pi);
elim_graph_add_edge (g, p0, pi); elim_graph_add_edge (g, p0, pi, locus);
} }
} }
} }
@ -472,8 +511,10 @@ static void
elim_forward (elim_graph g, int T) elim_forward (elim_graph g, int T)
{ {
int S; int S;
source_location locus;
SET_BIT (g->visited, T); SET_BIT (g->visited, T);
FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
{ {
if (!TEST_BIT (g->visited, S)) if (!TEST_BIT (g->visited, S))
elim_forward (g, S); elim_forward (g, S);
@ -488,7 +529,9 @@ static int
elim_unvisited_predecessor (elim_graph g, int T) elim_unvisited_predecessor (elim_graph g, int T)
{ {
int P; int P;
FOR_EACH_ELIM_GRAPH_PRED (g, T, P, source_location locus;
FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
{ {
if (!TEST_BIT (g->visited, P)) if (!TEST_BIT (g->visited, P))
return 1; return 1;
@ -502,13 +545,15 @@ static void
elim_backward (elim_graph g, int T) elim_backward (elim_graph g, int T)
{ {
int P; int P;
source_location locus;
SET_BIT (g->visited, T); SET_BIT (g->visited, T);
FOR_EACH_ELIM_GRAPH_PRED (g, T, P, FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
{ {
if (!TEST_BIT (g->visited, P)) if (!TEST_BIT (g->visited, P))
{ {
elim_backward (g, P); elim_backward (g, P);
insert_partition_copy_on_edge (g->e, P, T); insert_partition_copy_on_edge (g->e, P, T, locus);
} }
}); });
} }
@ -537,6 +582,7 @@ static void
elim_create (elim_graph g, int T) elim_create (elim_graph g, int T)
{ {
int P, S; int P, S;
source_location locus;
if (elim_unvisited_predecessor (g, T)) if (elim_unvisited_predecessor (g, T))
{ {
@ -544,23 +590,23 @@ elim_create (elim_graph g, int T)
rtx U = get_temp_reg (var); rtx U = get_temp_reg (var);
int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var)); int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
insert_part_to_rtx_on_edge (g->e, U, T); insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
FOR_EACH_ELIM_GRAPH_PRED (g, T, P, FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
{ {
if (!TEST_BIT (g->visited, P)) if (!TEST_BIT (g->visited, P))
{ {
elim_backward (g, P); elim_backward (g, P);
insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp); insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
} }
}); });
} }
else else
{ {
S = elim_graph_remove_succ_edge (g, T); S = elim_graph_remove_succ_edge (g, T, &locus);
if (S != -1) if (S != -1)
{ {
SET_BIT (g->visited, T); SET_BIT (g->visited, T);
insert_partition_copy_on_edge (g->e, T, S); insert_partition_copy_on_edge (g->e, T, S, locus);
} }
} }
} }
@ -574,6 +620,7 @@ eliminate_phi (edge e, elim_graph g)
int x; int x;
gcc_assert (VEC_length (tree, g->const_copies) == 0); gcc_assert (VEC_length (tree, g->const_copies) == 0);
gcc_assert (VEC_length (source_location, g->copy_locus) == 0);
/* Abnormal edges already have everything coalesced. */ /* Abnormal edges already have everything coalesced. */
if (e->flags & EDGE_ABNORMAL) if (e->flags & EDGE_ABNORMAL)
@ -610,9 +657,12 @@ eliminate_phi (edge e, elim_graph g)
{ {
int dest; int dest;
tree src; tree src;
source_location locus;
src = VEC_pop (tree, g->const_copies); src = VEC_pop (tree, g->const_copies);
dest = VEC_pop (int, g->const_dests); dest = VEC_pop (int, g->const_dests);
insert_value_copy_on_edge (e, dest, src); locus = VEC_pop (source_location, g->copy_locus);
insert_value_copy_on_edge (e, dest, src, locus);
} }
} }
@ -991,6 +1041,11 @@ insert_backedge_copies (void)
name = make_ssa_name (result_var, stmt); name = make_ssa_name (result_var, stmt);
gimple_assign_set_lhs (stmt, name); gimple_assign_set_lhs (stmt, name);
/* copy location if present. */
if (gimple_phi_arg_has_location (phi, i))
gimple_set_location (stmt,
gimple_phi_arg_location (phi, i));
/* Insert the new statement into the block and update /* Insert the new statement into the block and update
the PHI node. */ the PHI node. */
if (last && stmt_ends_bb_p (last)) if (last && stmt_ends_bb_p (last))

View File

@ -747,6 +747,7 @@ create_phi_for_local_result (void **slot, void *data)
gimple new_phi; gimple new_phi;
basic_block store_bb; basic_block store_bb;
tree local_res; tree local_res;
source_location locus;
/* STORE_BB is the block where the phi /* STORE_BB is the block where the phi
should be stored. It is the destination of the loop exit. should be stored. It is the destination of the loop exit.
@ -765,11 +766,12 @@ create_phi_for_local_result (void **slot, void *data)
local_res local_res
= make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)), = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
NULL); NULL);
locus = gimple_location (reduc->reduc_stmt);
new_phi = create_phi_node (local_res, store_bb); new_phi = create_phi_node (local_res, store_bb);
SSA_NAME_DEF_STMT (local_res) = new_phi; SSA_NAME_DEF_STMT (local_res) = new_phi;
add_phi_arg (new_phi, reduc->init, e); add_phi_arg (new_phi, reduc->init, e, locus);
add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt), add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
FALLTHRU_EDGE (loop->latch)); FALLTHRU_EDGE (loop->latch), locus);
reduc->new_phi = new_phi; reduc->new_phi = new_phi;
return 1; return 1;
@ -1219,7 +1221,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
nphi = create_phi_node (res, orig_header); nphi = create_phi_node (res, orig_header);
SSA_NAME_DEF_STMT (res) = nphi; SSA_NAME_DEF_STMT (res) = nphi;
add_phi_arg (nphi, t, hpred); add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
if (res == control) if (res == control)
{ {
@ -1370,14 +1372,20 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU); end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
source_location locus;
tree def;
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
res = PHI_RESULT (phi); res = PHI_RESULT (phi);
stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit)); stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
add_phi_arg (phi,
PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)), def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop));
guard); locus = gimple_phi_arg_location_from_edge (stmt,
add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)), loop_preheader_edge (loop));
end); add_phi_arg (phi, def, guard, locus);
def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop));
locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop));
add_phi_arg (phi, def, end, locus);
} }
e = redirect_edge_and_branch (exit, nexit->dest); e = redirect_edge_and_branch (exit, nexit->dest);
PENDING_STMT (e) = NULL; PENDING_STMT (e) = NULL;

View File

@ -231,6 +231,8 @@ make_phi_node (tree var, int len)
for (i = 0; i < capacity; i++) for (i = 0; i < capacity; i++)
{ {
use_operand_p imm; use_operand_p imm;
gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
imm = gimple_phi_arg_imm_use_ptr (phi, i); imm = gimple_phi_arg_imm_use_ptr (phi, i);
imm->use = gimple_phi_arg_def_ptr (phi, i); imm->use = gimple_phi_arg_def_ptr (phi, i);
imm->prev = NULL; imm->prev = NULL;
@ -299,6 +301,8 @@ resize_phi_node (gimple *phi, size_t len)
for (i = gimple_phi_num_args (new_phi); i < len; i++) for (i = gimple_phi_num_args (new_phi); i < len; i++)
{ {
use_operand_p imm; use_operand_p imm;
gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
imm = gimple_phi_arg_imm_use_ptr (new_phi, i); imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
imm->use = gimple_phi_arg_def_ptr (new_phi, i); imm->use = gimple_phi_arg_def_ptr (new_phi, i);
imm->prev = NULL; imm->prev = NULL;
@ -384,7 +388,7 @@ create_phi_node (tree var, basic_block bb)
PHI points to the reallocated phi node when we return. */ PHI points to the reallocated phi node when we return. */
void void
add_phi_arg (gimple phi, tree def, edge e) add_phi_arg (gimple phi, tree def, edge e, source_location locus)
{ {
basic_block bb = e->dest; basic_block bb = e->dest;
@ -407,6 +411,7 @@ add_phi_arg (gimple phi, tree def, edge e)
} }
SET_PHI_ARG_DEF (phi, e->dest_idx, def); SET_PHI_ARG_DEF (phi, e->dest_idx, def);
gimple_phi_arg_set_location (phi, e->dest_idx, locus);
} }
@ -435,6 +440,9 @@ remove_phi_arg_num (gimple phi, int i)
/* Set use on new node, and link into last element's place. */ /* Set use on new node, and link into last element's place. */
*(new_p->use) = *(old_p->use); *(new_p->use) = *(old_p->use);
relink_imm_use (new_p, old_p); relink_imm_use (new_p, old_p);
/* Move the location as well. */
gimple_phi_arg_set_location (phi, i,
gimple_phi_arg_location (phi, num_elem - 1));
} }
/* Shrink the vector and return. Note that we do not have to clear /* Shrink the vector and return. Note that we do not have to clear

View File

@ -1512,8 +1512,8 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
phi = create_phi_node (var, loop->header); phi = create_phi_node (var, loop->header);
SSA_NAME_DEF_STMT (var) = phi; SSA_NAME_DEF_STMT (var) = phi;
add_phi_arg (phi, init, entry); add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
add_phi_arg (phi, next, latch); add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
} }
} }
@ -1576,8 +1576,8 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
next = VEC_index (tree, *vars, 1); next = VEC_index (tree, *vars, 1);
phi = create_phi_node (var, loop->header); phi = create_phi_node (var, loop->header);
SSA_NAME_DEF_STMT (var) = phi; SSA_NAME_DEF_STMT (var) = phi;
add_phi_arg (phi, init, entry); add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
add_phi_arg (phi, next, latch); add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
} }
else else
{ {

View File

@ -951,6 +951,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
tree op; tree op;
source_location locus;
/* Dead PHI do not imply control dependency. */ /* Dead PHI do not imply control dependency. */
if (!gimple_plf (phi, STMT_NECESSARY) if (!gimple_plf (phi, STMT_NECESSARY)
@ -975,10 +976,16 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
continue; continue;
} }
if (!e2) if (!e2)
op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0); {
op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
locus = gimple_phi_arg_location (phi, e->dest_idx == 0 ? 1 : 0);
}
else else
op = gimple_phi_arg_def (phi, e2->dest_idx); {
add_phi_arg (phi, op, e); op = gimple_phi_arg_def (phi, e2->dest_idx);
locus = gimple_phi_arg_location (phi, e2->dest_idx);
}
add_phi_arg (phi, op, e, locus);
gcc_assert (e2 || degenerate_phi_p (phi)); gcc_assert (e2 || degenerate_phi_p (phi));
gsi_next (&gsi); gsi_next (&gsi);
} }

View File

@ -125,8 +125,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
stmt = create_phi_node (vb, loop->header); stmt = create_phi_node (vb, loop->header);
SSA_NAME_DEF_STMT (vb) = stmt; SSA_NAME_DEF_STMT (vb) = stmt;
add_phi_arg (stmt, initial, loop_preheader_edge (loop)); add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION);
add_phi_arg (stmt, va, loop_latch_edge (loop)); add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
} }
/* Add exit phis for the USE on EXIT. */ /* Add exit phis for the USE on EXIT. */
@ -156,7 +156,7 @@ add_exit_phis_edge (basic_block exit, tree use)
create_new_def_for (gimple_phi_result (phi), phi, create_new_def_for (gimple_phi_result (phi), phi,
gimple_phi_result_ptr (phi)); gimple_phi_result_ptr (phi));
FOR_EACH_EDGE (e, ei, exit->preds) FOR_EACH_EDGE (e, ei, exit->preds)
add_phi_arg (phi, use, e); add_phi_arg (phi, use, e, UNKNOWN_LOCATION);
} }
/* Add exit phis for VAR that is used in LIVEIN. /* Add exit phis for VAR that is used in LIVEIN.
@ -476,11 +476,13 @@ split_loop_exit_edge (edge exit)
tree new_name, name; tree new_name, name;
use_operand_p op_p; use_operand_p op_p;
gimple_stmt_iterator psi; gimple_stmt_iterator psi;
source_location locus;
for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi)) for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi))
{ {
phi = gsi_stmt (psi); phi = gsi_stmt (psi);
op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb)); op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
locus = gimple_phi_arg_location_from_edge (phi, single_succ_edge (bb));
name = USE_FROM_PTR (op_p); name = USE_FROM_PTR (op_p);
@ -494,7 +496,7 @@ split_loop_exit_edge (edge exit)
new_name = duplicate_ssa_name (name, NULL); new_name = duplicate_ssa_name (name, NULL);
new_phi = create_phi_node (new_name, bb); new_phi = create_phi_node (new_name, bb);
SSA_NAME_DEF_STMT (new_name) = new_phi; SSA_NAME_DEF_STMT (new_name) = new_phi;
add_phi_arg (new_phi, name, exit); add_phi_arg (new_phi, name, exit, locus);
SET_USE (op_p, new_name); SET_USE (op_p, new_name);
} }
@ -1014,8 +1016,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
phi_rest = create_phi_node (new_init, rest); phi_rest = create_phi_node (new_init, rest);
SSA_NAME_DEF_STMT (new_init) = phi_rest; SSA_NAME_DEF_STMT (new_init) = phi_rest;
add_phi_arg (phi_rest, init, precond_edge); add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION);
add_phi_arg (phi_rest, next, new_exit); add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION);
SET_USE (op, new_init); SET_USE (op, new_init);
} }

View File

@ -513,6 +513,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var))) if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
{ {
source_location locus_0, locus_1;
new_var2 = create_tmp_var (TREE_TYPE (result), NULL); new_var2 = create_tmp_var (TREE_TYPE (result), NULL);
add_referenced_var (new_var2); add_referenced_var (new_var2);
new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2, new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
@ -521,6 +523,13 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
gimple_assign_set_lhs (new_stmt, new_var2); gimple_assign_set_lhs (new_stmt, new_var2);
gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
new_var = new_var2; new_var = new_var2;
/* Set the locus to the first argument, unless is doesn't have one. */
locus_0 = gimple_phi_arg_location (phi, 0);
locus_1 = gimple_phi_arg_location (phi, 1);
if (locus_0 == UNKNOWN_LOCATION)
locus_0 = locus_1;
gimple_set_location (new_stmt, locus_0);
} }
replace_phi_edge_with_variable (cond_bb, e1, phi, new_var); replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
@ -1177,6 +1186,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
tree lhs, rhs, name; tree lhs, rhs, name;
gimple newphi, new_stmt; gimple newphi, new_stmt;
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
source_location locus;
enum tree_code code; enum tree_code code;
/* Check if middle_bb contains of only one store. */ /* Check if middle_bb contains of only one store. */
@ -1184,6 +1194,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
|| gimple_code (assign) != GIMPLE_ASSIGN) || gimple_code (assign) != GIMPLE_ASSIGN)
return false; return false;
locus = gimple_location (assign);
lhs = gimple_assign_lhs (assign); lhs = gimple_assign_lhs (assign);
rhs = gimple_assign_rhs1 (assign); rhs = gimple_assign_rhs1 (assign);
if (!INDIRECT_REF_P (lhs)) if (!INDIRECT_REF_P (lhs))
@ -1224,6 +1235,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
new_stmt = gimple_build_assign (condstoretemp, lhs); new_stmt = gimple_build_assign (condstoretemp, lhs);
name = make_ssa_name (condstoretemp, new_stmt); name = make_ssa_name (condstoretemp, new_stmt);
gimple_assign_set_lhs (new_stmt, name); gimple_assign_set_lhs (new_stmt, name);
gimple_set_location (new_stmt, locus);
mark_symbols_for_renaming (new_stmt); mark_symbols_for_renaming (new_stmt);
gsi_insert_on_edge (e1, new_stmt); gsi_insert_on_edge (e1, new_stmt);
@ -1231,8 +1243,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
holding the old RHS, and the other holding the temporary holding the old RHS, and the other holding the temporary
where we stored the old memory contents. */ where we stored the old memory contents. */
newphi = create_phi_node (condstoretemp, join_bb); newphi = create_phi_node (condstoretemp, join_bb);
add_phi_arg (newphi, rhs, e0); add_phi_arg (newphi, rhs, e0, locus);
add_phi_arg (newphi, name, e1); add_phi_arg (newphi, name, e1, locus);
lhs = unshare_expr (lhs); lhs = unshare_expr (lhs);
new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi)); new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));

View File

@ -159,14 +159,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
{ {
tree old_arg, new_var; tree old_arg, new_var;
gimple tmp; gimple tmp;
source_location locus;
old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e); old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
locus = gimple_phi_arg_location_from_edge (phi, e);
while (TREE_CODE (old_arg) == SSA_NAME while (TREE_CODE (old_arg) == SSA_NAME
&& (SSA_NAME_VERSION (old_arg) >= n && (SSA_NAME_VERSION (old_arg) >= n
|| phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE)) || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
{ {
gimple def_stmt = SSA_NAME_DEF_STMT (old_arg); gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
old_arg = gimple_assign_rhs1 (def_stmt); old_arg = gimple_assign_rhs1 (def_stmt);
locus = gimple_location (def_stmt);
} }
if (TREE_CODE (old_arg) == SSA_NAME) if (TREE_CODE (old_arg) == SSA_NAME)
@ -196,6 +199,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
add_referenced_var (new_var); add_referenced_var (new_var);
new_var = make_ssa_name (new_var, tmp); new_var = make_ssa_name (new_var, tmp);
gimple_assign_set_lhs (tmp, new_var); gimple_assign_set_lhs (tmp, new_var);
gimple_set_location (tmp, locus);
gsi_insert_on_edge (e, tmp); gsi_insert_on_edge (e, tmp);
update_stmt (tmp); update_stmt (tmp);
@ -209,7 +213,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
} }
} }
add_phi_arg (new_phi, new_var, e); add_phi_arg (new_phi, new_var, e, locus);
} }
update_stmt (new_phi); update_stmt (new_phi);

View File

@ -3328,9 +3328,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
gcc_assert (get_expr_type (ae) == type gcc_assert (get_expr_type (ae) == type
|| useless_type_conversion_p (type, get_expr_type (ae))); || useless_type_conversion_p (type, get_expr_type (ae)));
if (ae->kind == CONSTANT) if (ae->kind == CONSTANT)
add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred); add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION);
else else
add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred); add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
UNKNOWN_LOCATION);
} }
newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi)); newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));

View File

@ -325,9 +325,11 @@ create_edge_and_update_destination_phis (struct redirection_data *rd)
for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
source_location locus;
int indx = rd->outgoing_edge->dest_idx; int indx = rd->outgoing_edge->dest_idx;
add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e);
locus = gimple_phi_arg_location (phi, indx);
add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e, locus);
} }
} }

View File

@ -53,7 +53,7 @@ static struct pointer_map_t *edge_var_maps;
/* Add a mapping with PHI RESULT and PHI DEF associated with edge E. */ /* Add a mapping with PHI RESULT and PHI DEF associated with edge E. */
void void
redirect_edge_var_map_add (edge e, tree result, tree def) redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
{ {
void **slot; void **slot;
edge_var_map_vector old_head, head; edge_var_map_vector old_head, head;
@ -71,6 +71,7 @@ redirect_edge_var_map_add (edge e, tree result, tree def)
} }
new_node.def = def; new_node.def = def;
new_node.result = result; new_node.result = result;
new_node.locus = locus;
VEC_safe_push (edge_var_map, heap, head, &new_node); VEC_safe_push (edge_var_map, heap, head, &new_node);
if (old_head != head) if (old_head != head)
@ -193,14 +194,16 @@ ssa_redirect_edge (edge e, basic_block dest)
for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi)) for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
{ {
tree def; tree def;
source_location locus ;
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
def = gimple_phi_arg_def (phi, e->dest_idx); def = gimple_phi_arg_def (phi, e->dest_idx);
locus = gimple_phi_arg_location (phi, e->dest_idx);
if (def == NULL_TREE) if (def == NULL_TREE)
continue; continue;
redirect_edge_var_map_add (e, gimple_phi_result (phi), def); redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
} }
e = redirect_edge_succ_nodup (e, dest); e = redirect_edge_succ_nodup (e, dest);
@ -233,7 +236,7 @@ flush_pending_stmts (edge e)
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
def = redirect_edge_var_map_def (vm); def = redirect_edge_var_map_def (vm);
add_phi_arg (phi, def, e); add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
} }
redirect_edge_var_map_clear (e); redirect_edge_var_map_clear (e);

View File

@ -638,8 +638,8 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
!gsi_end_p (gsi); gsi_next (&gsi), i++) !gsi_end_p (gsi); gsi_next (&gsi), i++)
{ {
gimple phi = gsi_stmt (gsi); gimple phi = gsi_stmt (gsi);
add_phi_arg (phi, info.target_inbound_names[i], e1f); add_phi_arg (phi, info.target_inbound_names[i], e1f, UNKNOWN_LOCATION);
add_phi_arg (phi, info.target_outbound_names[i], e2f); add_phi_arg (phi, info.target_outbound_names[i], e2f, UNKNOWN_LOCATION);
} }
} }

View File

@ -548,7 +548,7 @@ add_successor_phi_arg (edge e, tree var, tree phi_arg)
break; break;
gcc_assert (!gsi_end_p (gsi)); gcc_assert (!gsi_end_p (gsi));
add_phi_arg (gsi_stmt (gsi), phi_arg, e); add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION);
} }
/* Creates a GIMPLE statement which computes the operation specified by /* Creates a GIMPLE statement which computes the operation specified by
@ -773,7 +773,7 @@ eliminate_tail_call (struct tailcall *t)
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi))); gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
add_phi_arg (phi, arg, e); add_phi_arg (phi, arg, e, gimple_location (stmt));
gsi_next (&gsi); gsi_next (&gsi);
} }
@ -870,7 +870,8 @@ create_tailcall_accumulator (const char *label, basic_block bb, tree init)
add_referenced_var (tmp); add_referenced_var (tmp);
phi = create_phi_node (tmp, bb); phi = create_phi_node (tmp, bb);
/* RET_TYPE can be a float when -ffast-maths is enabled. */ /* RET_TYPE can be a float when -ffast-maths is enabled. */
add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb)); add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb),
UNKNOWN_LOCATION);
return PHI_RESULT (phi); return PHI_RESULT (phi);
} }
@ -933,7 +934,8 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
set_default_def (param, new_name); set_default_def (param, new_name);
phi = create_phi_node (name, first); phi = create_phi_node (name, first);
SSA_NAME_DEF_STMT (name) = phi; SSA_NAME_DEF_STMT (name) = phi;
add_phi_arg (phi, new_name, single_pred_edge (first)); add_phi_arg (phi, new_name, single_pred_edge (first),
EXPR_LOCATION (param));
} }
phis_constructed = true; phis_constructed = true;
} }

View File

@ -3049,7 +3049,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
msq = make_ssa_name (vec_dest, NULL); msq = make_ssa_name (vec_dest, NULL);
phi_stmt = create_phi_node (msq, containing_loop->header); phi_stmt = create_phi_node (msq, containing_loop->header);
SSA_NAME_DEF_STMT (msq) = phi_stmt; SSA_NAME_DEF_STMT (msq) = phi_stmt;
add_phi_arg (phi_stmt, msq_init, pe); add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION);
return msq; return msq;
} }

View File

@ -169,15 +169,18 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
!gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig); !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig);
gsi_next (&gsi_new), gsi_next (&gsi_orig)) gsi_next (&gsi_new), gsi_next (&gsi_orig))
{ {
source_location locus;
phi_new = gsi_stmt (gsi_new); phi_new = gsi_stmt (gsi_new);
phi_orig = gsi_stmt (gsi_orig); phi_orig = gsi_stmt (gsi_orig);
/* step 1. */ /* step 1. */
def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e); def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
add_phi_arg (phi_new, def, new_loop_entry_e); locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e);
add_phi_arg (phi_new, def, new_loop_entry_e, locus);
/* step 2. */ /* step 2. */
def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch); def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
if (TREE_CODE (def) != SSA_NAME) if (TREE_CODE (def) != SSA_NAME)
continue; continue;
@ -190,7 +193,7 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
} }
/* An ordinary ssa name defined in the loop. */ /* An ordinary ssa name defined in the loop. */
add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop)); add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
/* step 3 (case 1). */ /* step 3 (case 1). */
if (!after) if (!after)
@ -383,6 +386,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
!gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update); !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update);
gsi_next (&gsi_orig), gsi_next (&gsi_update)) gsi_next (&gsi_orig), gsi_next (&gsi_update))
{ {
source_location loop_locus, guard_locus;;
orig_phi = gsi_stmt (gsi_orig); orig_phi = gsi_stmt (gsi_orig);
update_phi = gsi_stmt (gsi_update); update_phi = gsi_stmt (gsi_update);
@ -395,10 +399,16 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
/* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge /* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
of LOOP. Set the two phi args in NEW_PHI for these edges: */ of LOOP. Set the two phi args in NEW_PHI for these edges: */
loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0)); loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0));
loop_locus = gimple_phi_arg_location_from_edge (orig_phi,
EDGE_SUCC (loop->latch,
0));
guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop)); guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop));
guard_locus
= gimple_phi_arg_location_from_edge (orig_phi,
loop_preheader_edge (loop));
add_phi_arg (new_phi, loop_arg, new_exit_e); add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus);
add_phi_arg (new_phi, guard_arg, guard_edge); add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus);
/* 1.3. Update phi in successor block. */ /* 1.3. Update phi in successor block. */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
@ -417,7 +427,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
*new_exit_bb); *new_exit_bb);
/* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */ /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */
add_phi_arg (new_phi, loop_arg, single_exit (loop)); add_phi_arg (new_phi, loop_arg, single_exit (loop), loop_locus);
/* 2.3. Update phi in successor of NEW_EXIT_BB: */ /* 2.3. Update phi in successor of NEW_EXIT_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@ -545,8 +555,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
if (new_name2) if (new_name2)
guard_arg = new_name2; guard_arg = new_name2;
add_phi_arg (new_phi, loop_arg, new_exit_e); add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION);
add_phi_arg (new_phi, guard_arg, guard_edge); add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION);
/* 1.3. Update phi in successor block. */ /* 1.3. Update phi in successor block. */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def); gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
@ -561,7 +571,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
*new_exit_bb); *new_exit_bb);
/* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */ /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop. */
add_phi_arg (new_phi, loop_arg, single_exit (loop)); add_phi_arg (new_phi, loop_arg, single_exit (loop), UNKNOWN_LOCATION);
/* 2.3. Update phi in successor of NEW_EXIT_BB: */ /* 2.3. Update phi in successor of NEW_EXIT_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg); gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@ -596,7 +606,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
/* 3.3. GUARD_BB has one incoming edge: */ /* 3.3. GUARD_BB has one incoming edge: */
gcc_assert (EDGE_COUNT (guard_edge->src->preds) == 1); gcc_assert (EDGE_COUNT (guard_edge->src->preds) == 1);
add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0)); add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0),
UNKNOWN_LOCATION);
/* 3.4. Update phi in successor of GUARD_BB: */ /* 3.4. Update phi in successor of GUARD_BB: */
gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge) gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
@ -720,13 +731,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
if (phi_arg) if (phi_arg)
{ {
edge new_loop_exit_edge; edge new_loop_exit_edge;
source_location locus;
locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop));
if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch) if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1); new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
else else
new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0); new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
add_phi_arg (phi, phi_arg, new_loop_exit_edge); add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus);
} }
} }
@ -764,7 +777,8 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
phi = gsi_stmt (gsi); phi = gsi_stmt (gsi);
phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e); phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
if (phi_arg) if (phi_arg)
add_phi_arg (phi, phi_arg, new_exit_e); add_phi_arg (phi, phi_arg, new_exit_e,
gimple_phi_arg_location_from_edge (phi, entry_e));
} }
redirect_edge_and_branch_force (entry_e, new_loop->header); redirect_edge_and_branch_force (entry_e, new_loop->header);
@ -954,8 +968,9 @@ set_prologue_iterations (basic_block bb_before_first_loop,
gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
newphi = create_phi_node (var, bb_before_first_loop); newphi = create_phi_node (var, bb_before_first_loop);
add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru); add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru,
add_phi_arg (newphi, first_niters, e_false); UNKNOWN_LOCATION);
add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION);
first_niters = PHI_RESULT (newphi); first_niters = PHI_RESULT (newphi);
} }
@ -2383,7 +2398,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning,
new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)), new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
new_exit_bb); new_exit_bb);
arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e); arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
add_phi_arg (new_phi, arg, new_exit_e); add_phi_arg (new_phi, arg, new_exit_e,
gimple_phi_arg_location_from_edge (orig_phi, e));
SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi)); SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
} }

View File

@ -2524,8 +2524,9 @@ get_initial_def_for_induction (gimple iv_phi)
NULL)); NULL));
/* Set the arguments of the phi node: */ /* Set the arguments of the phi node: */
add_phi_arg (induction_phi, vec_init, pe); add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop)); add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop),
UNKNOWN_LOCATION);
/* In case that vectorization factor (VF) is bigger than the number /* In case that vectorization factor (VF) is bigger than the number
@ -2934,12 +2935,13 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
for (j = 0; j < ncopies; j++) for (j = 0; j < ncopies; j++)
{ {
/* 1.1 set the loop-entry arg of the reduction-phi: */ /* 1.1 set the loop-entry arg of the reduction-phi: */
add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop)); add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop),
UNKNOWN_LOCATION);
/* 1.2 set the loop-latch arg for the reduction-phi: */ /* 1.2 set the loop-latch arg for the reduction-phi: */
if (j > 0) if (j > 0)
def = vect_get_vec_def_for_stmt_copy (dt, def); def = vect_get_vec_def_for_stmt_copy (dt, def);
add_phi_arg (phi, def, loop_latch_edge (loop)); add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
{ {
@ -3350,9 +3352,9 @@ vect_finalize_reduction:
/* Update phi node arguments with vs0 and vs2. */ /* Update phi node arguments with vs0 and vs2. */
add_phi_arg (vect_phi, vect_phi_init, add_phi_arg (vect_phi, vect_phi_init,
loop_preheader_edge (outer_loop)); loop_preheader_edge (outer_loop), UNKNOWN_LOCATION);
add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt),
loop_latch_edge (outer_loop)); loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
if (vect_print_dump_info (REPORT_DETAILS)) if (vect_print_dump_info (REPORT_DETAILS))
{ {
fprintf (vect_dump, "created double reduction phi node: "); fprintf (vect_dump, "created double reduction phi node: ");

View File

@ -3639,7 +3639,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
{ {
gcc_assert (phi); gcc_assert (phi);
if (i == vec_num - 1 && j == ncopies - 1) if (i == vec_num - 1 && j == ncopies - 1)
add_phi_arg (phi, lsq, loop_latch_edge (containing_loop)); add_phi_arg (phi, lsq, loop_latch_edge (containing_loop),
UNKNOWN_LOCATION);
msq = lsq; msq = lsq;
} }
} }

View File

@ -1888,6 +1888,7 @@ struct GTY(()) phi_arg_d {
pointer arithmetic with it. See phi_arg_index_from_use. */ pointer arithmetic with it. See phi_arg_index_from_use. */
struct ssa_use_operand_d imm_use; struct ssa_use_operand_d imm_use;
tree def; tree def;
location_t locus;
}; };