diff mbox

Add block debug info to phi_arg_d

Message ID CAO2gOZXW=GFs7eT=yu+GRWAD+DtBNmo0qpCGY=f0iM9V-Jympg@mail.gmail.com
State New
Headers show

Commit Message

Dehao Chen July 5, 2012, 9:08 a.m. UTC
Hi,

This patch added block field to phi_arg_d to make sure the associated
source locus is consistent with its block info.

Bootstrapped and passed gcc regression tests.

OK for trunk?

Thanks,
Dehao

http://codereview.appspot.com/6349075

gcc/ChangeLog

2012-07-05  Dehao Chen  <dehao@google.com>

	* tree.h (phi_arg_d): New field.
	* tree-flow-inline.h (gimple_phi_arg_block): New function.
	(gimple_phi_arg_block_from_edge): New function.
	(gimple_phi_arg_set_block): New function.
	(gimple_phi_arg_has_block): New function.
	(redirect_edge_var_map_block): New function.
	* tree-flow.h (_edge_var_map): New field.
	* tree-ssa-live.c (remove_unused_locals): Mark phi_arg's block
	as used.
	* tree-eh.c (cleanup_empty_eh_merge_phis): Add block debug info for
	redirect_edge_var_map_add.
	* tree-outof-ssa.c (_elim_graph): New field.
	(insert_partition_copy_on_edge): New parameter.
	(insert_value_copy_on_edge): New parameter.
	(insert_rtx_to_part_on_edge): New parameter.
	(insert_part_to_rtx_on_edge): New parameter.
	(elim_graph_add_edge): New parameter.
	(elim_graph_remove_succ_edge): New parameter.
	(FOR_EACH_ELIM_GRAPH_SUCC): New parameter.
	(FOR_EACH_ELIM_GRAPH_PRED): New parameter.
	(new_elim_graph): Add block debug info.
	(clear_elim_graph): Likewise.
	(delete_elim_graph): Likewise.
	(elim_graph_add_node): Likewise.
	(elim_graph_add_edge): Likewise.
	(elim_graph_remove_succ_edge): Likewise.
	(eliminate_build): Likewise.
	(elim_forward): Likewise.
	(elim_unvisited_predecessor): Likewise.
	(elim_backward): Likewise.
	(elim_create): Likewise.
	(eliminate_phi): Likewise.
	(insert_backedge_copies): Likewise.
	* tree-into-ssa.c (insert_phi_nodes_for): Add block debug info for
	add_phi_arg.
	(rewrite_add_phi_arguments): Likewise.
	* tree-ssa-loop-im.c (execute_sm_if_changed): Likewise.
	* tree-ssa-tail-merge.c (replace_block_by): Likewise.
	* tree-ssa-threadupdate.c (copy_phi_args): Likewise.
	* tree-loop-distribution.c (update_phis_for_loop_copy): Likewise.
	* tree-ssa-loop-manip.c (create_iv): Likewise.
	(add_exit_phis_edge): Likewise.
	(split_loop_exit_edge): Likewise.
	(copy_phi_node_args): Likewise.
	(tree_transform_and_unroll_loop): Likewise.
	* value-prof.c (gimple_ic): Likewise.
	(gimple_stringop_fixed_value): Likewise.
	* tree-tailcall.c (add_successor_phi_arg): Likewise.
	(eliminate_tail_call): Likewise.
	(create_tailcall_accumulator): Likewise.
	(tree_optimize_tail_calls_1): Likewise.
	* tree-phinodes.c (add_phi_arg): Likewise.
	(make_phi_node): Likewise.
	(resize_phi_node): Likewise.
	(remove_phi_arg_num): Likewise.
	* omp-low.c (expand_parallel_call): Likewise.
	(expand_omp_for_static_chunk): Likewise.
	* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop):
	Likewise.
	(slpeel_update_phi_nodes_for_guard1): Likewise.
	(slpeel_update_phi_nodes_for_guard2): Likewise.
	(slpeel_tree_duplicate_loop_to_edge_cfg): Likewise.
	(set_prologue_iterations): Likewise.
	(slpeel_tree_peel_loop_to_edge): Likewise.
	(vect_loop_versioning): Likewise.
	* tree-parloops.c (create_phi_for_local_result): Likewise.
	(transform_to_exit_first_loop): Likewise.
	(create_parallel_loop): Likewise.
	* ipa-split.c (split_function): Likewise.
	* tree-vect-loop.c (get_initial_def_for_induction): Likewise.
	(vect_create_epilog_for_reduction): Likewise.
	* tree-vect-data-refs.c (vect_setup_realignment): Likewise.
	* graphite-scop-detection.c (canonicalize_loop_closed_ssa): Likewise.
	* tree-ssa-phiopt.c (cond_store_replacement): Likewise.
	(cond_if_else_store_replacement_1): Likewise.
	* tree-cfgcleanup.c (remove_forwarder_block): Likewise.
	(remove_forwarder_block_with_phi): Likewise.
	* tree-ssa-pre.c (insert_into_preds_of_block): Likewise.
	* tree-predcom.c (initialize_root_vars): Likewise.
	(initialize_root_vars_lm): Likewise.
	* sese.c (sese_add_exit_phis_edge): Likewise.
	* tree-ssa-dce.c (forward_edge_to_pdom): Likewise.
	* tree-ssa.c (flush_pending_stmts): Likewise.
	(redirect_edge_var_map_add): Likewise.
	(ssa_redirect_edge): Likewise.
	* gimple-streamer-in.c (input_phi): Likewise.
	* tree-vect-stmts.c (vectorizable_load): Likewise.
	* tree-inline.c (copy_phis_for_bb): Likewise.
	* tree-ssa-phiprop.c (phiprop_insert_phi): Likewise.
	* tree-switch-conversion.c (fix_phi_nodes): Likewise.
	* tree-cfg.c (reinstall_phi_args): Likewise.
	(gimple_make_forwarder_block): Likewise.
	(add_phi_args_after_copy_edge): Likewise.
	(gimple_duplicate_sese_tail): Likewise.

Comments

Richard Biener July 5, 2012, 9:23 a.m. UTC | #1
On Thu, Jul 5, 2012 at 11:08 AM, Dehao Chen <dehao@google.com> wrote:
> Hi,
>
> This patch added block field to phi_arg_d to make sure the associated
> source locus is consistent with its block info.
>
> Bootstrapped and passed gcc regression tests.
>
> OK for trunk?

Hum - makes me want a location like we have on RTL (which maps to
location plus block ...).  But oh well ...

struct GTY(()) phi_arg_d {
  /* imm_use MUST be the first element in struct because we do some
     pointer arithmetic with it.  See phi_arg_index_from_use.  */
  struct ssa_use_operand_d imm_use;
location_t locus;
+  tree block;
 };

please place block before locus though.

Ok with that change.

Thanks,
Richard.

