diff options
32 files changed, 424 insertions, 109 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f5b3ba34104..47845784fbc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> PR tree-optimization/40570 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 359433922d5..c172c96a580 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -74,6 +74,9 @@ gimple_assign_rhs_to_tree (gimple stmt) else gcc_unreachable (); + if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t)) + SET_EXPR_LOCATION (t, gimple_location (stmt)); + return t; } diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 1deb9c81a0a..70ab4e1b800 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -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++) { + 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, false); pp_character (buffer, '('); diff --git a/gcc/graphite.c b/gcc/graphite.c index a87bca867c9..f3bdc4b101f 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -4555,7 +4555,7 @@ add_loop_exit_phis (void **slot, void *s) tree res = create_new_def_for (gimple_phi_result (phi), 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; *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, gimple_phi_result_ptr (phi)); - add_phi_arg (phi, name1, true_edge); - add_phi_arg (phi, name2, false_edge); + add_phi_arg (phi, name1, true_edge, UNKNOWN_LOCATION); + add_phi_arg (phi, name2, false_edge, UNKNOWN_LOCATION); entry->new_name = res; *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, gimple_phi_result_ptr (phi)); - add_phi_arg (phi, use, false_e); - add_phi_arg (phi, use, true_e); + add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION); + add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION); } /* Add phi nodes for VAR that is used in LIVEIN. Phi nodes are diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c index 199c5855e2e..bc84eee372b 100644 --- a/gcc/ipa-struct-reorg.c +++ b/gcc/ipa-struct-reorg.c @@ -658,7 +658,7 @@ make_edge_and_fix_phis_of_dest (basic_block bb, edge e) { gimple phi = gsi_stmt (si); 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; diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c index 852be11153c..e7a49951a67 100644 --- a/gcc/lambda-code.c +++ b/gcc/lambda-code.c @@ -2343,6 +2343,10 @@ can_convert_to_perfect_nest (struct loop *loop) return false; } + +DEF_VEC_I(source_location); +DEF_VEC_ALLOC_I(source_location,heap); + /* Transform the loop nest into a perfect nest, if possible. LOOP is the loop nest to transform into a perfect nest LBOUNDS are the lower bounds for the loops to transform @@ -2400,6 +2404,7 @@ perfect_nestify (struct loop *loop, gimple stmt; tree oldivvar, ivvar, ivvarinced; VEC(tree,heap) *phis = NULL; + VEC(source_location,heap) *locations = NULL; htab_t replacements = NULL; /* Create the new loop. */ @@ -2412,8 +2417,11 @@ perfect_nestify (struct loop *loop, { phi = gsi_stmt (bsi); 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_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); @@ -2426,10 +2434,12 @@ perfect_nestify (struct loop *loop, { tree def; tree phiname; + source_location locus; def = VEC_pop (tree, phis); phiname = VEC_pop (tree, phis); + locus = VEC_pop (source_location, locations); 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); VEC_free (tree, heap, phis); diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 82827bf762a..3a4a1f40c55 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3013,8 +3013,8 @@ expand_parallel_call (struct omp_region *region, basic_block bb, { gimple phi = create_phi_node (tmp_join, bb); SSA_NAME_DEF_STMT (tmp_join) = phi; - add_phi_arg (phi, tmp_then, e_then); - add_phi_arg (phi, tmp_else, e_else); + add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION); + add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION); } 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) { gimple nphi; + source_location locus; phi = gsi_stmt (psi); 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; 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 iter_part_bb, we need to use v_extra instead. */ if (t == fd->loop.v) t = v_extra; - add_phi_arg (nphi, t, ene); - add_phi_arg (nphi, redirect_edge_var_map_def (vm), re); + add_phi_arg (nphi, t, ene, locus); + 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)); 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. */ phi = create_phi_node (trip_main, iter_part_bb); SSA_NAME_DEF_STMT (trip_main) = phi; - add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb)); - add_phi_arg (phi, trip_init, single_succ_edge (entry_bb)); + add_phi_arg (phi, trip_back, single_succ_edge (trip_update_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); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 49345c2535b..a6097edf3fe 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2886,7 +2886,7 @@ reinstall_phi_args (edge new_edge, edge old_edge) 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); @@ -4840,7 +4840,8 @@ gimple_make_forwarder_block (edge fallthru) new_phi = create_phi_node (var, bb); SSA_NAME_DEF_STMT (var) = new_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. */ @@ -5239,7 +5240,8 @@ add_phi_args_after_copy_edge (edge e_copy) phi = gsi_stmt (psi); phi_copy = gsi_stmt (psi_copy); 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); phi2 = gsi_stmt (psi2); 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)); } } diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index fdd7d780ade..34cfc80bbee 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -401,7 +401,8 @@ remove_forwarder_block (basic_block bb) gsi_next (&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); 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) { @@ -763,12 +765,13 @@ remove_forwarder_block_with_phi (basic_block bb) if (def == old_arg) { def = new_arg; + locus = redirect_edge_var_map_location (vm); break; } } } - add_phi_arg (phi, def, s); + add_phi_arg (phi, def, s, locus); } redirect_edge_var_map_clear (e); diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index e6de3772c3c..f56ecea7db7 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -455,6 +455,39 @@ gimple_phi_arg_edge (gimple gs, size_t 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 PHI nodes. */ static inline gimple_seq @@ -1196,6 +1229,14 @@ redirect_edge_var_map_result (edge_var_map *v) 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 in function cfun. */ diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index f9f0da20025..69dc446b8b8 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -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 gimple make_phi_node (tree var, int len); 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_node (gimple_stmt_iterator *, bool); extern void remove_phi_nodes (basic_block); @@ -604,6 +604,7 @@ extern bool gimple_stmt_may_fallthru (gimple); struct GTY(()) _edge_var_map { tree result; /* PHI result. */ tree def; /* PHI arg definition. */ + source_location locus; /* PHI arg location. */ }; 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; 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_dup (edge, edge); extern edge_var_map_vector redirect_edge_var_map_vector (edge); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index e62c5c1e792..f79ba758088 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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); 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)); } } } diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index ab827eadc57..bdec08063e4 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -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 reaching definition. */ FOR_EACH_EDGE (e, ei, bb->preds) - add_phi_arg (phi, var, e); + add_phi_arg (phi, var, e, UNKNOWN_LOCATION); } else { @@ -1320,9 +1320,12 @@ rewrite_add_phi_arguments (basic_block bb) gsi_next (&gsi)) { tree currdef; + gimple stmt; + phi = gsi_stmt (gsi); 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); 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; 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 symbol we may find NULL arguments. That's why we 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 { tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg); 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)) - 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) SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1; } diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 575025473cb..b9b6ea3cd43 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -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)) { tree def; + source_location locus; gimple phi_new = gsi_stmt (si_new); gimple phi_orig = gsi_stmt (si_orig); /* Add the first phi argument for the phi in NEW_LOOP (the one associated with the entry of NEW_LOOP) */ 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 associated with the latch of NEW_LOOP) */ 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) { @@ -122,7 +125,7 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop) /* Could be an integer. */ 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); } } diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 4ed8e9fbdf0..696c7259eed 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -36,6 +36,9 @@ along with GCC; see the file COPYING3. If not see #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. The node and pred/succ list is a simple linear list of nodes and edges represented as pairs of nodes. @@ -67,6 +70,9 @@ typedef struct _elim_graph { /* The predecessor and successor edge list. */ VEC(int,heap) *edge_list; + /* Source locus on each edge */ + VEC(source_location,heap) *edge_locus; + /* Visited vector. */ sbitmap visited; @@ -82,6 +88,9 @@ typedef struct _elim_graph { /* List of constant copies to emit. These are pushed on in pairs. */ VEC(int,heap) *const_dests; VEC(tree,heap) *const_copies; + + /* Source locations for any constant copies. */ + VEC(source_location,heap) *copy_locus; } *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. */ 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; 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]); 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], SA.partition_to_pseudo[src], @@ -180,7 +192,7 @@ insert_partition_copy_on_edge (edge e, int dest, int src) onto edge E. */ 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; 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]); set_location_for_edge (e); + /* If a locus is provided, override the default. */ + if (locus) + set_curr_insn_source_location (locus); start_sequence (); 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. */ 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; 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]); + 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], src, @@ -246,7 +266,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp) onto edge E. */ 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; 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]); + 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, SA.partition_to_pseudo[src], @@ -282,7 +306,9 @@ new_elim_graph (int size) g->nodes = VEC_alloc (int, heap, 30); g->const_dests = VEC_alloc (int, 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_locus = VEC_alloc (source_location, heap, 10); g->stack = VEC_alloc (int, heap, 30); 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->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 (int, heap, g->const_dests); VEC_free (int, heap, g->nodes); + VEC_free (source_location, heap, g->copy_locus); + VEC_free (source_location, heap, g->edge_locus); + free (g); } @@ -343,10 +373,11 @@ elim_graph_add_node (elim_graph g, int node) /* Add the edge PRED->SUCC to graph G. */ 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, 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. */ 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; unsigned x; @@ -364,8 +395,11 @@ elim_graph_remove_succ_edge (elim_graph g, int node) VEC_replace (int, g->edge_list, x, -1); y = VEC_index (int, g->edge_list, x + 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; } + *locus = UNKNOWN_LOCATION; 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 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 { \ unsigned x_; \ int y_; \ @@ -384,6 +418,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } while (0) @@ -393,7 +428,7 @@ do { \ GRAPH. VAR will hold the partition number found. CODE is the 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 { \ unsigned x_; \ int y_; \ @@ -403,6 +438,7 @@ do { \ if (y_ != (NODE)) \ continue; \ (VAR) = VEC_index (int, (GRAPH)->edge_list, x_); \ + (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \ CODE; \ } \ } 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)) { gimple phi = gsi_stmt (gsi); + source_location locus; p0 = var_to_partition (g->map, gimple_phi_result (phi)); /* Ignore results which are not in partitions. */ @@ -439,6 +476,7 @@ eliminate_build (elim_graph g) continue; 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 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. */ VEC_safe_push (int, heap, g->const_dests, p0); VEC_safe_push (tree, heap, g->const_copies, Ti); + VEC_safe_push (source_location, heap, g->copy_locus, locus); } else { @@ -459,7 +498,7 @@ eliminate_build (elim_graph g) { eliminate_name (g, p0); 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) { int S; + source_location locus; + 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)) elim_forward (g, S); @@ -488,7 +529,9 @@ static int elim_unvisited_predecessor (elim_graph g, int T) { 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)) return 1; @@ -502,13 +545,15 @@ static void elim_backward (elim_graph g, int T) { int P; + source_location locus; + 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)) { 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) { int P, S; + source_location locus; if (elim_unvisited_predecessor (g, T)) { @@ -544,23 +590,23 @@ elim_create (elim_graph g, int T) rtx U = get_temp_reg (var); int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var)); - insert_part_to_rtx_on_edge (g->e, U, T); - FOR_EACH_ELIM_GRAPH_PRED (g, T, P, + insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION); + FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, { if (!TEST_BIT (g->visited, 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 { - S = elim_graph_remove_succ_edge (g, T); + S = elim_graph_remove_succ_edge (g, T, &locus); if (S != -1) { 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; 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. */ if (e->flags & EDGE_ABNORMAL) @@ -610,9 +657,12 @@ eliminate_phi (edge e, elim_graph g) { int dest; tree src; + source_location locus; + src = VEC_pop (tree, g->const_copies); 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); 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 the PHI node. */ if (last && stmt_ends_bb_p (last)) diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index f9a2e40d480..9acf0ff75f0 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -747,6 +747,7 @@ create_phi_for_local_result (void **slot, void *data) gimple new_phi; basic_block store_bb; tree local_res; + source_location locus; /* STORE_BB is the block where the phi 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 = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)), NULL); + locus = gimple_location (reduc->reduc_stmt); new_phi = create_phi_node (local_res, store_bb); 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), - FALLTHRU_EDGE (loop->latch)); + FALLTHRU_EDGE (loop->latch), locus); reduc->new_phi = new_phi; 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); SSA_NAME_DEF_STMT (res) = nphi; - add_phi_arg (nphi, t, hpred); + add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION); 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); for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi)) { + source_location locus; + tree def; phi = gsi_stmt (gsi); res = PHI_RESULT (phi); 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)), - guard); - add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)), - end); + + def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)); + locus = gimple_phi_arg_location_from_edge (stmt, + loop_preheader_edge (loop)); + 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); PENDING_STMT (e) = NULL; diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c index 2907807690a..a48ae01fe8d 100644 --- a/gcc/tree-phinodes.c +++ b/gcc/tree-phinodes.c @@ -231,6 +231,8 @@ make_phi_node (tree var, int len) for (i = 0; i < capacity; i++) { use_operand_p imm; + + gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION); imm = gimple_phi_arg_imm_use_ptr (phi, i); imm->use = gimple_phi_arg_def_ptr (phi, i); 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++) { 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->use = gimple_phi_arg_def_ptr (new_phi, i); 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. */ 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; @@ -407,6 +411,7 @@ add_phi_arg (gimple phi, tree def, edge e) } 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. */ *(new_p->use) = *(old_p->use); 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 diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 5d8bf4d2704..0ce35f5de86 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -1512,8 +1512,8 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars) phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + 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); phi = create_phi_node (var, loop->header); SSA_NAME_DEF_STMT (var) = phi; - add_phi_arg (phi, init, entry); - add_phi_arg (phi, next, latch); + add_phi_arg (phi, init, entry, UNKNOWN_LOCATION); + add_phi_arg (phi, next, latch, UNKNOWN_LOCATION); } else { diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index c1f4e7f647b..2eec3147886 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -951,6 +951,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) { gimple phi = gsi_stmt (gsi); tree op; + source_location locus; /* Dead PHI do not imply control dependency. */ if (!gimple_plf (phi, STMT_NECESSARY) @@ -975,10 +976,16 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb) continue; } 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 - 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)); gsi_next (&gsi); } diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c index c4a40b084a6..e43c0bc404a 100644 --- a/gcc/tree-ssa-loop-manip.c +++ b/gcc/tree-ssa-loop-manip.c @@ -125,8 +125,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop, stmt = create_phi_node (vb, loop->header); SSA_NAME_DEF_STMT (vb) = stmt; - add_phi_arg (stmt, initial, loop_preheader_edge (loop)); - add_phi_arg (stmt, va, loop_latch_edge (loop)); + add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION); + add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION); } /* 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, gimple_phi_result_ptr (phi)); 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. @@ -476,11 +476,13 @@ split_loop_exit_edge (edge exit) tree new_name, name; use_operand_p op_p; gimple_stmt_iterator psi; + source_location locus; for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi)) { phi = gsi_stmt (psi); 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); @@ -494,7 +496,7 @@ split_loop_exit_edge (edge exit) new_name = duplicate_ssa_name (name, NULL); new_phi = create_phi_node (new_name, bb); 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); } @@ -1014,8 +1016,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor, phi_rest = create_phi_node (new_init, rest); SSA_NAME_DEF_STMT (new_init) = phi_rest; - add_phi_arg (phi_rest, init, precond_edge); - add_phi_arg (phi_rest, next, new_exit); + add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION); + add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION); SET_USE (op, new_init); } diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 8c3f71d32b6..97847f4c888 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -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))) { + source_location locus_0, locus_1; + new_var2 = create_tmp_var (TREE_TYPE (result), NULL); add_referenced_var (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); gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT); 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); @@ -1177,6 +1186,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb, tree lhs, rhs, name; gimple newphi, new_stmt; gimple_stmt_iterator gsi; + source_location locus; enum tree_code code; /* 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) return false; + locus = gimple_location (assign); lhs = gimple_assign_lhs (assign); rhs = gimple_assign_rhs1 (assign); 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); name = make_ssa_name (condstoretemp, new_stmt); gimple_assign_set_lhs (new_stmt, name); + gimple_set_location (new_stmt, locus); mark_symbols_for_renaming (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 where we stored the old memory contents. */ newphi = create_phi_node (condstoretemp, join_bb); - add_phi_arg (newphi, rhs, e0); - add_phi_arg (newphi, name, e1); + add_phi_arg (newphi, rhs, e0, locus); + add_phi_arg (newphi, name, e1, locus); lhs = unshare_expr (lhs); new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi)); diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index 022e4af9a48..bac2303899f 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -159,14 +159,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, { tree old_arg, new_var; gimple tmp; + source_location locus; 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 && (SSA_NAME_VERSION (old_arg) >= n || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE)) { gimple def_stmt = SSA_NAME_DEF_STMT (old_arg); old_arg = gimple_assign_rhs1 (def_stmt); + locus = gimple_location (def_stmt); } 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); new_var = make_ssa_name (new_var, tmp); gimple_assign_set_lhs (tmp, new_var); + gimple_set_location (tmp, locus); gsi_insert_on_edge (e, 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); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 9e3754b37fc..237c250a5f0 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -3328,9 +3328,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum, gcc_assert (get_expr_type (ae) == type || useless_type_conversion_p (type, get_expr_type (ae))); 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 - 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)); diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index b6d2fafaa0f..71a34957bdf 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -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)) { gimple phi = gsi_stmt (gsi); - + source_location locus; 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); } } diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 7ec04f70fad..e8033cd46ca 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -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. */ 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; 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.result = result; + new_node.locus = locus; VEC_safe_push (edge_var_map, heap, head, &new_node); 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)) { tree def; + source_location locus ; phi = gsi_stmt (gsi); def = gimple_phi_arg_def (phi, e->dest_idx); + locus = gimple_phi_arg_location (phi, e->dest_idx); if (def == NULL_TREE) 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); @@ -233,7 +236,7 @@ flush_pending_stmts (edge e) phi = gsi_stmt (gsi); 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); diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index a5494827b37..1309e822fe2 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -638,8 +638,8 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf) !gsi_end_p (gsi); gsi_next (&gsi), i++) { gimple phi = gsi_stmt (gsi); - add_phi_arg (phi, info.target_inbound_names[i], e1f); - add_phi_arg (phi, info.target_outbound_names[i], e2f); + add_phi_arg (phi, info.target_inbound_names[i], e1f, UNKNOWN_LOCATION); + add_phi_arg (phi, info.target_outbound_names[i], e2f, UNKNOWN_LOCATION); } } diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index f2d58dd6e4a..efd6bc2c029 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -548,7 +548,7 @@ add_successor_phi_arg (edge e, tree var, tree phi_arg) break; 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 @@ -773,7 +773,7 @@ eliminate_tail_call (struct tailcall *t) phi = gsi_stmt (gsi); 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); } @@ -870,7 +870,8 @@ create_tailcall_accumulator (const char *label, basic_block bb, tree init) add_referenced_var (tmp); phi = create_phi_node (tmp, bb); /* 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); } @@ -933,7 +934,8 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) set_default_def (param, new_name); phi = create_phi_node (name, first); 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; } diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 7646cc1ad0f..facde06969e 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -3049,7 +3049,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi, msq = make_ssa_name (vec_dest, NULL); phi_stmt = create_phi_node (msq, containing_loop->header); 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; } diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c index eaf263c4270..c0b15cd98a5 100644 --- a/gcc/tree-vect-loop-manip.c +++ b/gcc/tree-vect-loop-manip.c @@ -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_next (&gsi_new), gsi_next (&gsi_orig)) { + source_location locus; phi_new = gsi_stmt (gsi_new); phi_orig = gsi_stmt (gsi_orig); /* step 1. */ 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. */ 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) continue; @@ -190,7 +193,7 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_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). */ 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_next (&gsi_orig), gsi_next (&gsi_update)) { + source_location loop_locus, guard_locus;; orig_phi = gsi_stmt (gsi_orig); 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 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_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_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, guard_arg, guard_edge); + add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus); + add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus); /* 1.3. Update phi in successor block. */ 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); /* 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: */ 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) guard_arg = new_name2; - add_phi_arg (new_phi, loop_arg, new_exit_e); - add_phi_arg (new_phi, guard_arg, guard_edge); + add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION); + add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION); /* 1.3. Update phi in successor block. */ 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); /* 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: */ 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: */ 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: */ 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) { 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) new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1); else 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_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e); 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); @@ -954,8 +968,9 @@ set_prologue_iterations (basic_block bb_before_first_loop, gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); newphi = create_phi_node (var, bb_before_first_loop); - add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru); - add_phi_arg (newphi, first_niters, e_false); + add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru, + UNKNOWN_LOCATION); + add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION); 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_exit_bb); 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)); } diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index b7b9d7893e5..113dc0ff0e6 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2524,8 +2524,9 @@ get_initial_def_for_induction (gimple iv_phi) NULL)); /* Set the arguments of the phi node: */ - add_phi_arg (induction_phi, vec_init, pe); - add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop)); + add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION); + 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 @@ -2934,12 +2935,13 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt, for (j = 0; j < ncopies; j++) { /* 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: */ if (j > 0) 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)) { @@ -3350,9 +3352,9 @@ vect_finalize_reduction: /* Update phi node arguments with vs0 and vs2. */ 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), - loop_latch_edge (outer_loop)); + loop_latch_edge (outer_loop), UNKNOWN_LOCATION); if (vect_print_dump_info (REPORT_DETAILS)) { fprintf (vect_dump, "created double reduction phi node: "); diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c index 50900775a04..aacf768a4cf 100644 --- a/gcc/tree-vect-stmts.c +++ b/gcc/tree-vect-stmts.c @@ -3639,7 +3639,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt, { gcc_assert (phi); 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; } } diff --git a/gcc/tree.h b/gcc/tree.h index d972cfe334e..a1370fa5e55 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -1888,6 +1888,7 @@ struct GTY(()) phi_arg_d { pointer arithmetic with it. See phi_arg_index_from_use. */ struct ssa_use_operand_d imm_use; tree def; + location_t locus; }; |