> Thanks,
> Dehao
>
> http://codereview.appspot.com/6349075
>
> gcc/ChangeLog
>
> 2012-07-05  Dehao Chen  <dehao@google.com>
>
>         * tree.h (phi_arg_d): New field.
>         * tree-flow-inline.h (gimple_phi_arg_block): New function.
>         (gimple_phi_arg_block_from_edge): New function.
>         (gimple_phi_arg_set_block): New function.
>         (gimple_phi_arg_has_block): New function.
>         (redirect_edge_var_map_block): New function.
>         * tree-flow.h (_edge_var_map): New field.
>         * tree-ssa-live.c (remove_unused_locals): Mark phi_arg's block
>         as used.
>         * tree-eh.c (cleanup_empty_eh_merge_phis): Add block debug info for
>         redirect_edge_var_map_add.
>         * tree-outof-ssa.c (_elim_graph): New field.
>         (insert_partition_copy_on_edge): New parameter.
>         (insert_value_copy_on_edge): New parameter.
>         (insert_rtx_to_part_on_edge): New parameter.
>         (insert_part_to_rtx_on_edge): New parameter.
>         (elim_graph_add_edge): New parameter.
>         (elim_graph_remove_succ_edge): New parameter.
>         (FOR_EACH_ELIM_GRAPH_SUCC): New parameter.
>         (FOR_EACH_ELIM_GRAPH_PRED): New parameter.
>         (new_elim_graph): Add block debug info.
>         (clear_elim_graph): Likewise.
>         (delete_elim_graph): Likewise.
>         (elim_graph_add_node): Likewise.
>         (elim_graph_add_edge): Likewise.
>         (elim_graph_remove_succ_edge): Likewise.
>         (eliminate_build): Likewise.
>         (elim_forward): Likewise.
>         (elim_unvisited_predecessor): Likewise.
>         (elim_backward): Likewise.
>         (elim_create): Likewise.
>         (eliminate_phi): Likewise.
>         (insert_backedge_copies): Likewise.
>         * tree-into-ssa.c (insert_phi_nodes_for): Add block debug info for
>         add_phi_arg.
>         (rewrite_add_phi_arguments): Likewise.
>         * tree-ssa-loop-im.c (execute_sm_if_changed): Likewise.
>         * tree-ssa-tail-merge.c (replace_block_by): Likewise.
>         * tree-ssa-threadupdate.c (copy_phi_args): Likewise.
>         * tree-loop-distribution.c (update_phis_for_loop_copy): Likewise.
>         * tree-ssa-loop-manip.c (create_iv): Likewise.
>         (add_exit_phis_edge): Likewise.
>         (split_loop_exit_edge): Likewise.
>         (copy_phi_node_args): Likewise.
>         (tree_transform_and_unroll_loop): Likewise.
>         * value-prof.c (gimple_ic): Likewise.
>         (gimple_stringop_fixed_value): Likewise.
>         * tree-tailcall.c (add_successor_phi_arg): Likewise.
>         (eliminate_tail_call): Likewise.
>         (create_tailcall_accumulator): Likewise.
>         (tree_optimize_tail_calls_1): Likewise.
>         * tree-phinodes.c (add_phi_arg): Likewise.
>         (make_phi_node): Likewise.
>         (resize_phi_node): Likewise.
>         (remove_phi_arg_num): Likewise.
>         * omp-low.c (expand_parallel_call): Likewise.
>         (expand_omp_for_static_chunk): Likewise.
>         * tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop):
>         Likewise.
>         (slpeel_update_phi_nodes_for_guard1): Likewise.
>         (slpeel_update_phi_nodes_for_guard2): Likewise.
>         (slpeel_tree_duplicate_loop_to_edge_cfg): Likewise.
>         (set_prologue_iterations): Likewise.
>         (slpeel_tree_peel_loop_to_edge): Likewise.
>         (vect_loop_versioning): Likewise.
>         * tree-parloops.c (create_phi_for_local_result): Likewise.
>         (transform_to_exit_first_loop): Likewise.
>         (create_parallel_loop): Likewise.
>         * ipa-split.c (split_function): Likewise.
>         * tree-vect-loop.c (get_initial_def_for_induction): Likewise.
>         (vect_create_epilog_for_reduction): Likewise.
>         * tree-vect-data-refs.c (vect_setup_realignment): Likewise.
>         * graphite-scop-detection.c (canonicalize_loop_closed_ssa): Likewise.
>         * tree-ssa-phiopt.c (cond_store_replacement): Likewise.
>         (cond_if_else_store_replacement_1): Likewise.
>         * tree-cfgcleanup.c (remove_forwarder_block): Likewise.
>         (remove_forwarder_block_with_phi): Likewise.
>         * tree-ssa-pre.c (insert_into_preds_of_block): Likewise.
>         * tree-predcom.c (initialize_root_vars): Likewise.
>         (initialize_root_vars_lm): Likewise.
>         * sese.c (sese_add_exit_phis_edge): Likewise.
>         * tree-ssa-dce.c (forward_edge_to_pdom): Likewise.
>         * tree-ssa.c (flush_pending_stmts): Likewise.
>         (redirect_edge_var_map_add): Likewise.
>         (ssa_redirect_edge): Likewise.
>         * gimple-streamer-in.c (input_phi): Likewise.
>         * tree-vect-stmts.c (vectorizable_load): Likewise.
>         * tree-inline.c (copy_phis_for_bb): Likewise.
>         * tree-ssa-phiprop.c (phiprop_insert_phi): Likewise.
>         * tree-switch-conversion.c (fix_phi_nodes): Likewise.
>         * tree-cfg.c (reinstall_phi_args): Likewise.
>         (gimple_make_forwarder_block): Likewise.
>         (add_phi_args_after_copy_edge): Likewise.
>         (gimple_duplicate_sese_tail): Likewise.
>
> Index: gcc/tree-into-ssa.c
> ===================================================================
> --- gcc/tree-into-ssa.c (revision 189246)
> +++ gcc/tree-into-ssa.c (working copy)
> @@ -1119,7 +1119,7 @@
>              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, UNKNOWN_LOCATION);
> +           add_phi_arg (phi, var, e, UNKNOWN_LOCATION, NULL);
>         }
>        else
>         {
> @@ -1474,7 +1474,8 @@
>           phi = gsi_stmt (gsi);
>           currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
>           stmt = SSA_NAME_DEF_STMT (currdef);
> -         add_phi_arg (phi, currdef, e, gimple_location (stmt));
> +         add_phi_arg (phi, currdef, e, gimple_location (stmt),
> +                      gimple_block (stmt));
>         }
>      }
>  }
> Index: gcc/tree-ssa-loop-im.c
> ===================================================================
> --- gcc/tree-ssa-loop-im.c      (revision 189246)
> +++ gcc/tree-ssa-loop-im.c      (working copy)
> @@ -2086,7 +2086,7 @@
>           if (gimple_phi_arg_edge (phi, i)->src == new_bb)
>             {
>               tree arg = gimple_phi_arg_def (phi, i);
> -             add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION);
> +             add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION, NULL);
>               update_stmt (phi);
>             }
>        }
> Index: gcc/tree-ssa-tail-merge.c
> ===================================================================
> --- gcc/tree-ssa-tail-merge.c   (revision 189246)
> +++ gcc/tree-ssa-tail-merge.c   (working copy)
> @@ -1458,7 +1458,7 @@
>        bb2_phi = vop_phi (bb2);
>
>        add_phi_arg (bb2_phi, SSA_NAME_VAR (gimple_phi_result (bb2_phi)),
> -                  pred_edge, UNKNOWN_LOCATION);
> +                  pred_edge, UNKNOWN_LOCATION, NULL);
>      }
>
>    bb2->frequency += bb1->frequency;
> Index: gcc/tree-ssa-threadupdate.c
> ===================================================================
> --- gcc/tree-ssa-threadupdate.c (revision 189246)
> +++ gcc/tree-ssa-threadupdate.c (working copy)
> @@ -316,7 +316,9 @@
>      {
>        gimple phi = gsi_stmt (gsi);
>        source_location locus = gimple_phi_arg_location (phi, src_indx);
> -      add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus);
> +      tree block = gimple_phi_arg_block (phi, src_indx);
> +      add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus,
> +                  block);
>      }
>  }
>
> Index: gcc/tree-loop-distribution.c
> ===================================================================
> --- gcc/tree-loop-distribution.c        (revision 189246)
> +++ gcc/tree-loop-distribution.c        (working copy)
> @@ -171,6 +171,7 @@
>      {
>        tree def;
>        source_location locus;
> +      tree block;
>        gimple phi_new = gsi_stmt (si_new);
>        gimple phi_orig = gsi_stmt (si_orig);
>
> @@ -178,12 +179,14 @@
>          associated with the entry of NEW_LOOP)  */
>        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_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);
> +      block = gimple_phi_arg_block_from_edge (phi_orig, orig_entry_e);
> +      add_phi_arg (phi_new, def, new_loop_entry_e, locus, block);
>
>        /* 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);
> +      block = gimple_phi_arg_block_from_edge (phi_orig, orig_loop_latch);
>
>        if (TREE_CODE (def) == SSA_NAME)
>         {
> @@ -198,7 +201,8 @@
>         /* Could be an integer.  */
>         new_ssa_name = def;
>
> -      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
> +      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus,
> +                  block);
>      }
>  }
>
> Index: gcc/tree-ssa-loop-manip.c
> ===================================================================
> --- gcc/tree-ssa-loop-manip.c   (revision 189246)
> +++ gcc/tree-ssa-loop-manip.c   (working copy)
> @@ -121,8 +121,9 @@
>
>    stmt = create_phi_node (vb, loop->header);
>    SSA_NAME_DEF_STMT (vb) = stmt;
> -  add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION);
> -  add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
> +  add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION,
> +              NULL);
> +  add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION, NULL);
>  }
>
>  /* Add exit phis for the USE on EXIT.  */
> @@ -152,7 +153,7 @@
>    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, UNKNOWN_LOCATION);
> +    add_phi_arg (phi, use, e, UNKNOWN_LOCATION, NULL);
>  }
>
>  /* Add exit phis for VAR that is used in LIVEIN.
> @@ -485,12 +486,14 @@
>    use_operand_p op_p;
>    gimple_stmt_iterator psi;
>    source_location locus;
> +  tree block;
>
>    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));
> +      block = gimple_phi_arg_block_from_edge (phi, single_succ_edge (bb));
>
>        name = USE_FROM_PTR (op_p);
>
> @@ -504,7 +507,7 @@
>        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, locus);
> +      add_phi_arg (new_phi, name, exit, locus, block);
>        SET_USE (op_p, new_name);
>      }
>
> @@ -1024,8 +1027,8 @@
>        phi_rest = create_phi_node (new_init, rest);
>        SSA_NAME_DEF_STMT (new_init) = phi_rest;
>
> -      add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION);
> -      add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION);
> +      add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION, NULL);
> +      add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION, NULL);
>        SET_USE (op, new_init);
>      }
>
> Index: gcc/value-prof.c
> ===================================================================
> --- gcc/value-prof.c    (revision 189246)
> +++ gcc/value-prof.c    (working copy)
> @@ -1245,10 +1245,12 @@
>        SSA_NAME_DEF_STMT (result) = phi;
>        gimple_call_set_lhs (icall_stmt,
>                            make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
> -      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION,
> +                  NULL);
>        gimple_call_set_lhs (dcall_stmt,
>                            make_ssa_name (SSA_NAME_VAR (result), dcall_stmt));
> -      add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION,
> +                  NULL);
>      }
>
>    /* Build an EH edge for the direct call if necessary.  */
> @@ -1476,10 +1478,12 @@
>        SSA_NAME_DEF_STMT (result) = phi;
>        gimple_call_set_lhs (vcall_stmt,
>                            make_ssa_name (SSA_NAME_VAR (result), vcall_stmt));
> -      add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION,
> +                  NULL);
>        gimple_call_set_lhs (icall_stmt,
>                            make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
> -      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION,
> +                  NULL);
>      }
>
>    /* Because these are all string op builtins, they're all nothrow.  */
> Index: gcc/tree-tailcall.c
> ===================================================================
> --- gcc/tree-tailcall.c (revision 189246)
> +++ gcc/tree-tailcall.c (working copy)
> @@ -597,7 +597,7 @@
>        break;
>
>    gcc_assert (!gsi_end_p (gsi));
> -  add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION);
> +  add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION, NULL);
>  }
>
>  /* Creates a GIMPLE statement which computes the operation specified by
> @@ -853,7 +853,7 @@
>        phi = gsi_stmt (gsi);
>        gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
>
> -      add_phi_arg (phi, arg, e, gimple_location (stmt));
> +      add_phi_arg (phi, arg, e, gimple_location (stmt), gimple_block (stmt));
>        gsi_next (&gsi);
>      }
>
> @@ -948,7 +948,7 @@
>    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),
> -              UNKNOWN_LOCATION);
> +              UNKNOWN_LOCATION, NULL);
>    return PHI_RESULT (phi);
>  }
>
> @@ -1012,7 +1012,7 @@
>                 phi = create_phi_node (name, first);
>                 SSA_NAME_DEF_STMT (name) = phi;
>                 add_phi_arg (phi, new_name, single_pred_edge (first),
> -                            EXPR_LOCATION (param));
> +                            EXPR_LOCATION (param), NULL);
>               }
>           phis_constructed = true;
>         }
> Index: gcc/tree.h
> ===================================================================
> --- gcc/tree.h  (revision 189246)
> +++ gcc/tree.h  (working copy)
> @@ -2036,6 +2036,7 @@
>    struct ssa_use_operand_d imm_use;
>    tree def;
>    location_t locus;
> +  tree block;
>  };
>
>
> Index: gcc/tree-phinodes.c
> ===================================================================
> --- gcc/tree-phinodes.c (revision 189246)
> +++ gcc/tree-phinodes.c (working copy)
> @@ -205,6 +205,7 @@
>        use_operand_p  imm;
>
>        gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
> +      gimple_phi_arg_set_block (phi, i ,NULL);
>        imm = gimple_phi_arg_imm_use_ptr (phi, i);
>        imm->use = gimple_phi_arg_def_ptr (phi, i);
>        imm->prev = NULL;
> @@ -275,6 +276,7 @@
>        use_operand_p imm;
>
>        gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
> +      gimple_phi_arg_set_block (new_phi, i, NULL);
>        imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
>        imm->use = gimple_phi_arg_def_ptr (new_phi, i);
>        imm->prev = NULL;
> @@ -362,7 +364,7 @@
>     PHI points to the reallocated phi node when we return.  */
>
>  void
> -add_phi_arg (gimple phi, tree def, edge e, source_location locus)
> +add_phi_arg (gimple phi, tree def, edge e, source_location locus, tree block)
>  {
>    basic_block bb = e->dest;
>
> @@ -386,6 +388,7 @@
>
>    SET_PHI_ARG_DEF (phi, e->dest_idx, def);
>    gimple_phi_arg_set_location (phi, e->dest_idx, locus);
> +  gimple_phi_arg_set_block (phi, e->dest_idx, block);
>  }
>
>
> @@ -417,6 +420,8 @@
>        /* Move the location as well.  */
>        gimple_phi_arg_set_location (phi, i,
>                                    gimple_phi_arg_location (phi, num_elem - 1));
> +      gimple_phi_arg_set_block (phi, i,
> +                               gimple_phi_arg_block (phi, num_elem - 1));
>      }
>
>    /* Shrink the vector and return.  Note that we do not have to clear
> Index: gcc/omp-low.c
> ===================================================================
> --- gcc/omp-low.c       (revision 189246)
> +++ gcc/omp-low.c       (working copy)
> @@ -3061,8 +3061,8 @@
>             {
>               gimple phi = create_phi_node (tmp_join, bb);
>               SSA_NAME_DEF_STMT (tmp_join) = phi;
> -             add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
> -             add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
> +             add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION, NULL);
> +             add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION, NULL);
>             }
>
>           val = tmp_join;
> @@ -4597,6 +4597,7 @@
>         {
>           gimple nphi;
>           source_location locus;
> +         tree block;
>
>           phi = gsi_stmt (psi);
>           t = gimple_phi_result (phi);
> @@ -4606,14 +4607,16 @@
>
>           t = PHI_ARG_DEF_FROM_EDGE (phi, se);
>           locus = gimple_phi_arg_location_from_edge (phi, se);
> +         block = gimple_phi_arg_block_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, locus);
> +         add_phi_arg (nphi, t, ene, locus, block);
>           locus = redirect_edge_var_map_location (vm);
> -         add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
> +         block = redirect_edge_var_map_block (vm);
> +         add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus, block);
>         }
>        gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
>        redirect_edge_var_map_clear (re);
> @@ -4629,9 +4632,9 @@
>        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),
> -                  UNKNOWN_LOCATION);
> +                  UNKNOWN_LOCATION, NULL);
>        add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
> -                  UNKNOWN_LOCATION);
> +                  UNKNOWN_LOCATION, NULL);
>      }
>
>    set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
> Index: gcc/tree-vect-loop-manip.c
> ===================================================================
> --- gcc/tree-vect-loop-manip.c  (revision 189246)
> +++ gcc/tree-vect-loop-manip.c  (working copy)
> @@ -294,13 +294,15 @@
>         gsi_next (&gsi_new), gsi_next (&gsi_orig))
>      {
>        source_location locus;
> +      tree block;
>        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);
>        locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e);
> -      add_phi_arg (phi_new, def, new_loop_entry_e, locus);
> +      block = gimple_phi_arg_block_from_edge (phi_orig, entry_arg_e);
> +      add_phi_arg (phi_new, def, new_loop_entry_e, locus, block);
>
>        /* step 2.  */
>        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
> @@ -317,7 +319,8 @@
>         }
>
>        /* An ordinary ssa name defined in the loop.  */
> -      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
> +      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus,
> +                  block);
>
>        /* Drop any debug references outside the loop, if they would
>          become ill-formed SSA.  */
> @@ -512,6 +515,7 @@
>         gsi_next (&gsi_orig), gsi_next (&gsi_update))
>      {
>        source_location loop_locus, guard_locus;
> +      tree loop_block, guard_block;
>        orig_phi = gsi_stmt (gsi_orig);
>        update_phi = gsi_stmt (gsi_update);
>
> @@ -527,13 +531,19 @@
>        loop_locus = gimple_phi_arg_location_from_edge (orig_phi,
>                                                       EDGE_SUCC (loop->latch,
>                                                                  0));
> +      loop_block = gimple_phi_arg_block_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));
> +      guard_block = gimple_phi_arg_block_from_edge (orig_phi,
> +                                                   loop_preheader_edge (loop));
>
> -      add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus);
> -      add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus);
> +      add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus, loop_block);
> +      add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus, guard_block);
>
>        /* 1.3. Update phi in successor block.  */
>        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
> @@ -552,7 +562,7 @@
>                                   *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), loop_locus);
> +      add_phi_arg (new_phi, loop_arg, single_exit (loop), loop_locus,
> loop_block);
>
>        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
>        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
> @@ -680,8 +690,8 @@
>        if (new_name2)
>          guard_arg = new_name2;
>
> -      add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION);
> -      add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION);
> +      add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION, NULL);
> +      add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION, NULL);
>
>        /* 1.3. Update phi in successor block.  */
>        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
> @@ -696,7 +706,8 @@
>                                   *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), UNKNOWN_LOCATION);
> +      add_phi_arg (new_phi, loop_arg, single_exit (loop), UNKNOWN_LOCATION,
> +                  NULL);
>
>        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
>        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
> @@ -733,7 +744,7 @@
>        /* 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),
> -                  UNKNOWN_LOCATION);
> +                  UNKNOWN_LOCATION, NULL);
>
>        /* 3.4. Update phi in successor of GUARD_BB:  */
>        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
> @@ -859,14 +870,16 @@
>         {
>           edge new_loop_exit_edge;
>           source_location locus;
> +         tree block;
>
>           locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop));
> +         block = gimple_phi_arg_block_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, locus);
> +         add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus, block);
>         }
>      }
>
> @@ -905,7 +918,8 @@
>           phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
>           if (phi_arg)
>             add_phi_arg (phi, phi_arg, new_exit_e,
> -                        gimple_phi_arg_location_from_edge (phi, entry_e));
> +                        gimple_phi_arg_location_from_edge (phi, entry_e),
> +                        gimple_phi_arg_block_from_edge (phi, entry_e));
>         }
>
>        redirect_edge_and_branch_force (entry_e, new_loop->header);
> @@ -1089,8 +1103,8 @@
>
>    newphi = create_phi_node (var, bb_before_first_loop);
>    add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru,
> -              UNKNOWN_LOCATION);
> -  add_phi_arg (newphi, *first_niters, e_false, UNKNOWN_LOCATION);
> +              UNKNOWN_LOCATION, NULL);
> +  add_phi_arg (newphi, *first_niters, e_false, UNKNOWN_LOCATION, NULL);
>
>    *first_niters = PHI_RESULT (newphi);
>  }
> @@ -1193,7 +1207,7 @@
>                                           new_phi);
>             use_operand_p use_p;
>
> -           add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION);
> +           add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION, NULL);
>             gimple_phi_set_result (new_phi, new_vop);
>             FOR_EACH_IMM_USE_STMT (stmt, imm_iter, vop)
>               if (stmt != new_phi && gimple_bb (stmt) != loop->header)
> @@ -2551,7 +2565,8 @@
>                                   new_exit_bb);
>        arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
>        add_phi_arg (new_phi, arg, new_exit_e,
> -                  gimple_phi_arg_location_from_edge (orig_phi, e));
> +                  gimple_phi_arg_location_from_edge (orig_phi, e),
> +                  gimple_phi_arg_block_from_edge (orig_phi, e));
>        adjust_phi_and_debug_stmts (orig_phi, e, PHI_RESULT (new_phi));
>      }
>
> Index: gcc/tree-parloops.c
> ===================================================================
> --- gcc/tree-parloops.c (revision 189246)
> +++ gcc/tree-parloops.c (working copy)
> @@ -998,6 +998,7 @@
>    basic_block store_bb;
>    tree local_res;
>    source_location locus;
> +  tree block;
>
>    /* STORE_BB is the block where the phi
>       should be stored.  It is the destination of the loop exit.
> @@ -1017,11 +1018,12 @@
>      = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
>                      NULL);
>    locus = gimple_location (reduc->reduc_stmt);
> +  block = gimple_block (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, locus);
> +  add_phi_arg (new_phi, reduc->init, e, locus, block);
>    add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
> -              FALLTHRU_EDGE (loop->latch), locus);
> +              FALLTHRU_EDGE (loop->latch), locus, block);
>    reduc->new_phi = new_phi;
>
>    return 1;
> @@ -1500,7 +1502,7 @@
>        SET_PHI_RESULT (phi, t);
>        nphi = create_phi_node (res, orig_header);
>        SSA_NAME_DEF_STMT (res) = nphi;
> -      add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
> +      add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION, NULL);
>
>        if (res == control)
>         {
> @@ -1656,6 +1658,7 @@
>    for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
>      {
>        source_location locus;
> +      tree block;
>        tree def;
>        phi = gsi_stmt (gsi);
>        stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
> @@ -1663,11 +1666,14 @@
>        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);
> +      block = gimple_phi_arg_block_from_edge (stmt,
> +                                             loop_preheader_edge (loop));
> +      add_phi_arg (phi, def, guard, locus, block);
>
>        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);
> +      block = gimple_phi_arg_block_from_edge (stmt, loop_latch_edge (loop));
> +      add_phi_arg (phi, def, end, locus, block);
>      }
>    e = redirect_edge_and_branch (exit, nexit->dest);
>    PENDING_STMT (e) = NULL;
> Index: gcc/tree-eh.c
> ===================================================================
> --- gcc/tree-eh.c       (revision 189246)
> +++ gcc/tree-eh.c       (working copy)
> @@ -3853,13 +3853,15 @@
>           FOR_EACH_EDGE (e, ei, old_bb->preds)
>             {
>               location_t oloc;
> +             tree oblock;
>               tree oop;
>
>               if ((e->flags & EDGE_EH) == 0)
>                 continue;
>               oop = gimple_phi_arg_def (ophi, e->dest_idx);
>               oloc = gimple_phi_arg_location (ophi, e->dest_idx);
> -             redirect_edge_var_map_add (e, nresult, oop, oloc);
> +             oblock = gimple_phi_arg_block (ophi, e->dest_idx);
> +             redirect_edge_var_map_add (e, nresult, oop, oloc, oblock);
>             }
>         }
>        /* If we didn't find the PHI, but it's a VOP, remember to rename
> @@ -3874,8 +3876,9 @@
>         {
>           location_t nloc
>             = gimple_phi_arg_location (nphi, old_bb_out->dest_idx);
> +         tree nblock = gimple_phi_arg_block (nphi, old_bb_out->dest_idx);
>           FOR_EACH_EDGE (e, ei, old_bb->preds)
> -           redirect_edge_var_map_add (e, nresult, nop, nloc);
> +           redirect_edge_var_map_add (e, nresult, nop, nloc, nblock);
>         }
>      }
>
> Index: gcc/ipa-split.c
> ===================================================================
> --- gcc/ipa-split.c     (revision 189246)
> +++ gcc/ipa-split.c     (working copy)
> @@ -1286,7 +1286,8 @@
>                   /* When there is PHI, just update its value.  */
>                   if (TREE_CODE (retval) == SSA_NAME
>                       && !gsi_end_p (psi))
> -                   add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION);
> +                   add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION,
> +                                NULL);
>                   /* Otherwise update the return BB itself.
>                      find_return_bb allows at most one assignment to return value,
>                      so update first statement.  */
> Index: gcc/tree-vect-loop.c
> ===================================================================
> --- gcc/tree-vect-loop.c        (revision 189246)
> +++ gcc/tree-vect-loop.c        (working copy)
> @@ -3131,9 +3131,9 @@
>                                                     NULL));
>
>    /* Set the arguments of the phi node:  */
> -  add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
> +  add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION, NULL);
>    add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop),
> -              UNKNOWN_LOCATION);
> +              UNKNOWN_LOCATION, NULL);
>
>
>    /* In case that vectorization factor (VF) is bigger than the number
> @@ -3617,13 +3617,13 @@
>          {
>            /* Set the loop-entry arg of the reduction-phi.  */
>            add_phi_arg (phi, vec_init_def, loop_preheader_edge (loop),
> -                       UNKNOWN_LOCATION);
> +                       UNKNOWN_LOCATION, NULL);
>
>            /* Set the loop-latch arg for the reduction-phi.  */
>            if (j > 0)
>              def = vect_get_vec_def_for_stmt_copy (vect_unknown_def_type, def);
>
> -          add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
> +          add_phi_arg (phi, def, loop_latch_edge (loop),
> UNKNOWN_LOCATION, NULL);
>
>            if (vect_print_dump_info (REPORT_DETAILS))
>              {
> @@ -4241,9 +4241,10 @@
>                    /* Update phi node arguments with vs0 and vs2.  */
>                    add_phi_arg (vect_phi, vect_phi_init,
>                                 loop_preheader_edge (outer_loop),
> -                               UNKNOWN_LOCATION);
> +                               UNKNOWN_LOCATION, NULL);
>                    add_phi_arg (vect_phi, PHI_RESULT (inner_phi),
> -                               loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
> +                               loop_latch_edge (outer_loop), UNKNOWN_LOCATION,
> +                              NULL);
>                    if (vect_print_dump_info (REPORT_DETAILS))
>                      {
>                        fprintf (vect_dump, "created double reduction phi "
> Index: gcc/tree-flow-inline.h
> ===================================================================
> --- gcc/tree-flow-inline.h      (revision 189246)
> +++ gcc/tree-flow-inline.h      (working copy)
> @@ -483,6 +483,22 @@
>    return gimple_phi_arg (gs, e->dest_idx)->locus;
>  }
>
> +/* Return the block location of gimple argument I of phi node GS.  */
> +
> +static inline tree
> +gimple_phi_arg_block (gimple gs, size_t i)
> +{
> +  return gimple_phi_arg (gs, i)->block;
> +}
> +
> +/* Return the block location of the argument on edge E of phi node GS.  */
> +
> +static inline tree
> +gimple_phi_arg_block_from_edge (gimple gs, edge e)
> +{
> +  return gimple_phi_arg (gs, e->dest_idx)->block;
> +}
> +
>  /* Set the source location of gimple argument I of phi node GS to LOC.  */
>
>  static inline void
> @@ -491,6 +507,14 @@
>    gimple_phi_arg (gs, i)->locus = loc;
>  }
>
> +/* Set the block location of gimple argument I of phi node GS to BLOCK.  */
> +
> +static inline void
> +gimple_phi_arg_set_block (gimple gs, size_t i, tree block)
> +{
> +  gimple_phi_arg (gs, i)->block = block;
> +}
> +
>  /* Return TRUE if argument I of phi node GS has a location record.  */
>
>  static inline bool
> @@ -499,6 +523,13 @@
>    return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
>  }
>
> +/* Return TRUE if argument I of phi node GS has a location record.  */
> +
> +static inline bool
> +gimple_phi_arg_has_block (gimple gs, size_t i)
> +{
> +  return gimple_phi_arg_block (gs, i) != NULL;
> +}
>
>  /* Return the PHI nodes for basic block BB, or NULL if there are no
>     PHI nodes.  */
> @@ -1217,6 +1248,13 @@
>    return v->locus;
>  }
>
> +/* Given an edge_var_map V, return the PHI arg location.  */
> +
> +static inline tree
> +redirect_edge_var_map_block (edge_var_map *v)
> +{
> +  return v->block;
> +}
>
>  /* Return an SSA_NAME node for variable VAR defined in statement STMT
>     in function cfun.  */
> Index: gcc/tree-vect-data-refs.c
> ===================================================================
> --- gcc/tree-vect-data-refs.c   (revision 189246)
> +++ gcc/tree-vect-data-refs.c   (working copy)
> @@ -4407,7 +4407,7 @@
>    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, UNKNOWN_LOCATION);
> +  add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION, NULL);
>
>    return msq;
>  }
> Index: gcc/graphite-scop-detection.c
> ===================================================================
> --- gcc/graphite-scop-detection.c       (revision 189246)
> +++ gcc/graphite-scop-detection.c       (working copy)
> @@ -1331,7 +1331,7 @@
>                                           gimple_phi_result_ptr (close_phi));
>                 add_phi_arg (close_phi, arg,
>                              gimple_phi_arg_edge (close_phi, 0),
> -                            UNKNOWN_LOCATION);
> +                            UNKNOWN_LOCATION, NULL);
>                 use_p = gimple_phi_arg_imm_use_ptr (phi, i);
>                 replace_exp (use_p, res);
>                 update_stmt (phi);
> Index: gcc/tree-ssa-phiopt.c
> ===================================================================
> --- gcc/tree-ssa-phiopt.c       (revision 189246)
> +++ gcc/tree-ssa-phiopt.c       (working copy)
> @@ -1454,6 +1454,7 @@
>    gimple newphi, new_stmt;
>    gimple_stmt_iterator gsi;
>    source_location locus;
> +  tree block;
>
>    /* Check if middle_bb contains of only one store.  */
>    if (!assign
> @@ -1461,6 +1462,7 @@
>      return false;
>
>    locus = gimple_location (assign);
> +  block = gimple_block (assign);
>    lhs = gimple_assign_lhs (assign);
>    rhs = gimple_assign_rhs1 (assign);
>    if (TREE_CODE (lhs) != MEM_REF
> @@ -1494,14 +1496,15 @@
>    name = make_ssa_name (condstoretemp, new_stmt);
>    gimple_assign_set_lhs (new_stmt, name);
>    gimple_set_location (new_stmt, locus);
> +  gimple_set_block (new_stmt, block);
>    gsi_insert_on_edge (e1, new_stmt);
>
>    /* 4) Create a PHI node at the join block, with one argument
>          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, locus);
> -  add_phi_arg (newphi, name, e1, locus);
> +  add_phi_arg (newphi, rhs, e0, locus, block);
> +  add_phi_arg (newphi, name, e1, locus, block);
>
>    lhs = unshare_expr (lhs);
>    new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
> @@ -1528,6 +1531,7 @@
>  {
>    tree lhs_base, lhs, then_rhs, else_rhs;
>    source_location then_locus, else_locus;
> +  tree then_block, else_block;
>    gimple_stmt_iterator gsi;
>    gimple newphi, new_stmt;
>
> @@ -1553,6 +1557,8 @@
>    else_rhs = gimple_assign_rhs1 (else_assign);
>    then_locus = gimple_location (then_assign);
>    else_locus = gimple_location (else_assign);
> +  then_block = gimple_block (then_assign);
> +  else_block = gimple_block (else_assign);
>
>    /* Now we've checked the constraints, so do the transformation:
>       1) Remove the stores.  */
> @@ -1576,8 +1582,10 @@
>         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, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
> -  add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
> +  add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus,
> +              then_block);
> +  add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus,
> +              else_block);
>
>    new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
>
> Index: gcc/tree-cfgcleanup.c
> ===================================================================
> --- gcc/tree-cfgcleanup.c       (revision 189246)
> +++ gcc/tree-cfgcleanup.c       (working copy)
> @@ -444,7 +444,9 @@
>             {
>               gimple phi = gsi_stmt (gsi);
>               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);
> +             tree b = gimple_phi_arg_block_from_edge (phi, succ);
> +             add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l,
> +                          b);
>             }
>         }
>      }
> @@ -871,6 +873,7 @@
>           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);
> +         tree block = gimple_phi_arg_block_from_edge (phi, succ);
>
>           if (TREE_CODE (def) == SSA_NAME)
>             {
> @@ -891,12 +894,13 @@
>                     {
>                       def = new_arg;
>                       locus = redirect_edge_var_map_location (vm);
> +                     block = redirect_edge_var_map_block (vm);
>                       break;
>                     }
>                 }
>             }
>
> -         add_phi_arg (phi, def, s, locus);
> +         add_phi_arg (phi, def, s, locus, block);
>         }
>
>        redirect_edge_var_map_clear (e);
> Index: gcc/tree-ssa-pre.c
> ===================================================================
> --- gcc/tree-ssa-pre.c  (revision 189246)
> +++ gcc/tree-ssa-pre.c  (working copy)
> @@ -3403,10 +3403,10 @@
>        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, UNKNOWN_LOCATION);
> +       add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION, NULL);
>        else
>         add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
> -                    UNKNOWN_LOCATION);
> +                    UNKNOWN_LOCATION, NULL);
>      }
>
>    newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
> Index: gcc/tree-ssa-live.c
> ===================================================================
> --- gcc/tree-ssa-live.c (revision 189246)
> +++ gcc/tree-ssa-live.c (working copy)
> @@ -765,6 +765,10 @@
>            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
>              {
>               tree arg = USE_FROM_PTR (arg_p);
> +             int index = PHI_ARG_INDEX_FROM_USE (arg_p);
> +             tree block = gimple_phi_arg_block (phi, index);
> +             if (block != NULL)
> +               TREE_USED (block) = true;
>               mark_all_vars_used (&arg, global_unused_vars);
>              }
>          }
> Index: gcc/tree-predcom.c
> ===================================================================
> --- gcc/tree-predcom.c  (revision 189246)
> +++ gcc/tree-predcom.c  (working copy)
> @@ -1531,8 +1531,8 @@
>
>        phi = create_phi_node (var, loop->header);
>        SSA_NAME_DEF_STMT (var) = phi;
> -      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
> -      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION, NULL);
> +      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION, NULL);
>      }
>  }
>
> @@ -1595,8 +1595,8 @@
>        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, UNKNOWN_LOCATION);
> -      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION, NULL);
> +      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION, NULL);
>      }
>    else
>      {
> Index: gcc/sese.c
> ===================================================================
> --- gcc/sese.c  (revision 189246)
> +++ gcc/sese.c  (working copy)
> @@ -349,8 +349,8 @@
>
>    create_new_def_for (gimple_phi_result (phi), phi,
>                       gimple_phi_result_ptr (phi));
> -  add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION);
> -  add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION);
> +  add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION, NULL);
> +  add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION, NULL);
>  }
>
>  /* Insert in the block BB phi nodes for variables defined in REGION
> Index: gcc/tree-ssa-dce.c
> ===================================================================
> --- gcc/tree-ssa-dce.c  (revision 189246)
> +++ gcc/tree-ssa-dce.c  (working copy)
> @@ -1129,6 +1129,7 @@
>           gimple phi = gsi_stmt (gsi);
>           tree op;
>           source_location locus;
> +         tree block;
>
>           /* PHIs for virtuals have no control dependency relation on them.
>              We are lost here and must force renaming of the symbol.  */
> @@ -1148,7 +1149,8 @@
>
>           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);
> +         block = gimple_phi_arg_block (phi, e2->dest_idx);
> +         add_phi_arg (phi, op, e, locus, block);
>           /* The resulting PHI if not dead can only be degenerate.  */
>           gcc_assert (degenerate_phi_p (phi));
>           gsi_next (&gsi);
> Index: gcc/tree-ssa.c
> ===================================================================
> --- gcc/tree-ssa.c      (revision 189246)
> +++ gcc/tree-ssa.c      (working copy)
> @@ -51,7 +51,8 @@
>  /* 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,
> source_location locus)
> +redirect_edge_var_map_add (edge e, tree result, tree def,
> source_location locus,
> +                          tree block)
>  {
>    void **slot;
>    edge_var_map_vector old_head, head;
> @@ -70,6 +71,7 @@
>    new_node.def = def;
>    new_node.result = result;
>    new_node.locus = locus;
> +  new_node.block = block;
>
>    VEC_safe_push (edge_var_map, heap, head, &new_node);
>    if (old_head != head)
> @@ -193,15 +195,17 @@
>      {
>        tree def;
>        source_location locus ;
> +      tree block;
>
>        phi = gsi_stmt (gsi);
>        def = gimple_phi_arg_def (phi, e->dest_idx);
>        locus = gimple_phi_arg_location (phi, e->dest_idx);
> +      block = gimple_phi_arg_block (phi, e->dest_idx);
>
>        if (def == NULL_TREE)
>         continue;
>
> -      redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
> +      redirect_edge_var_map_add (e, gimple_phi_result (phi), def,
> locus, block);
>      }
>
>    e = redirect_edge_succ_nodup (e, dest);
> @@ -234,7 +238,8 @@
>
>        phi = gsi_stmt (gsi);
>        def = redirect_edge_var_map_def (vm);
> -      add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
> +      add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm),
> +                  redirect_edge_var_map_block (vm));
>      }
>
>    redirect_edge_var_map_clear (e);
> Index: gcc/gimple-streamer-in.c
> ===================================================================
> --- gcc/gimple-streamer-in.c    (revision 189246)
> +++ gcc/gimple-streamer-in.c    (working copy)
> @@ -67,7 +67,7 @@
>             break;
>           }
>
> -      add_phi_arg (result, def, e, arg_loc);
> +      add_phi_arg (result, def, e, arg_loc, NULL);
>      }
>
>    return result;
> Index: gcc/tree-vect-stmts.c
> ===================================================================
> --- gcc/tree-vect-stmts.c       (revision 189246)
> +++ gcc/tree-vect-stmts.c       (working copy)
> @@ -5117,7 +5117,7 @@
>                       if (i == vec_num - 1 && j == ncopies - 1)
>                         add_phi_arg (phi, lsq,
>                                      loop_latch_edge (containing_loop),
> -                                    UNKNOWN_LOCATION);
> +                                    UNKNOWN_LOCATION, NULL);
>                       msq = lsq;
>                     }
>                 }
> Index: gcc/tree-inline.c
> ===================================================================
> --- gcc/tree-inline.c   (revision 189246)
> +++ gcc/tree-inline.c   (working copy)
> @@ -2019,6 +2019,7 @@
>               tree arg;
>               tree new_arg;
>               tree block = id->block;
> +             tree arg_block, *n;
>               edge_iterator ei2;
>
>               /* When doing partial cloning, we allow PHIs on the entry block
> @@ -2046,8 +2047,15 @@
>                   gsi_insert_seq_on_edge (new_edge, stmts);
>                   inserted = true;
>                 }
> +             n = (tree *) pointer_map_contains (id->decl_map,
> +               gimple_phi_arg_block_from_edge (phi, old_edge));
> +             if (n)
> +               arg_block = *n;
> +             else
> +               arg_block = NULL;
>               add_phi_arg (new_phi, new_arg, new_edge,
> -                          gimple_phi_arg_location_from_edge (phi, old_edge));
> +                          gimple_phi_arg_location_from_edge (phi, old_edge),
> +                          arg_block);
>             }
>         }
>      }
> Index: gcc/tree-ssa-phiprop.c
> ===================================================================
> --- gcc/tree-ssa-phiprop.c      (revision 189246)
> +++ gcc/tree-ssa-phiprop.c      (working copy)
> @@ -159,9 +159,11 @@
>        tree old_arg, new_var;
>        gimple tmp;
>        source_location locus;
> +      tree block;
>
>        old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
>        locus = gimple_phi_arg_location_from_edge (phi, e);
> +      block = gimple_phi_arg_block_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))
> @@ -169,6 +171,7 @@
>           gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
>           old_arg = gimple_assign_rhs1 (def_stmt);
>           locus = gimple_location (def_stmt);
> +         block = gimple_block (def_stmt);
>         }
>
>        if (TREE_CODE (old_arg) == SSA_NAME)
> @@ -203,6 +206,7 @@
>           new_var = make_ssa_name (new_var, tmp);
>           gimple_assign_set_lhs (tmp, new_var);
>           gimple_set_location (tmp, locus);
> +         gimple_set_block (tmp, block);
>
>           gsi_insert_on_edge (e, tmp);
>           update_stmt (tmp);
> @@ -216,7 +220,7 @@
>             }
>         }
>
> -      add_phi_arg (new_phi, new_var, e, locus);
> +      add_phi_arg (new_phi, new_var, e, locus, block);
>      }
>
>    update_stmt (new_phi);
> Index: gcc/tree-outof-ssa.c
> ===================================================================
> --- gcc/tree-outof-ssa.c        (revision 189246)
> +++ gcc/tree-outof-ssa.c        (working copy)
> @@ -78,6 +78,9 @@
>    /* Source locus on each edge */
>    VEC(source_location,heap) *edge_locus;
>
> +  /* Block location on each edge.  */
> +  VEC(tree,heap) *edge_block;
> +
>    /* Visited vector.  */
>    sbitmap visited;
>
> @@ -96,6 +99,9 @@
>
>    /* Source locations for any constant copies.  */
>    VEC(source_location,heap) *copy_locus;
> +
> +  /* Block locations for any constant copies.  */
> +  VEC(tree,heap) *copy_block;
>  } *elim_graph;
>
>
> @@ -174,7 +180,8 @@
>  /* 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,
> source_location locus)
> +insert_partition_copy_on_edge (edge e, int dest, int src,
> source_location locus,
> +                              tree block)
>  {
>    tree var;
>    rtx seq;
> @@ -194,7 +201,10 @@
>    set_location_for_edge (e);
>    /* If a locus is provided, override the default.  */
>    if (locus)
> -    set_curr_insn_source_location (locus);
> +    {
> +      set_curr_insn_source_location (locus);
> +      set_curr_insn_block (block);
> +    }
>
>    var = partition_to_var (SA.map, src);
>    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
> @@ -209,7 +219,8 @@
>     onto edge E.  */
>
>  static void
> -insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
> +insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus,
> +                          tree block)
>  {
>    rtx seq, x;
>    enum machine_mode dest_mode, src_mode;
> @@ -231,7 +242,10 @@
>    set_location_for_edge (e);
>    /* If a locus is provided, override the default.  */
>    if (locus)
> -    set_curr_insn_source_location (locus);
> +    {
> +      set_curr_insn_source_location (locus);
> +      set_curr_insn_block (block);
> +    }
>
>    start_sequence ();
>
> @@ -269,7 +283,7 @@
>
>  static void
>  insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
> -                           source_location locus)
> +                           source_location locus, tree block)
>  {
>    rtx seq;
>    if (dump_file && (dump_flags & TDF_DETAILS))
> @@ -287,7 +301,10 @@
>    set_location_for_edge (e);
>    /* If a locus is provided, override the default.  */
>    if (locus)
> -    set_curr_insn_source_location (locus);
> +    {
> +      set_curr_insn_source_location (locus);
> +      set_curr_insn_block (block);
> +    }
>
>    /* We give the destination as sizeexp in case src/dest are BLKmode
>       mems.  Usually we give the source.  As we result from SSA names
> @@ -304,7 +321,8 @@
>     onto edge E.  */
>
>  static void
> -insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
> +insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus,
> +                           tree block)
>  {
>    tree var;
>    rtx seq;
> @@ -323,7 +341,10 @@
>    set_location_for_edge (e);
>    /* If a locus is provided, override the default.  */
>    if (locus)
> -    set_curr_insn_source_location (locus);
> +    {
> +      set_curr_insn_source_location (locus);
> +      set_curr_insn_block (block);
> +    }
>
>    var = partition_to_var (SA.map, src);
>    seq = emit_partition_copy (dest,
> @@ -347,8 +368,10 @@
>    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->copy_block = VEC_alloc (tree, heap, 10);
>    g->edge_list = VEC_alloc (int, heap, 20);
>    g->edge_locus = VEC_alloc (source_location, heap, 10);
> +  g->edge_block = VEC_alloc (tree, heap, 10);
>    g->stack = VEC_alloc (int, heap, 30);
>
>    g->visited = sbitmap_alloc (size);
> @@ -365,6 +388,7 @@
>    VEC_truncate (int, g->nodes, 0);
>    VEC_truncate (int, g->edge_list, 0);
>    VEC_truncate (source_location, g->edge_locus, 0);
> +  VEC_truncate (tree, g->edge_block, 0);
>  }
>
>
> @@ -380,7 +404,9 @@
>    VEC_free (int, heap, g->const_dests);
>    VEC_free (int, heap, g->nodes);
>    VEC_free (source_location, heap, g->copy_locus);
> +  VEC_free (tree, heap, g->copy_block);
>    VEC_free (source_location, heap, g->edge_locus);
> +  VEC_free (tree, heap, g->edge_block);
>
>    free (g);
>  }
> @@ -413,11 +439,13 @@
>  /* Add the edge PRED->SUCC to graph G.  */
>
>  static inline void
> -elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus)
> +elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus,
> +                    tree block)
>  {
>    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);
> +  VEC_safe_push (tree, heap, g->edge_block, block);
>  }
>
>
> @@ -425,7 +453,8 @@
>     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, source_location *locus)
> +elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus,
> +                            tree *block)
>  {
>    int y;
>    unsigned x;
> @@ -437,9 +466,12 @@
>         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);
> +       *block = VEC_index (tree, g->edge_block, x / 2);
> +       VEC_replace (tree, g->edge_block, x / 2, NULL);
>         return y;
>        }
>    *locus = UNKNOWN_LOCATION;
> +  *block = NULL;
>    return -1;
>  }
>
> @@ -448,7 +480,7 @@
>     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, LOCUS, CODE)                \
> +#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, BLOCK, CODE) \
>  do {                                                                   \
>    unsigned x_;                                                         \
>    int y_;                                                              \
> @@ -460,6 +492,8 @@
>        (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1));    \
>        (void) ((LOCUS) = VEC_index (source_location,                    \
>                                    (GRAPH)->edge_locus, x_ / 2));       \
> +      (void) ((BLOCK) = VEC_index (tree,                               \
> +                                  (GRAPH)->edge_block, x_ / 2));       \
>        CODE;                                                            \
>      }                                                                  \
>  } while (0)
> @@ -469,7 +503,7 @@
>     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, LOCUS, CODE)                \
> +#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, BLOCK, CODE) \
>  do {                                                                   \
>    unsigned x_;                                                         \
>    int y_;                                                              \
> @@ -481,6 +515,8 @@
>        (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_));                \
>        (void) ((LOCUS) = VEC_index (source_location,                    \
>                                    (GRAPH)->edge_locus, x_ / 2));       \
> +      (void) ((BLOCK) = VEC_index (tree,                               \
> +                                  (GRAPH)->edge_block, x_ / 2));       \
>        CODE;                                                            \
>      }                                                                  \
>  } while (0)
> @@ -511,6 +547,7 @@
>      {
>        gimple phi = gsi_stmt (gsi);
>        source_location locus;
> +      tree block;
>
>        p0 = var_to_partition (g->map, gimple_phi_result (phi));
>        /* Ignore results which are not in partitions.  */
> @@ -519,6 +556,7 @@
>
>        Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
>        locus = gimple_phi_arg_location_from_edge (phi, g->e);
> +      block = gimple_phi_arg_block_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
> @@ -532,6 +570,7 @@
>           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);
> +         VEC_safe_push (tree, heap, g->copy_block, block);
>         }
>        else
>          {
> @@ -540,7 +579,7 @@
>             {
>               eliminate_name (g, p0);
>               eliminate_name (g, pi);
> -             elim_graph_add_edge (g, p0, pi, locus);
> +             elim_graph_add_edge (g, p0, pi, locus, block);
>             }
>         }
>      }
> @@ -554,9 +593,10 @@
>  {
>    int S;
>    source_location locus;
> +  tree block;
>
>    SET_BIT (g->visited, T);
> -  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
> +  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, block,
>      {
>        if (!TEST_BIT (g->visited, S))
>          elim_forward (g, S);
> @@ -572,8 +612,9 @@
>  {
>    int P;
>    source_location locus;
> +  tree block;
>
> -  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
> +  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
>      {
>        if (!TEST_BIT (g->visited, P))
>          return 1;
> @@ -588,14 +629,15 @@
>  {
>    int P;
>    source_location locus;
> +  tree block;
>
>    SET_BIT (g->visited, T);
> -  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
> +  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
>      {
>        if (!TEST_BIT (g->visited, P))
>          {
>           elim_backward (g, P);
> -         insert_partition_copy_on_edge (g->e, P, T, locus);
> +         insert_partition_copy_on_edge (g->e, P, T, locus, block);
>         }
>      });
>  }
> @@ -624,6 +666,7 @@
>  {
>    int P, S;
>    source_location locus;
> +  tree block;
>
>    if (elim_unvisited_predecessor (g, T))
>      {
> @@ -631,23 +674,24 @@
>        rtx U = get_temp_reg (var);
>        int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
>
> -      insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
> -      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
> +      insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION, NULL);
> +      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
>         {
>           if (!TEST_BIT (g->visited, P))
>             {
>               elim_backward (g, P);
> -             insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
> +             insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus,
> +                                         block);
>             }
>         });
>      }
>    else
>      {
> -      S = elim_graph_remove_succ_edge (g, T, &locus);
> +      S = elim_graph_remove_succ_edge (g, T, &locus, &block);
>        if (S != -1)
>         {
>           SET_BIT (g->visited, T);
> -         insert_partition_copy_on_edge (g->e, T, S, locus);
> +         insert_partition_copy_on_edge (g->e, T, S, locus, block);
>         }
>      }
>  }
> @@ -662,6 +706,7 @@
>
>    gcc_assert (VEC_length (tree, g->const_copies) == 0);
>    gcc_assert (VEC_length (source_location, g->copy_locus) == 0);
> +  gcc_assert (VEC_length (tree, g->copy_block) == 0);
>
>    /* Abnormal edges already have everything coalesced.  */
>    if (e->flags & EDGE_ABNORMAL)
> @@ -699,11 +744,13 @@
>        int dest;
>        tree src;
>        source_location locus;
> +      tree block;
>
>        src = VEC_pop (tree, g->const_copies);
>        dest = VEC_pop (int, g->const_dests);
>        locus = VEC_pop (source_location, g->copy_locus);
> -      insert_value_copy_on_edge (e, dest, src, locus);
> +      block = VEC_pop (tree, g->copy_block);
> +      insert_value_copy_on_edge (e, dest, src, locus, block);
>      }
>  }
>
> @@ -1088,8 +1135,12 @@
>
>                   /* copy location if present.  */
>                   if (gimple_phi_arg_has_location (phi, i))
> -                   gimple_set_location (stmt,
> -                                        gimple_phi_arg_location (phi, i));
> +                   {
> +                     gimple_set_location (stmt,
> +                                          gimple_phi_arg_location (phi, i));
> +                     gimple_set_block (stmt,
> +                                       gimple_phi_arg_block (phi, i));
> +                   }
>
>                   /* Insert the new statement into the block and update
>                      the PHI node.  */
> Index: gcc/tree-flow.h
> ===================================================================
> --- gcc/tree-flow.h     (revision 189246)
> +++ gcc/tree-flow.h     (working copy)
> @@ -506,7 +506,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 create_phi_node (tree, basic_block);
> -extern void add_phi_arg (gimple, tree, edge, source_location);
> +extern void add_phi_arg (gimple, tree, edge, source_location, tree);
>  extern void remove_phi_args (edge);
>  extern void remove_phi_node (gimple_stmt_iterator *, bool);
>  extern void remove_phi_nodes (basic_block);
> @@ -530,6 +530,7 @@
>    tree result;                 /* PHI result.  */
>    tree def;                    /* PHI arg definition.  */
>    source_location locus;        /* PHI arg location.  */
> +  tree block;                  /* PHI arg block.  */
>  };
>  typedef struct _edge_var_map edge_var_map;
>
> @@ -540,7 +541,7 @@
>  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, source_location);
> +extern void redirect_edge_var_map_add (edge, tree, tree,
> source_location, tree);
>  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);
> Index: gcc/tree-switch-conversion.c
> ===================================================================
> --- gcc/tree-switch-conversion.c        (revision 189246)
> +++ gcc/tree-switch-conversion.c        (working copy)
> @@ -1189,8 +1189,10 @@
>         !gsi_end_p (gsi); gsi_next (&gsi), i++)
>      {
>        gimple phi = gsi_stmt (gsi);
> -      add_phi_arg (phi, info->target_inbound_names[i], e1f, UNKNOWN_LOCATION);
> -      add_phi_arg (phi, info->target_outbound_names[i], e2f, UNKNOWN_LOCATION);
> +      add_phi_arg (phi, info->target_inbound_names[i], e1f, UNKNOWN_LOCATION,
> +                  NULL);
> +      add_phi_arg (phi, info->target_outbound_names[i], e2f, UNKNOWN_LOCATION,
> +                  NULL);
>      }
>  }
>
> Index: gcc/tree-cfg.c
> ===================================================================
> --- gcc/tree-cfg.c      (revision 189246)
> +++ gcc/tree-cfg.c      (working copy)
> @@ -2554,7 +2554,8 @@
>
>        gcc_assert (result == gimple_phi_result (phi));
>
> -      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
> +      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm),
> +                  redirect_edge_var_map_block (vm));
>      }
>
>    redirect_edge_var_map_clear (old_edge);
> @@ -5014,7 +5015,7 @@
>        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,
> -                  UNKNOWN_LOCATION);
> +                  UNKNOWN_LOCATION, NULL);
>      }
>
>    /* Add the arguments we have stored on edges.  */
> @@ -5475,7 +5476,8 @@
>        phi_copy = gsi_stmt (psi_copy);
>        def = PHI_ARG_DEF_FROM_EDGE (phi, e);
>        add_phi_arg (phi_copy, def, e_copy,
> -                  gimple_phi_arg_location_from_edge (phi, e));
> +                  gimple_phi_arg_location_from_edge (phi, e),
> +                  gimple_phi_arg_block_from_edge (phi, e));
>      }
>  }
>
> @@ -5850,7 +5852,8 @@
>           {
>             phi = gsi_stmt (psi);
>             def = PHI_ARG_DEF (phi, nexits[0]->dest_idx);
> -           add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e));
> +           add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e),
> +                        gimple_phi_arg_block_from_edge (phi, e));
>           }
>        }
>    e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
> @@ -7426,7 +7429,8 @@
>        phi1 = gsi_stmt (psi1);
>        phi2 = gsi_stmt (psi2);
>        def = PHI_ARG_DEF (phi2, e2->dest_idx);
> -      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
> +      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2),
> +                  gimple_phi_arg_block_from_edge (phi2, e2));
>      }
>  }
Steven Bosscher July 5, 2012, 9:42 a.m. UTC | #2
On Thu, Jul 5, 2012 at 11:23 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Thu, Jul 5, 2012 at 11:08 AM, Dehao Chen <dehao@google.com> wrote:
>> Hi,
>>
>> This patch added block field to phi_arg_d to make sure the associated
>> source locus is consistent with its block info.
>>
>> Bootstrapped and passed gcc regression tests.
>>
>> OK for trunk?
>
> Hum - makes me want a location like we have on RTL (which maps to
> location plus block ...).  But oh well ...
>
> struct GTY(()) phi_arg_d {
>   /* imm_use MUST be the first element in struct because we do some
>      pointer arithmetic with it.  See phi_arg_index_from_use.  */
>   struct ssa_use_operand_d imm_use;
> location_t locus;
> +  tree block;
>  };
>
> please place block before locus though.
>
> Ok with that change.

Ehm, wait a moment, please -- does this have to be a tree pointer? Why
not use BLOCK_NUMBER instead? Adding a pointer to such a
frequently-used structure should be avoided if an int suffices.

Ciao!
Steven
Richard Biener July 5, 2012, 9:58 a.m. UTC | #3
On Thu, Jul 5, 2012 at 11:42 AM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> On Thu, Jul 5, 2012 at 11:23 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Thu, Jul 5, 2012 at 11:08 AM, Dehao Chen <dehao@google.com> wrote:
>>> Hi,
>>>
>>> This patch added block field to phi_arg_d to make sure the associated
>>> source locus is consistent with its block info.
>>>
>>> Bootstrapped and passed gcc regression tests.
>>>
>>> OK for trunk?
>>
>> Hum - makes me want a location like we have on RTL (which maps to
>> location plus block ...).  But oh well ...
>>
>> struct GTY(()) phi_arg_d {
>>   /* imm_use MUST be the first element in struct because we do some
>>      pointer arithmetic with it.  See phi_arg_index_from_use.  */
>>   struct ssa_use_operand_d imm_use;
>> location_t locus;
>> +  tree block;
>>  };
>>
>> please place block before locus though.
>>
>> Ok with that change.
>
> Ehm, wait a moment, please -- does this have to be a tree pointer? Why
> not use BLOCK_NUMBER instead? Adding a pointer to such a
> frequently-used structure should be avoided if an int suffices.

Well, we re-number blocks frequently enough that this won't work.  In
gimple stmts there is also a block tree pointer.  The real solution would
of course be to associate location_t with a block, too, like the source locus
on RTL does.  It will also be fun do deal with during inlining and LTO
streaming.

Richard.

> Ciao!
> Steven
Dehao Chen July 5, 2012, 10:17 a.m. UTC | #4
On Thu, Jul 5, 2012 at 5:58 PM, Richard Guenther
<richard.guenther@gmail.com> wrote:
>
> On Thu, Jul 5, 2012 at 11:42 AM, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> > On Thu, Jul 5, 2012 at 11:23 AM, Richard Guenther
> > <richard.guenther@gmail.com> wrote:
> >> On Thu, Jul 5, 2012 at 11:08 AM, Dehao Chen <dehao@google.com> wrote:
> >>> Hi,
> >>>
> >>> This patch added block field to phi_arg_d to make sure the associated
> >>> source locus is consistent with its block info.
> >>>
> >>> Bootstrapped and passed gcc regression tests.
> >>>
> >>> OK for trunk?
> >>
> >> Hum - makes me want a location like we have on RTL (which maps to
> >> location plus block ...).  But oh well ...
> >>
> >> struct GTY(()) phi_arg_d {
> >>   /* imm_use MUST be the first element in struct because we do some
> >>      pointer arithmetic with it.  See phi_arg_index_from_use.  */
> >>   struct ssa_use_operand_d imm_use;
> >> location_t locus;
> >> +  tree block;
> >>  };
> >>
> >> please place block before locus though.
> >>
> >> Ok with that change.
> >
> > Ehm, wait a moment, please -- does this have to be a tree pointer? Why
> > not use BLOCK_NUMBER instead? Adding a pointer to such a
> > frequently-used structure should be avoided if an int suffices.
>
> Well, we re-number blocks frequently enough that this won't work.  In
> gimple stmts there is also a block tree pointer.  The real solution would
> of course be to associate location_t with a block, too, like the source locus
> on RTL does.  It will also be fun do deal with during inlining and LTO
> streaming.

Yeah, I agree that we should have a uniformed way to represent locus,
discriminator and block together. But as you mentioned, updating it
would be non-trivial since blocks are updated regularly (I'm wondering
why we need to eliminate redundant blocks all the time, just for
saving space?). But anyway, this patch can at least ensure consist
debug info. Shall we get it into trunk?

Thanks,
Dehao

>
> Richard.
>
> > Ciao!
> > Steven
Richard Biener July 5, 2012, 12:10 p.m. UTC | #5
On Thu, Jul 5, 2012 at 12:15 PM, Dehao Chen <dehao@google.com> wrote:
>
> On Thu, Jul 5, 2012 at 5:58 PM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>>
>> On Thu, Jul 5, 2012 at 11:42 AM, Steven Bosscher <stevenb.gcc@gmail.com>
>> wrote:
>> > On Thu, Jul 5, 2012 at 11:23 AM, Richard Guenther
>> > <richard.guenther@gmail.com> wrote:
>> >> On Thu, Jul 5, 2012 at 11:08 AM, Dehao Chen <dehao@google.com> wrote:
>> >>> Hi,
>> >>>
>> >>> This patch added block field to phi_arg_d to make sure the associated
>> >>> source locus is consistent with its block info.
>> >>>
>> >>> Bootstrapped and passed gcc regression tests.
>> >>>
>> >>> OK for trunk?
>> >>
>> >> Hum - makes me want a location like we have on RTL (which maps to
>> >> location plus block ...).  But oh well ...
>> >>
>> >> struct GTY(()) phi_arg_d {
>> >>   /* imm_use MUST be the first element in struct because we do some
>> >>      pointer arithmetic with it.  See phi_arg_index_from_use.  */
>> >>   struct ssa_use_operand_d imm_use;
>> >> location_t locus;
>> >> +  tree block;
>> >>  };
>> >>
>> >> please place block before locus though.
>> >>
>> >> Ok with that change.
>> >
>> > Ehm, wait a moment, please -- does this have to be a tree pointer? Why
>> > not use BLOCK_NUMBER instead? Adding a pointer to such a
>> > frequently-used structure should be avoided if an int suffices.
>>
>> Well, we re-number blocks frequently enough that this won't work.  In
>> gimple stmts there is also a block tree pointer.  The real solution would
>> of course be to associate location_t with a block, too, like the source
>> locus
>> on RTL does.  It will also be fun do deal with during inlining and LTO
>> streaming.
>
> Yeah, I agree that we should have a uniformed way to represent locus,
> discriminator and block together. But as you mentioned, updating it would be
> non-trivial since blocks are updated regularly (I'm wondering why we need to
> eliminate redundant blocks all the time, just for saving space?). But
> anyway, this patch can at least ensure consist debug info. Shall we get it
> into trunk?

I'd say yes.  But can you add a testcase at least that fails now and is
fixed with your patch?

Thanks,
Richard.
diff mbox

Patch

Index: gcc/tree-into-ssa.c
===================================================================
--- gcc/tree-into-ssa.c	(revision 189246)
+++ gcc/tree-into-ssa.c	(working copy)
@@ -1119,7 +1119,7 @@ 
 	     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, UNKNOWN_LOCATION);
+	    add_phi_arg (phi, var, e, UNKNOWN_LOCATION, NULL);
 	}
       else
 	{
@@ -1474,7 +1474,8 @@ 
 	  phi = gsi_stmt (gsi);
 	  currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
 	  stmt = SSA_NAME_DEF_STMT (currdef);
-	  add_phi_arg (phi, currdef, e, gimple_location (stmt));
+	  add_phi_arg (phi, currdef, e, gimple_location (stmt),
+		       gimple_block (stmt));
 	}
     }
 }
Index: gcc/tree-ssa-loop-im.c
===================================================================
--- gcc/tree-ssa-loop-im.c	(revision 189246)
+++ gcc/tree-ssa-loop-im.c	(working copy)
@@ -2086,7 +2086,7 @@ 
 	  if (gimple_phi_arg_edge (phi, i)->src == new_bb)
 	    {
 	      tree arg = gimple_phi_arg_def (phi, i);
-	      add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION);
+	      add_phi_arg (phi, arg, then_old_edge, UNKNOWN_LOCATION, NULL);
 	      update_stmt (phi);
 	    }
       }
Index: gcc/tree-ssa-tail-merge.c
===================================================================
--- gcc/tree-ssa-tail-merge.c	(revision 189246)
+++ gcc/tree-ssa-tail-merge.c	(working copy)
@@ -1458,7 +1458,7 @@ 
       bb2_phi = vop_phi (bb2);

       add_phi_arg (bb2_phi, SSA_NAME_VAR (gimple_phi_result (bb2_phi)),
-		   pred_edge, UNKNOWN_LOCATION);
+		   pred_edge, UNKNOWN_LOCATION, NULL);
     }

   bb2->frequency += bb1->frequency;
Index: gcc/tree-ssa-threadupdate.c
===================================================================
--- gcc/tree-ssa-threadupdate.c	(revision 189246)
+++ gcc/tree-ssa-threadupdate.c	(working copy)
@@ -316,7 +316,9 @@ 
     {
       gimple phi = gsi_stmt (gsi);
       source_location locus = gimple_phi_arg_location (phi, src_indx);
-      add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus);
+      tree block = gimple_phi_arg_block (phi, src_indx);
+      add_phi_arg (phi, gimple_phi_arg_def (phi, src_indx), tgt_e, locus,
+		   block);
     }
 }

Index: gcc/tree-loop-distribution.c
===================================================================
--- gcc/tree-loop-distribution.c	(revision 189246)
+++ gcc/tree-loop-distribution.c	(working copy)
@@ -171,6 +171,7 @@ 
     {
       tree def;
       source_location locus;
+      tree block;
       gimple phi_new = gsi_stmt (si_new);
       gimple phi_orig = gsi_stmt (si_orig);

@@ -178,12 +179,14 @@ 
 	 associated with the entry of NEW_LOOP)  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_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);
+      block = gimple_phi_arg_block_from_edge (phi_orig, orig_entry_e);
+      add_phi_arg (phi_new, def, new_loop_entry_e, locus, block);

       /* 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);
+      block = gimple_phi_arg_block_from_edge (phi_orig, orig_loop_latch);

       if (TREE_CODE (def) == SSA_NAME)
 	{
@@ -198,7 +201,8 @@ 
 	/* Could be an integer.  */
 	new_ssa_name = def;

-      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
+      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus,
+		   block);
     }
 }

Index: gcc/tree-ssa-loop-manip.c
===================================================================
--- gcc/tree-ssa-loop-manip.c	(revision 189246)
+++ gcc/tree-ssa-loop-manip.c	(working copy)
@@ -121,8 +121,9 @@ 

   stmt = create_phi_node (vb, loop->header);
   SSA_NAME_DEF_STMT (vb) = stmt;
-  add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION);
-  add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
+  add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION,
+	       NULL);
+  add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION, NULL);
 }

 /* Add exit phis for the USE on EXIT.  */
@@ -152,7 +153,7 @@ 
   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, UNKNOWN_LOCATION);
+    add_phi_arg (phi, use, e, UNKNOWN_LOCATION, NULL);
 }

 /* Add exit phis for VAR that is used in LIVEIN.
@@ -485,12 +486,14 @@ 
   use_operand_p op_p;
   gimple_stmt_iterator psi;
   source_location locus;
+  tree block;

   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));
+      block = gimple_phi_arg_block_from_edge (phi, single_succ_edge (bb));

       name = USE_FROM_PTR (op_p);

@@ -504,7 +507,7 @@ 
       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, locus);
+      add_phi_arg (new_phi, name, exit, locus, block);
       SET_USE (op_p, new_name);
     }

@@ -1024,8 +1027,8 @@ 
       phi_rest = create_phi_node (new_init, rest);
       SSA_NAME_DEF_STMT (new_init) = phi_rest;

-      add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION);
-      add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION);
+      add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION, NULL);
+      add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION, NULL);
       SET_USE (op, new_init);
     }

Index: gcc/value-prof.c
===================================================================
--- gcc/value-prof.c	(revision 189246)
+++ gcc/value-prof.c	(working copy)
@@ -1245,10 +1245,12 @@ 
       SSA_NAME_DEF_STMT (result) = phi;
       gimple_call_set_lhs (icall_stmt,
 			   make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
-      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
+      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION,
+		   NULL);
       gimple_call_set_lhs (dcall_stmt,
 			   make_ssa_name (SSA_NAME_VAR (result), dcall_stmt));
-      add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION);
+      add_phi_arg (phi, gimple_call_lhs (dcall_stmt), e_dj, UNKNOWN_LOCATION,
+		   NULL);
     }

   /* Build an EH edge for the direct call if necessary.  */
@@ -1476,10 +1478,12 @@ 
       SSA_NAME_DEF_STMT (result) = phi;
       gimple_call_set_lhs (vcall_stmt,
 			   make_ssa_name (SSA_NAME_VAR (result), vcall_stmt));
-      add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION);
+      add_phi_arg (phi, gimple_call_lhs (vcall_stmt), e_vj, UNKNOWN_LOCATION,
+		   NULL);
       gimple_call_set_lhs (icall_stmt,
 			   make_ssa_name (SSA_NAME_VAR (result), icall_stmt));
-      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION);
+      add_phi_arg (phi, gimple_call_lhs (icall_stmt), e_ij, UNKNOWN_LOCATION,
+		   NULL);
     }

   /* Because these are all string op builtins, they're all nothrow.  */
Index: gcc/tree-tailcall.c
===================================================================
--- gcc/tree-tailcall.c	(revision 189246)
+++ gcc/tree-tailcall.c	(working copy)
@@ -597,7 +597,7 @@ 
       break;

   gcc_assert (!gsi_end_p (gsi));
-  add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION);
+  add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION, NULL);
 }

 /* Creates a GIMPLE statement which computes the operation specified by
@@ -853,7 +853,7 @@ 
       phi = gsi_stmt (gsi);
       gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));

-      add_phi_arg (phi, arg, e, gimple_location (stmt));
+      add_phi_arg (phi, arg, e, gimple_location (stmt), gimple_block (stmt));
       gsi_next (&gsi);
     }

@@ -948,7 +948,7 @@ 
   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),
-	       UNKNOWN_LOCATION);
+	       UNKNOWN_LOCATION, NULL);
   return PHI_RESULT (phi);
 }

@@ -1012,7 +1012,7 @@ 
 		phi = create_phi_node (name, first);
 		SSA_NAME_DEF_STMT (name) = phi;
 		add_phi_arg (phi, new_name, single_pred_edge (first),
-			     EXPR_LOCATION (param));
+			     EXPR_LOCATION (param), NULL);
 	      }
 	  phis_constructed = true;
 	}
Index: gcc/tree.h
===================================================================
--- gcc/tree.h	(revision 189246)
+++ gcc/tree.h	(working copy)
@@ -2036,6 +2036,7 @@ 
   struct ssa_use_operand_d imm_use;
   tree def;
   location_t locus;
+  tree block;
 };

 
Index: gcc/tree-phinodes.c
===================================================================
--- gcc/tree-phinodes.c	(revision 189246)
+++ gcc/tree-phinodes.c	(working copy)
@@ -205,6 +205,7 @@ 
       use_operand_p  imm;

       gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
+      gimple_phi_arg_set_block (phi, i ,NULL);
       imm = gimple_phi_arg_imm_use_ptr (phi, i);
       imm->use = gimple_phi_arg_def_ptr (phi, i);
       imm->prev = NULL;
@@ -275,6 +276,7 @@ 
       use_operand_p imm;

       gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
+      gimple_phi_arg_set_block (new_phi, i, NULL);
       imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
       imm->use = gimple_phi_arg_def_ptr (new_phi, i);
       imm->prev = NULL;
@@ -362,7 +364,7 @@ 
    PHI points to the reallocated phi node when we return.  */

 void
-add_phi_arg (gimple phi, tree def, edge e, source_location locus)
+add_phi_arg (gimple phi, tree def, edge e, source_location locus, tree block)
 {
   basic_block bb = e->dest;

@@ -386,6 +388,7 @@ 

   SET_PHI_ARG_DEF (phi, e->dest_idx, def);
   gimple_phi_arg_set_location (phi, e->dest_idx, locus);
+  gimple_phi_arg_set_block (phi, e->dest_idx, block);
 }


@@ -417,6 +420,8 @@ 
       /* Move the location as well.  */
       gimple_phi_arg_set_location (phi, i,
 				   gimple_phi_arg_location (phi, num_elem - 1));
+      gimple_phi_arg_set_block (phi, i,
+				gimple_phi_arg_block (phi, num_elem - 1));
     }

   /* Shrink the vector and return.  Note that we do not have to clear
Index: gcc/omp-low.c
===================================================================
--- gcc/omp-low.c	(revision 189246)
+++ gcc/omp-low.c	(working copy)
@@ -3061,8 +3061,8 @@ 
 	    {
 	      gimple phi = create_phi_node (tmp_join, bb);
 	      SSA_NAME_DEF_STMT (tmp_join) = phi;
-	      add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
-	      add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
+	      add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION, NULL);
+	      add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION, NULL);
 	    }

 	  val = tmp_join;
@@ -4597,6 +4597,7 @@ 
 	{
 	  gimple nphi;
 	  source_location locus;
+	  tree block;

 	  phi = gsi_stmt (psi);
 	  t = gimple_phi_result (phi);
@@ -4606,14 +4607,16 @@ 

 	  t = PHI_ARG_DEF_FROM_EDGE (phi, se);
 	  locus = gimple_phi_arg_location_from_edge (phi, se);
+	  block = gimple_phi_arg_block_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, locus);
+	  add_phi_arg (nphi, t, ene, locus, block);
 	  locus = redirect_edge_var_map_location (vm);
-	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
+	  block = redirect_edge_var_map_block (vm);
+	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus, block);
 	}
       gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
       redirect_edge_var_map_clear (re);
@@ -4629,9 +4632,9 @@ 
       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),
-		   UNKNOWN_LOCATION);
+		   UNKNOWN_LOCATION, NULL);
       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
-		   UNKNOWN_LOCATION);
+		   UNKNOWN_LOCATION, NULL);
     }

   set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
Index: gcc/tree-vect-loop-manip.c
===================================================================
--- gcc/tree-vect-loop-manip.c	(revision 189246)
+++ gcc/tree-vect-loop-manip.c	(working copy)
@@ -294,13 +294,15 @@ 
        gsi_next (&gsi_new), gsi_next (&gsi_orig))
     {
       source_location locus;
+      tree block;
       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);
       locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e);
-      add_phi_arg (phi_new, def, new_loop_entry_e, locus);
+      block = gimple_phi_arg_block_from_edge (phi_orig, entry_arg_e);
+      add_phi_arg (phi_new, def, new_loop_entry_e, locus, block);

       /* step 2.  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
@@ -317,7 +319,8 @@ 
 	}

       /* An ordinary ssa name defined in the loop.  */
-      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
+      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus,
+		   block);

       /* Drop any debug references outside the loop, if they would
 	 become ill-formed SSA.  */
@@ -512,6 +515,7 @@ 
        gsi_next (&gsi_orig), gsi_next (&gsi_update))
     {
       source_location loop_locus, guard_locus;
+      tree loop_block, guard_block;
       orig_phi = gsi_stmt (gsi_orig);
       update_phi = gsi_stmt (gsi_update);

@@ -527,13 +531,19 @@ 
       loop_locus = gimple_phi_arg_location_from_edge (orig_phi,
 						      EDGE_SUCC (loop->latch,
 								 0));
+      loop_block = gimple_phi_arg_block_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));
+      guard_block = gimple_phi_arg_block_from_edge (orig_phi,
+						    loop_preheader_edge (loop));

-      add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus);
-      add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus);
+      add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus, loop_block);
+      add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus, guard_block);

       /* 1.3. Update phi in successor block.  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
@@ -552,7 +562,7 @@ 
                                  *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), loop_locus);
+      add_phi_arg (new_phi, loop_arg, single_exit (loop), loop_locus,
loop_block);

       /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@@ -680,8 +690,8 @@ 
       if (new_name2)
         guard_arg = new_name2;

-      add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION);
-      add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION);
+      add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION, NULL);
+      add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION, NULL);

       /* 1.3. Update phi in successor block.  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
@@ -696,7 +706,8 @@ 
                                  *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), UNKNOWN_LOCATION);
+      add_phi_arg (new_phi, loop_arg, single_exit (loop), UNKNOWN_LOCATION,
+		   NULL);

       /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@@ -733,7 +744,7 @@ 
       /* 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),
-		   UNKNOWN_LOCATION);
+		   UNKNOWN_LOCATION, NULL);

       /* 3.4. Update phi in successor of GUARD_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
@@ -859,14 +870,16 @@ 
 	{
 	  edge new_loop_exit_edge;
 	  source_location locus;
+	  tree block;

 	  locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop));
+	  block = gimple_phi_arg_block_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, locus);
+	  add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus, block);
 	}
     }

@@ -905,7 +918,8 @@ 
 	  phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
 	  if (phi_arg)
 	    add_phi_arg (phi, phi_arg, new_exit_e,
-			 gimple_phi_arg_location_from_edge (phi, entry_e));
+			 gimple_phi_arg_location_from_edge (phi, entry_e),
+			 gimple_phi_arg_block_from_edge (phi, entry_e));
 	}

       redirect_edge_and_branch_force (entry_e, new_loop->header);
@@ -1089,8 +1103,8 @@ 

   newphi = create_phi_node (var, bb_before_first_loop);
   add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru,
-	       UNKNOWN_LOCATION);
-  add_phi_arg (newphi, *first_niters, e_false, UNKNOWN_LOCATION);
+	       UNKNOWN_LOCATION, NULL);
+  add_phi_arg (newphi, *first_niters, e_false, UNKNOWN_LOCATION, NULL);

   *first_niters = PHI_RESULT (newphi);
 }
@@ -1193,7 +1207,7 @@ 
 					  new_phi);
 	    use_operand_p use_p;

-	    add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION);
+	    add_phi_arg (new_phi, vop, exit_e, UNKNOWN_LOCATION, NULL);
 	    gimple_phi_set_result (new_phi, new_vop);
 	    FOR_EACH_IMM_USE_STMT (stmt, imm_iter, vop)
 	      if (stmt != new_phi && gimple_bb (stmt) != loop->header)
@@ -2551,7 +2565,8 @@ 
 				  new_exit_bb);
       arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
       add_phi_arg (new_phi, arg, new_exit_e,
-		   gimple_phi_arg_location_from_edge (orig_phi, e));
+		   gimple_phi_arg_location_from_edge (orig_phi, e),
+ 		   gimple_phi_arg_block_from_edge (orig_phi, e));
       adjust_phi_and_debug_stmts (orig_phi, e, PHI_RESULT (new_phi));
     }

Index: gcc/tree-parloops.c
===================================================================
--- gcc/tree-parloops.c	(revision 189246)
+++ gcc/tree-parloops.c	(working copy)
@@ -998,6 +998,7 @@ 
   basic_block store_bb;
   tree local_res;
   source_location locus;
+  tree block;

   /* STORE_BB is the block where the phi
      should be stored.  It is the destination of the loop exit.
@@ -1017,11 +1018,12 @@ 
     = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
 		     NULL);
   locus = gimple_location (reduc->reduc_stmt);
+  block = gimple_block (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, locus);
+  add_phi_arg (new_phi, reduc->init, e, locus, block);
   add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
-	       FALLTHRU_EDGE (loop->latch), locus);
+	       FALLTHRU_EDGE (loop->latch), locus, block);
   reduc->new_phi = new_phi;

   return 1;
@@ -1500,7 +1502,7 @@ 
       SET_PHI_RESULT (phi, t);
       nphi = create_phi_node (res, orig_header);
       SSA_NAME_DEF_STMT (res) = nphi;
-      add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
+      add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION, NULL);

       if (res == control)
 	{
@@ -1656,6 +1658,7 @@ 
   for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       source_location locus;
+      tree block;
       tree def;
       phi = gsi_stmt (gsi);
       stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
@@ -1663,11 +1666,14 @@ 
       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);
+      block = gimple_phi_arg_block_from_edge (stmt,
+					      loop_preheader_edge (loop));
+      add_phi_arg (phi, def, guard, locus, block);

       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);
+      block = gimple_phi_arg_block_from_edge (stmt, loop_latch_edge (loop));
+      add_phi_arg (phi, def, end, locus, block);
     }
   e = redirect_edge_and_branch (exit, nexit->dest);
   PENDING_STMT (e) = NULL;
Index: gcc/tree-eh.c
===================================================================
--- gcc/tree-eh.c	(revision 189246)
+++ gcc/tree-eh.c	(working copy)
@@ -3853,13 +3853,15 @@ 
 	  FOR_EACH_EDGE (e, ei, old_bb->preds)
 	    {
 	      location_t oloc;
+	      tree oblock;
 	      tree oop;

 	      if ((e->flags & EDGE_EH) == 0)
 		continue;
 	      oop = gimple_phi_arg_def (ophi, e->dest_idx);
 	      oloc = gimple_phi_arg_location (ophi, e->dest_idx);
-	      redirect_edge_var_map_add (e, nresult, oop, oloc);
+	      oblock = gimple_phi_arg_block (ophi, e->dest_idx);
+	      redirect_edge_var_map_add (e, nresult, oop, oloc, oblock);
 	    }
 	}
       /* If we didn't find the PHI, but it's a VOP, remember to rename
@@ -3874,8 +3876,9 @@ 
 	{
 	  location_t nloc
 	    = gimple_phi_arg_location (nphi, old_bb_out->dest_idx);
+	  tree nblock = gimple_phi_arg_block (nphi, old_bb_out->dest_idx);
 	  FOR_EACH_EDGE (e, ei, old_bb->preds)
-	    redirect_edge_var_map_add (e, nresult, nop, nloc);
+	    redirect_edge_var_map_add (e, nresult, nop, nloc, nblock);
 	}
     }

Index: gcc/ipa-split.c
===================================================================
--- gcc/ipa-split.c	(revision 189246)
+++ gcc/ipa-split.c	(working copy)
@@ -1286,7 +1286,8 @@ 
 		  /* When there is PHI, just update its value.  */
 		  if (TREE_CODE (retval) == SSA_NAME
 		      && !gsi_end_p (psi))
-		    add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION);
+		    add_phi_arg (gsi_stmt (psi), retval, e, UNKNOWN_LOCATION,
+				 NULL);
 		  /* Otherwise update the return BB itself.
 		     find_return_bb allows at most one assignment to return value,
 		     so update first statement.  */
Index: gcc/tree-vect-loop.c
===================================================================
--- gcc/tree-vect-loop.c	(revision 189246)
+++ gcc/tree-vect-loop.c	(working copy)
@@ -3131,9 +3131,9 @@ 
                                                    NULL));

   /* Set the arguments of the phi node:  */
-  add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
+  add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION, NULL);
   add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop),
-	       UNKNOWN_LOCATION);
+	       UNKNOWN_LOCATION, NULL);


   /* In case that vectorization factor (VF) is bigger than the number
@@ -3617,13 +3617,13 @@ 
         {
           /* Set the loop-entry arg of the reduction-phi.  */
           add_phi_arg (phi, vec_init_def, loop_preheader_edge (loop),
-                       UNKNOWN_LOCATION);
+                       UNKNOWN_LOCATION, NULL);

           /* Set the loop-latch arg for the reduction-phi.  */
           if (j > 0)
             def = vect_get_vec_def_for_stmt_copy (vect_unknown_def_type, def);

-          add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
+          add_phi_arg (phi, def, loop_latch_edge (loop),
UNKNOWN_LOCATION, NULL);

           if (vect_print_dump_info (REPORT_DETAILS))
             {
@@ -4241,9 +4241,10 @@ 
                   /* Update phi node arguments with vs0 and vs2.  */
                   add_phi_arg (vect_phi, vect_phi_init,
                                loop_preheader_edge (outer_loop),
-                               UNKNOWN_LOCATION);
+                               UNKNOWN_LOCATION, NULL);
                   add_phi_arg (vect_phi, PHI_RESULT (inner_phi),
-                               loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
+                               loop_latch_edge (outer_loop), UNKNOWN_LOCATION,
+			       NULL);
                   if (vect_print_dump_info (REPORT_DETAILS))
                     {
                       fprintf (vect_dump, "created double reduction phi "
Index: gcc/tree-flow-inline.h
===================================================================
--- gcc/tree-flow-inline.h	(revision 189246)
+++ gcc/tree-flow-inline.h	(working copy)
@@ -483,6 +483,22 @@ 
   return gimple_phi_arg (gs, e->dest_idx)->locus;
 }

+/* Return the block location of gimple argument I of phi node GS.  */
+
+static inline tree
+gimple_phi_arg_block (gimple gs, size_t i)
+{
+  return gimple_phi_arg (gs, i)->block;
+}
+
+/* Return the block location of the argument on edge E of phi node GS.  */
+
+static inline tree
+gimple_phi_arg_block_from_edge (gimple gs, edge e)
+{
+  return gimple_phi_arg (gs, e->dest_idx)->block;
+}
+
 /* Set the source location of gimple argument I of phi node GS to LOC.  */

 static inline void
@@ -491,6 +507,14 @@ 
   gimple_phi_arg (gs, i)->locus = loc;
 }

+/* Set the block location of gimple argument I of phi node GS to BLOCK.  */
+
+static inline void
+gimple_phi_arg_set_block (gimple gs, size_t i, tree block)
+{
+  gimple_phi_arg (gs, i)->block = block;
+}
+
 /* Return TRUE if argument I of phi node GS has a location record.  */

 static inline bool
@@ -499,6 +523,13 @@ 
   return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
 }

+/* Return TRUE if argument I of phi node GS has a location record.  */
+
+static inline bool
+gimple_phi_arg_has_block (gimple gs, size_t i)
+{
+  return gimple_phi_arg_block (gs, i) != NULL;
+}

 /* Return the PHI nodes for basic block BB, or NULL if there are no
    PHI nodes.  */
@@ -1217,6 +1248,13 @@ 
   return v->locus;
 }

+/* Given an edge_var_map V, return the PHI arg location.  */
+
+static inline tree
+redirect_edge_var_map_block (edge_var_map *v)
+{
+  return v->block;
+}

 /* Return an SSA_NAME node for variable VAR defined in statement STMT
    in function cfun.  */
Index: gcc/tree-vect-data-refs.c
===================================================================
--- gcc/tree-vect-data-refs.c	(revision 189246)
+++ gcc/tree-vect-data-refs.c	(working copy)
@@ -4407,7 +4407,7 @@ 
   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, UNKNOWN_LOCATION);
+  add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION, NULL);

   return msq;
 }
Index: gcc/graphite-scop-detection.c
===================================================================
--- gcc/graphite-scop-detection.c	(revision 189246)
+++ gcc/graphite-scop-detection.c	(working copy)
@@ -1331,7 +1331,7 @@ 
 					  gimple_phi_result_ptr (close_phi));
 		add_phi_arg (close_phi, arg,
 			     gimple_phi_arg_edge (close_phi, 0),
-			     UNKNOWN_LOCATION);
+			     UNKNOWN_LOCATION, NULL);
 		use_p = gimple_phi_arg_imm_use_ptr (phi, i);
 		replace_exp (use_p, res);
 		update_stmt (phi);
Index: gcc/tree-ssa-phiopt.c
===================================================================
--- gcc/tree-ssa-phiopt.c	(revision 189246)
+++ gcc/tree-ssa-phiopt.c	(working copy)
@@ -1454,6 +1454,7 @@ 
   gimple newphi, new_stmt;
   gimple_stmt_iterator gsi;
   source_location locus;
+  tree block;

   /* Check if middle_bb contains of only one store.  */
   if (!assign
@@ -1461,6 +1462,7 @@ 
     return false;

   locus = gimple_location (assign);
+  block = gimple_block (assign);
   lhs = gimple_assign_lhs (assign);
   rhs = gimple_assign_rhs1 (assign);
   if (TREE_CODE (lhs) != MEM_REF
@@ -1494,14 +1496,15 @@ 
   name = make_ssa_name (condstoretemp, new_stmt);
   gimple_assign_set_lhs (new_stmt, name);
   gimple_set_location (new_stmt, locus);
+  gimple_set_block (new_stmt, block);
   gsi_insert_on_edge (e1, new_stmt);

   /* 4) Create a PHI node at the join block, with one argument
         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, locus);
-  add_phi_arg (newphi, name, e1, locus);
+  add_phi_arg (newphi, rhs, e0, locus, block);
+  add_phi_arg (newphi, name, e1, locus, block);

   lhs = unshare_expr (lhs);
   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
@@ -1528,6 +1531,7 @@ 
 {
   tree lhs_base, lhs, then_rhs, else_rhs;
   source_location then_locus, else_locus;
+  tree then_block, else_block;
   gimple_stmt_iterator gsi;
   gimple newphi, new_stmt;

@@ -1553,6 +1557,8 @@ 
   else_rhs = gimple_assign_rhs1 (else_assign);
   then_locus = gimple_location (then_assign);
   else_locus = gimple_location (else_assign);
+  then_block = gimple_block (then_assign);
+  else_block = gimple_block (else_assign);

   /* Now we've checked the constraints, so do the transformation:
      1) Remove the stores.  */
@@ -1576,8 +1582,10 @@ 
 	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, then_rhs, EDGE_SUCC (then_bb, 0), then_locus);
-  add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus);
+  add_phi_arg (newphi, then_rhs, EDGE_SUCC (then_bb, 0), then_locus,
+	       then_block);
+  add_phi_arg (newphi, else_rhs, EDGE_SUCC (else_bb, 0), else_locus,
+	       else_block);

   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));

Index: gcc/tree-cfgcleanup.c
===================================================================
--- gcc/tree-cfgcleanup.c	(revision 189246)
+++ gcc/tree-cfgcleanup.c	(working copy)
@@ -444,7 +444,9 @@ 
 	    {
 	      gimple phi = gsi_stmt (gsi);
 	      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);
+	      tree b = gimple_phi_arg_block_from_edge (phi, succ);
+	      add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l,
+			   b);
 	    }
 	}
     }
@@ -871,6 +873,7 @@ 
 	  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);
+	  tree block = gimple_phi_arg_block_from_edge (phi, succ);

 	  if (TREE_CODE (def) == SSA_NAME)
 	    {
@@ -891,12 +894,13 @@ 
 		    {
 		      def = new_arg;
 		      locus = redirect_edge_var_map_location (vm);
+		      block = redirect_edge_var_map_block (vm);
 		      break;
 		    }
 		}
 	    }

-	  add_phi_arg (phi, def, s, locus);
+	  add_phi_arg (phi, def, s, locus, block);
 	}

       redirect_edge_var_map_clear (e);
Index: gcc/tree-ssa-pre.c
===================================================================
--- gcc/tree-ssa-pre.c	(revision 189246)
+++ gcc/tree-ssa-pre.c	(working copy)
@@ -3403,10 +3403,10 @@ 
       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, UNKNOWN_LOCATION);
+	add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION, NULL);
       else
 	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
-		     UNKNOWN_LOCATION);
+		     UNKNOWN_LOCATION, NULL);
     }

   newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
Index: gcc/tree-ssa-live.c
===================================================================
--- gcc/tree-ssa-live.c	(revision 189246)
+++ gcc/tree-ssa-live.c	(working copy)
@@ -765,6 +765,10 @@ 
           FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
             {
 	      tree arg = USE_FROM_PTR (arg_p);
+	      int index = PHI_ARG_INDEX_FROM_USE (arg_p);
+	      tree block = gimple_phi_arg_block (phi, index);
+	      if (block != NULL)
+		TREE_USED (block) = true;
 	      mark_all_vars_used (&arg, global_unused_vars);
             }
         }
Index: gcc/tree-predcom.c
===================================================================
--- gcc/tree-predcom.c	(revision 189246)
+++ gcc/tree-predcom.c	(working copy)
@@ -1531,8 +1531,8 @@ 

       phi = create_phi_node (var, loop->header);
       SSA_NAME_DEF_STMT (var) = phi;
-      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
-      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
+      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION, NULL);
+      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION, NULL);
     }
 }

@@ -1595,8 +1595,8 @@ 
       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, UNKNOWN_LOCATION);
-      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
+      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION, NULL);
+      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION, NULL);
     }
   else
     {
Index: gcc/sese.c
===================================================================
--- gcc/sese.c	(revision 189246)
+++ gcc/sese.c	(working copy)
@@ -349,8 +349,8 @@ 

   create_new_def_for (gimple_phi_result (phi), phi,
 		      gimple_phi_result_ptr (phi));
-  add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION);
-  add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION);
+  add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION, NULL);
+  add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION, NULL);
 }

 /* Insert in the block BB phi nodes for variables defined in REGION
Index: gcc/tree-ssa-dce.c
===================================================================
--- gcc/tree-ssa-dce.c	(revision 189246)
+++ gcc/tree-ssa-dce.c	(working copy)
@@ -1129,6 +1129,7 @@ 
 	  gimple phi = gsi_stmt (gsi);
 	  tree op;
 	  source_location locus;
+	  tree block;

 	  /* PHIs for virtuals have no control dependency relation on them.
 	     We are lost here and must force renaming of the symbol.  */
@@ -1148,7 +1149,8 @@ 

 	  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);
+	  block = gimple_phi_arg_block (phi, e2->dest_idx);
+	  add_phi_arg (phi, op, e, locus, block);
 	  /* The resulting PHI if not dead can only be degenerate.  */
 	  gcc_assert (degenerate_phi_p (phi));
 	  gsi_next (&gsi);
Index: gcc/tree-ssa.c
===================================================================
--- gcc/tree-ssa.c	(revision 189246)
+++ gcc/tree-ssa.c	(working copy)
@@ -51,7 +51,8 @@ 
 /* 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,
source_location locus)
+redirect_edge_var_map_add (edge e, tree result, tree def,
source_location locus,
+			   tree block)
 {
   void **slot;
   edge_var_map_vector old_head, head;
@@ -70,6 +71,7 @@ 
   new_node.def = def;
   new_node.result = result;
   new_node.locus = locus;
+  new_node.block = block;

   VEC_safe_push (edge_var_map, heap, head, &new_node);
   if (old_head != head)
@@ -193,15 +195,17 @@ 
     {
       tree def;
       source_location locus ;
+      tree block;

       phi = gsi_stmt (gsi);
       def = gimple_phi_arg_def (phi, e->dest_idx);
       locus = gimple_phi_arg_location (phi, e->dest_idx);
+      block = gimple_phi_arg_block (phi, e->dest_idx);

       if (def == NULL_TREE)
 	continue;

-      redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
+      redirect_edge_var_map_add (e, gimple_phi_result (phi), def,
locus, block);
     }

   e = redirect_edge_succ_nodup (e, dest);
@@ -234,7 +238,8 @@ 

       phi = gsi_stmt (gsi);
       def = redirect_edge_var_map_def (vm);
-      add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
+      add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm),
+		   redirect_edge_var_map_block (vm));
     }

   redirect_edge_var_map_clear (e);
Index: gcc/gimple-streamer-in.c
===================================================================
--- gcc/gimple-streamer-in.c	(revision 189246)
+++ gcc/gimple-streamer-in.c	(working copy)
@@ -67,7 +67,7 @@ 
 	    break;
 	  }

-      add_phi_arg (result, def, e, arg_loc);
+      add_phi_arg (result, def, e, arg_loc, NULL);
     }

   return result;
Index: gcc/tree-vect-stmts.c
===================================================================
--- gcc/tree-vect-stmts.c	(revision 189246)
+++ gcc/tree-vect-stmts.c	(working copy)
@@ -5117,7 +5117,7 @@ 
 		      if (i == vec_num - 1 && j == ncopies - 1)
 			add_phi_arg (phi, lsq,
 				     loop_latch_edge (containing_loop),
-				     UNKNOWN_LOCATION);
+				     UNKNOWN_LOCATION, NULL);
 		      msq = lsq;
 		    }
 		}
Index: gcc/tree-inline.c
===================================================================
--- gcc/tree-inline.c	(revision 189246)
+++ gcc/tree-inline.c	(working copy)
@@ -2019,6 +2019,7 @@ 
 	      tree arg;
 	      tree new_arg;
 	      tree block = id->block;
+	      tree arg_block, *n;
 	      edge_iterator ei2;

 	      /* When doing partial cloning, we allow PHIs on the entry block
@@ -2046,8 +2047,15 @@ 
 		  gsi_insert_seq_on_edge (new_edge, stmts);
 		  inserted = true;
 		}
+	      n = (tree *) pointer_map_contains (id->decl_map,
+		gimple_phi_arg_block_from_edge (phi, old_edge));
+	      if (n)
+		arg_block = *n;
+	      else
+		arg_block = NULL;
 	      add_phi_arg (new_phi, new_arg, new_edge,
-			   gimple_phi_arg_location_from_edge (phi, old_edge));
+			   gimple_phi_arg_location_from_edge (phi, old_edge),
+			   arg_block);
 	    }
 	}
     }
Index: gcc/tree-ssa-phiprop.c
===================================================================
--- gcc/tree-ssa-phiprop.c	(revision 189246)
+++ gcc/tree-ssa-phiprop.c	(working copy)
@@ -159,9 +159,11 @@ 
       tree old_arg, new_var;
       gimple tmp;
       source_location locus;
+      tree block;

       old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
       locus = gimple_phi_arg_location_from_edge (phi, e);
+      block = gimple_phi_arg_block_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))
@@ -169,6 +171,7 @@ 
 	  gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
 	  old_arg = gimple_assign_rhs1 (def_stmt);
 	  locus = gimple_location (def_stmt);
+	  block = gimple_block (def_stmt);
 	}

       if (TREE_CODE (old_arg) == SSA_NAME)
@@ -203,6 +206,7 @@ 
 	  new_var = make_ssa_name (new_var, tmp);
 	  gimple_assign_set_lhs (tmp, new_var);
 	  gimple_set_location (tmp, locus);
+	  gimple_set_block (tmp, block);

 	  gsi_insert_on_edge (e, tmp);
 	  update_stmt (tmp);
@@ -216,7 +220,7 @@ 
 	    }
 	}

-      add_phi_arg (new_phi, new_var, e, locus);
+      add_phi_arg (new_phi, new_var, e, locus, block);
     }

   update_stmt (new_phi);
Index: gcc/tree-outof-ssa.c
===================================================================
--- gcc/tree-outof-ssa.c	(revision 189246)
+++ gcc/tree-outof-ssa.c	(working copy)
@@ -78,6 +78,9 @@ 
   /* Source locus on each edge */
   VEC(source_location,heap) *edge_locus;

+  /* Block location on each edge.  */
+  VEC(tree,heap) *edge_block;
+
   /* Visited vector.  */
   sbitmap visited;

@@ -96,6 +99,9 @@ 

   /* Source locations for any constant copies.  */
   VEC(source_location,heap) *copy_locus;
+
+  /* Block locations for any constant copies.  */
+  VEC(tree,heap) *copy_block;
 } *elim_graph;


@@ -174,7 +180,8 @@ 
 /* 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,
source_location locus)
+insert_partition_copy_on_edge (edge e, int dest, int src,
source_location locus,
+			       tree block)
 {
   tree var;
   rtx seq;
@@ -194,7 +201,10 @@ 
   set_location_for_edge (e);
   /* If a locus is provided, override the default.  */
   if (locus)
-    set_curr_insn_source_location (locus);
+    {
+      set_curr_insn_source_location (locus);
+      set_curr_insn_block (block);
+    }

   var = partition_to_var (SA.map, src);
   seq = emit_partition_copy (SA.partition_to_pseudo[dest],
@@ -209,7 +219,8 @@ 
    onto edge E.  */

 static void
-insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
+insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus,
+			   tree block)
 {
   rtx seq, x;
   enum machine_mode dest_mode, src_mode;
@@ -231,7 +242,10 @@ 
   set_location_for_edge (e);
   /* If a locus is provided, override the default.  */
   if (locus)
-    set_curr_insn_source_location (locus);
+    {
+      set_curr_insn_source_location (locus);
+      set_curr_insn_block (block);
+    }

   start_sequence ();

@@ -269,7 +283,7 @@ 

 static void
 insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
-			    source_location locus)
+			    source_location locus, tree block)
 {
   rtx seq;
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -287,7 +301,10 @@ 
   set_location_for_edge (e);
   /* If a locus is provided, override the default.  */
   if (locus)
-    set_curr_insn_source_location (locus);
+    {
+      set_curr_insn_source_location (locus);
+      set_curr_insn_block (block);
+    }

   /* We give the destination as sizeexp in case src/dest are BLKmode
      mems.  Usually we give the source.  As we result from SSA names
@@ -304,7 +321,8 @@ 
    onto edge E.  */

 static void
-insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
+insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus,
+			    tree block)
 {
   tree var;
   rtx seq;
@@ -323,7 +341,10 @@ 
   set_location_for_edge (e);
   /* If a locus is provided, override the default.  */
   if (locus)
-    set_curr_insn_source_location (locus);
+    {
+      set_curr_insn_source_location (locus);
+      set_curr_insn_block (block);
+    }

   var = partition_to_var (SA.map, src);
   seq = emit_partition_copy (dest,
@@ -347,8 +368,10 @@ 
   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->copy_block = VEC_alloc (tree, heap, 10);
   g->edge_list = VEC_alloc (int, heap, 20);
   g->edge_locus = VEC_alloc (source_location, heap, 10);
+  g->edge_block = VEC_alloc (tree, heap, 10);
   g->stack = VEC_alloc (int, heap, 30);

   g->visited = sbitmap_alloc (size);
@@ -365,6 +388,7 @@ 
   VEC_truncate (int, g->nodes, 0);
   VEC_truncate (int, g->edge_list, 0);
   VEC_truncate (source_location, g->edge_locus, 0);
+  VEC_truncate (tree, g->edge_block, 0);
 }


@@ -380,7 +404,9 @@ 
   VEC_free (int, heap, g->const_dests);
   VEC_free (int, heap, g->nodes);
   VEC_free (source_location, heap, g->copy_locus);
+  VEC_free (tree, heap, g->copy_block);
   VEC_free (source_location, heap, g->edge_locus);
+  VEC_free (tree, heap, g->edge_block);

   free (g);
 }
@@ -413,11 +439,13 @@ 
 /* Add the edge PRED->SUCC to graph G.  */

 static inline void
-elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus)
+elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus,
+		     tree block)
 {
   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);
+  VEC_safe_push (tree, heap, g->edge_block, block);
 }


@@ -425,7 +453,8 @@ 
    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, source_location *locus)
+elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus,
+			     tree *block)
 {
   int y;
   unsigned x;
@@ -437,9 +466,12 @@ 
 	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);
+	*block = VEC_index (tree, g->edge_block, x / 2);
+	VEC_replace (tree, g->edge_block, x / 2, NULL);
 	return y;
       }
   *locus = UNKNOWN_LOCATION;
+  *block = NULL;
   return -1;
 }

@@ -448,7 +480,7 @@ 
    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, LOCUS, CODE)		\
+#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, BLOCK, CODE)	\
 do {									\
   unsigned x_;								\
   int y_;								\
@@ -460,6 +492,8 @@ 
       (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1));	\
       (void) ((LOCUS) = VEC_index (source_location,			\
 				   (GRAPH)->edge_locus, x_ / 2));	\
+      (void) ((BLOCK) = VEC_index (tree,				\
+				   (GRAPH)->edge_block, x_ / 2));	\
       CODE;								\
     }									\
 } while (0)
@@ -469,7 +503,7 @@ 
    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, LOCUS, CODE)		\
+#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, BLOCK, CODE)	\
 do {									\
   unsigned x_;								\
   int y_;								\
@@ -481,6 +515,8 @@ 
       (void) ((VAR) = VEC_index (int, (GRAPH)->edge_list, x_));		\
       (void) ((LOCUS) = VEC_index (source_location,			\
 				   (GRAPH)->edge_locus, x_ / 2));	\
+      (void) ((BLOCK) = VEC_index (tree,				\
+				   (GRAPH)->edge_block, x_ / 2));	\
       CODE;								\
     }									\
 } while (0)
@@ -511,6 +547,7 @@ 
     {
       gimple phi = gsi_stmt (gsi);
       source_location locus;
+      tree block;

       p0 = var_to_partition (g->map, gimple_phi_result (phi));
       /* Ignore results which are not in partitions.  */
@@ -519,6 +556,7 @@ 

       Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
       locus = gimple_phi_arg_location_from_edge (phi, g->e);
+      block = gimple_phi_arg_block_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
@@ -532,6 +570,7 @@ 
 	  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);
+	  VEC_safe_push (tree, heap, g->copy_block, block);
 	}
       else
         {
@@ -540,7 +579,7 @@ 
 	    {
 	      eliminate_name (g, p0);
 	      eliminate_name (g, pi);
-	      elim_graph_add_edge (g, p0, pi, locus);
+	      elim_graph_add_edge (g, p0, pi, locus, block);
 	    }
 	}
     }
@@ -554,9 +593,10 @@ 
 {
   int S;
   source_location locus;
+  tree block;

   SET_BIT (g->visited, T);
-  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
+  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus, block,
     {
       if (!TEST_BIT (g->visited, S))
         elim_forward (g, S);
@@ -572,8 +612,9 @@ 
 {
   int P;
   source_location locus;
+  tree block;

-  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
+  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
     {
       if (!TEST_BIT (g->visited, P))
         return 1;
@@ -588,14 +629,15 @@ 
 {
   int P;
   source_location locus;
+  tree block;

   SET_BIT (g->visited, T);
-  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
+  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
     {
       if (!TEST_BIT (g->visited, P))
         {
 	  elim_backward (g, P);
-	  insert_partition_copy_on_edge (g->e, P, T, locus);
+	  insert_partition_copy_on_edge (g->e, P, T, locus, block);
 	}
     });
 }
@@ -624,6 +666,7 @@ 
 {
   int P, S;
   source_location locus;
+  tree block;

   if (elim_unvisited_predecessor (g, T))
     {
@@ -631,23 +674,24 @@ 
       rtx U = get_temp_reg (var);
       int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));

-      insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
-      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
+      insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION, NULL);
+      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus, block,
 	{
 	  if (!TEST_BIT (g->visited, P))
 	    {
 	      elim_backward (g, P);
-	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
+	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus,
+					  block);
 	    }
 	});
     }
   else
     {
-      S = elim_graph_remove_succ_edge (g, T, &locus);
+      S = elim_graph_remove_succ_edge (g, T, &locus, &block);
       if (S != -1)
 	{
 	  SET_BIT (g->visited, T);
-	  insert_partition_copy_on_edge (g->e, T, S, locus);
+	  insert_partition_copy_on_edge (g->e, T, S, locus, block);
 	}
     }
 }
@@ -662,6 +706,7 @@ 

   gcc_assert (VEC_length (tree, g->const_copies) == 0);
   gcc_assert (VEC_length (source_location, g->copy_locus) == 0);
+  gcc_assert (VEC_length (tree, g->copy_block) == 0);

   /* Abnormal edges already have everything coalesced.  */
   if (e->flags & EDGE_ABNORMAL)
@@ -699,11 +744,13 @@ 
       int dest;
       tree src;
       source_location locus;
+      tree block;

       src = VEC_pop (tree, g->const_copies);
       dest = VEC_pop (int, g->const_dests);
       locus = VEC_pop (source_location, g->copy_locus);
-      insert_value_copy_on_edge (e, dest, src, locus);
+      block = VEC_pop (tree, g->copy_block);
+      insert_value_copy_on_edge (e, dest, src, locus, block);
     }
 }

@@ -1088,8 +1135,12 @@ 

 		  /* copy location if present.  */
 		  if (gimple_phi_arg_has_location (phi, i))
-		    gimple_set_location (stmt,
-					 gimple_phi_arg_location (phi, i));
+		    {
+		      gimple_set_location (stmt,
+					   gimple_phi_arg_location (phi, i));
+		      gimple_set_block (stmt,
+					gimple_phi_arg_block (phi, i));
+		    }

 		  /* Insert the new statement into the block and update
 		     the PHI node.  */
Index: gcc/tree-flow.h
===================================================================
--- gcc/tree-flow.h	(revision 189246)
+++ gcc/tree-flow.h	(working copy)
@@ -506,7 +506,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 create_phi_node (tree, basic_block);
-extern void add_phi_arg (gimple, tree, edge, source_location);
+extern void add_phi_arg (gimple, tree, edge, source_location, tree);
 extern void remove_phi_args (edge);
 extern void remove_phi_node (gimple_stmt_iterator *, bool);
 extern void remove_phi_nodes (basic_block);
@@ -530,6 +530,7 @@ 
   tree result;			/* PHI result.  */
   tree def;			/* PHI arg definition.  */
   source_location locus;        /* PHI arg location.  */
+  tree block;			/* PHI arg block.  */
 };
 typedef struct _edge_var_map edge_var_map;

@@ -540,7 +541,7 @@ 
 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, source_location);
+extern void redirect_edge_var_map_add (edge, tree, tree,
source_location, tree);
 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);
Index: gcc/tree-switch-conversion.c
===================================================================
--- gcc/tree-switch-conversion.c	(revision 189246)
+++ gcc/tree-switch-conversion.c	(working copy)
@@ -1189,8 +1189,10 @@ 
        !gsi_end_p (gsi); gsi_next (&gsi), i++)
     {
       gimple phi = gsi_stmt (gsi);
-      add_phi_arg (phi, info->target_inbound_names[i], e1f, UNKNOWN_LOCATION);
-      add_phi_arg (phi, info->target_outbound_names[i], e2f, UNKNOWN_LOCATION);
+      add_phi_arg (phi, info->target_inbound_names[i], e1f, UNKNOWN_LOCATION,
+		   NULL);
+      add_phi_arg (phi, info->target_outbound_names[i], e2f, UNKNOWN_LOCATION,
+		   NULL);
     }
 }

Index: gcc/tree-cfg.c
===================================================================
--- gcc/tree-cfg.c	(revision 189246)
+++ gcc/tree-cfg.c	(working copy)
@@ -2554,7 +2554,8 @@ 

       gcc_assert (result == gimple_phi_result (phi));

-      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
+      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm),
+		   redirect_edge_var_map_block (vm));
     }

   redirect_edge_var_map_clear (old_edge);
@@ -5014,7 +5015,7 @@ 
       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,
-		   UNKNOWN_LOCATION);
+		   UNKNOWN_LOCATION, NULL);
     }

   /* Add the arguments we have stored on edges.  */
@@ -5475,7 +5476,8 @@ 
       phi_copy = gsi_stmt (psi_copy);
       def = PHI_ARG_DEF_FROM_EDGE (phi, e);
       add_phi_arg (phi_copy, def, e_copy,
-		   gimple_phi_arg_location_from_edge (phi, e));
+		   gimple_phi_arg_location_from_edge (phi, e),
+		   gimple_phi_arg_block_from_edge (phi, e));
     }
 }

@@ -5850,7 +5852,8 @@ 
 	  {
 	    phi = gsi_stmt (psi);
 	    def = PHI_ARG_DEF (phi, nexits[0]->dest_idx);
-	    add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e));
+	    add_phi_arg (phi, def, e, gimple_phi_arg_location_from_edge (phi, e),
+			 gimple_phi_arg_block_from_edge (phi, e));
 	  }
       }
   e = redirect_edge_and_branch (nexits[1], nexits[0]->dest);
@@ -7426,7 +7429,8 @@ 
       phi1 = gsi_stmt (psi1);
       phi2 = gsi_stmt (psi2);
       def = PHI_ARG_DEF (phi2, e2->dest_idx);
-      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
+      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2),
+		   gimple_phi_arg_block_from_edge (phi2, e2));
     }
 }