This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PHI argument locations (PR 26475)


Richi's recent comment in PR 26475 reminded me that I had forgotten to get back to this issue.

Our SSA implementation makes no attempts to keep location information in PHI nodes. As a result, we lose a lot of simple information. If anyone has looked, you'll see something like:

 if (x)
   ret = y;
 else
   ret = 42;

starts out:

 [q.c : 6:9] ret = y;
 goto <bb 5>;
<bb 4>:
 [q.c : 8:9] ret = 42;

and after into SSA looks something like:

<bb 3>:
<bb 4>:
 # ret_1 = PHI <y_3(D)(2), 42(3)>

and the location info from the original assignments is lost..

When matz merged out-of-ssa and expand, he added some changes which attempt to recreate a location by finding the last statement near the beginning of the phi argument edge. Sometimes this gets you in the ballpark, and sometimes it doesn't. Checking the output of the above example, the 'if' is the nearest statement, so we currently assign it's location to both arguments:

(insn 6 11 23 4 q.c:5 (set (reg/v:SI 58 [ ret ])
       (const_int 42 [0x2a])) -1 (nil))
<...>
(insn 5 25 12 5 q.c:5 (set (reg/v:SI 58 [ ret ])
       (reg/v:SI 61 [ y ])) -1 (nil))


During the initial debuglocus work, I needed to add support to PHI nodes so that arguments could support locations, and then out-of-ssa would propagate the original information. After looking back at it, it was fairly incomplete, so I just finished updating it. The .optimized output now looks like:


<bb 3>:
<bb 4>:
 # ret_1 = PHI <[q.c : 6:9] y_3(D)(2), [q.c : 8:9] 42(3)>

which is propagated properly into rtl:

(insn 6 11 23 4 q.c:8 (set (reg/v:SI 58 [ ret ])
(const_int 42 [0x2a])) -1 (nil))
<...>
(insn 5 25 12 5 q.c:6 (set (reg/v:SI 58 [ ret ])
(reg/v:SI 61 [ y ])) -1 (nil))
----------------------------
The primary change is that each PHI argument now contains a location field. With the removal of vast quantities of virtual PHI's by richi, I doubt its remotely noticeable, and there is no other reasonable way to retain the info anyway.


When into SSA is populating PHI arguments, the locus from reaching definitions is propagated into the PHI arguments. There were also some minor changes to the ssa-update machinery, and I had to maintain a location along with defs and edges in a couple of places (edge redirection varmap & outofssa elimination graph)

Originally I was only going to make a call to add the location when it was available, but eventually decided that the best course of action was to add a location parameter to add_phi_arg(), and update every call. This way one has to consciously say "there is no location for this argument" rather than just forgetting about it. I updated a lot of places with what I think is the correct location, but there were some places where I didn't understand what was going on well enough, so I just passed UNKNOWN_LOCATION in for those. (Which is what current behaviour would be). Changing every call to add_phi_args() makes the patch seem more intrusive than it is. It also makes it easy to find the places where we aren't adding locations for anyone that might want to look into fixing up the rest.

Out-of-ssa still guesses at the location info in set_location_for_edge() and then if a location is available in the argument, overrides the guess. I'm now thinking thats not so bright perhaps, and maybe we ought not ever guess anymore eh? Part of the reason is that presumably curr_insn_block need to be set somehow, perhaps I can just grab the logic for that and set it the same way when there is a location to be entered, and leave the location and curr_insn_block unset if there is no location? Im not sure what curr_insn_block is used for. What happens if I don't set it at all and just set the location?

Oh, and I also noticed that in tree-inline.c the parameters that are copied into locals are not given any location... There is a few lines of code there which gives them the same location as the call site, which seemed reasonable at the time, but isnt really related to this. Is that OK, or should I just remove it?

This bootstraps on x86_64-unknown-linux-gnu and passes all the testsuites with no regressions.

What do you think?

Andrew
-------------------------------

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

	PR debug 26475
	* tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set
	location for phi arguments.
	(rewrite_update_phi_arguments): Find locations for reaching defs.
	* tree-ssa-threadupdate.c (create_edge_and_update_destination_phis):
	Add location to add_phi_arg calls.
	* tree-loop-districbution.c (update_phis_for_loop_copy): Add locations.
	* tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge,
	split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations.
	* tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call,
	create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations.
	* tree.h (struct phi_arg_d): Add location_t to PHI arguments.
	* tree-phinodes.c (make_phi_node): Initialize location.
	(resize_phi_node): Initialize location to UNKNOWN_LOCATION.
	(add_phi_arg): Add location parameter.
	(remove_phi_arg_num): Move location when moving phi argument.
	* omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set 
	location.
	* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop,
	slpeel_update_phi_nodes_for_guard1,
	slpeel_update_phi_nodes_for_guard2,
	slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations,
	vect_loop_versioning): Set locations.
	* tree-parloops.c (create_phi_for_local_result,
	transform_to_exit_first_loop, create_parallel_loop): Add locations.
	* gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present.
	* tree-vect-loop.c (get_initial_def_for_induction,
	vect_create_epilog_for_reduction, vect_finalize_reduction): Add
	locations.
	* tree-flow-inline.h (gimple_phi_arg_location): New.  Return locus.
	(gimple_phi_arg_location_from_edge): New.  Return locus from an edge.
	(gimple_phi_arg_set_location): New.  Set locus.
	(gimple_phi_arg_has_location): New.  Check for locus.
	(redirect_edge_var_map_location): New.  Return locus from var_map.
	* tree-vect-data-refs.c (vect_setup_realignment): Set location.
	* tree-ssa-phiopt.c (conditional_replacement): Set locus when
	combining PHI arguments.
	(cond_store_replacement): Set location.
	* cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible.
	* grpahite.c (add_loop_exit_phis, add_guard_exit_phis,
	scop_add_exit_phis_edge): Add locations.
	* tree-cfgcleanup.c (remove_forwarder_block,
	remove_forwarder_block_with_phi): Add locations.
	* tree-ssa-pre.c (insert_into_preds_of_block): Add locations.
	* tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add
	locations.
	* tree-ssa-dce.c (forward_edge_to_pdom): Add locations.
	* tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge,
	flush_pending_stmts): Add source location.
	* lambda-code.c (perfect_nestify): Maintain location stack with argument
	stack to preserve locations.
	* tree-vect-stmts.c (vectorizable_load): Add location.
	* tree-inline.c (copy_phis_for_bb): Copy locus.
	(setup_one_parameter): Add call locus to inlined parameter stmts.
	(initialize_inlined_parameters): Pass in call location as parameter
	assignment locus.
	(tree_function_versioning): Pass location to setup_one_parameter.
	* tree-ssa-phiprop.c (phiprop_insert_phi): Set locations.
	* tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for
	copy and edge lists.
	(insert_partition_copy_on_edge, insert_value_copy_on_edge,
	insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a 
	locus parameter and override the stmt default if provided.
	(new_elim_graph, clear_elim_graph, delete_elim_graph,
	elim_graph_add_edge, elim_graph_remove_succ_edge,
	FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build,
	elim_forward, elim_unvisited_predecessor, elim_backward, elim_create,
	eliminate_phi):  Add locus info in elimination graph for each edge and
	value copy.
	(insert_backedge_copies): Copy locus if present.
	* tree-flow.h (struct _edge_var_map): Add locus field.
	* tree-switch_conversions.c (fix_phi_nodes): Add locations.
	* tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block,
	add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add 
	locations.
	* ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations.
	
Index: tree-into-ssa.c
===================================================================
*** tree-into-ssa.c	(revision 150217)
--- tree-into-ssa.c	(working copy)
*************** insert_phi_nodes_for (tree var, bitmap p
*** 1114,1120 ****
  	     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);
  	}
        else
  	{
--- 1114,1120 ----
  	     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);
  	}
        else
  	{
*************** rewrite_add_phi_arguments (basic_block b
*** 1320,1328 ****
  	   gsi_next (&gsi))
  	{
  	  tree currdef;
  	  phi = gsi_stmt (gsi);
  	  currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
! 	  add_phi_arg (phi, currdef, e);
  	}
      }
  }
--- 1320,1331 ----
  	   gsi_next (&gsi))
  	{
  	  tree currdef;
+ 	  gimple stmt;
+ 
  	  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));
  	}
      }
  }
*************** rewrite_update_phi_arguments (basic_bloc
*** 1857,1863 ****
        phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
        for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
  	{
! 	  tree arg, lhs_sym;
  	  use_operand_p arg_p;
  
    	  gcc_assert (rewrite_uses_p (phi));
--- 1860,1866 ----
        phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
        for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
  	{
! 	  tree arg, lhs_sym, reaching_def = NULL;
  	  use_operand_p arg_p;
  
    	  gcc_assert (rewrite_uses_p (phi));
*************** rewrite_update_phi_arguments (basic_bloc
*** 1875,1892 ****
  	      /* When updating a PHI node for a recently introduced
  		 symbol we may find NULL arguments.  That's why we
  		 take the symbol from the LHS of the PHI node.  */
! 	      SET_USE (arg_p, get_reaching_def (lhs_sym));
  	    }
  	  else
  	    {
  	      tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg);
  
  	      if (symbol_marked_for_renaming (sym))
! 		SET_USE (arg_p, get_reaching_def (sym));
  	      else if (is_old_name (arg))
! 		SET_USE (arg_p, get_reaching_def (arg));
  	    }
  
  	  if (e->flags & EDGE_ABNORMAL)
  	    SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
  	}
--- 1878,1918 ----
  	      /* When updating a PHI node for a recently introduced
  		 symbol we may find NULL arguments.  That's why we
  		 take the symbol from the LHS of the PHI node.  */
! 	      reaching_def = get_reaching_def (lhs_sym);
! 
  	    }
  	  else
  	    {
  	      tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg);
  
  	      if (symbol_marked_for_renaming (sym))
! 		reaching_def = get_reaching_def (sym);
  	      else if (is_old_name (arg))
! 		reaching_def = get_reaching_def (arg);
  	    }
  
+           /* Update the argument if there is a reaching def.  */
+ 	  if (reaching_def)
+ 	    {
+ 	      gimple stmt;
+ 	      source_location locus;
+ 	      int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
+ 
+ 	      SET_USE (arg_p, reaching_def);
+ 	      stmt = SSA_NAME_DEF_STMT (reaching_def);
+ 
+ 	      /* Single element PHI nodes  behave like copies, so get the 
+ 		 location from the phi argument.  */
+ 	      if (gimple_code (stmt) == GIMPLE_PHI && 
+ 		  gimple_phi_num_args (stmt) == 1)
+ 		locus = gimple_phi_arg_location (stmt, 0);
+ 	      else
+ 		locus = gimple_location (stmt);
+ 
+ 	      gimple_phi_arg_set_location (phi, arg_i, locus);
+ 	    }
+ 
+ 
  	  if (e->flags & EDGE_ABNORMAL)
  	    SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
  	}
Index: tree-ssa-threadupdate.c
===================================================================
*** tree-ssa-threadupdate.c	(revision 150217)
--- tree-ssa-threadupdate.c	(working copy)
*************** create_edge_and_update_destination_phis 
*** 325,333 ****
    for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple phi = gsi_stmt (gsi);
! 
        int indx = rd->outgoing_edge->dest_idx;
!       add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e);
      }
  }
  
--- 325,335 ----
    for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple phi = gsi_stmt (gsi);
!       source_location locus;
        int indx = rd->outgoing_edge->dest_idx;
! 
!       locus = gimple_phi_arg_location (phi, indx);
!       add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e, locus);
      }
  }
  
Index: tree-loop-distribution.c
===================================================================
*** tree-loop-distribution.c	(revision 150217)
--- tree-loop-distribution.c	(working copy)
*************** update_phis_for_loop_copy (struct loop *
*** 97,113 ****
         gsi_next (&si_new), gsi_next (&si_orig))
      {
        tree def;
        gimple phi_new = gsi_stmt (si_new);
        gimple phi_orig = gsi_stmt (si_orig);
  
        /* Add the first phi argument for the phi in NEW_LOOP (the one
  	 associated with the entry of NEW_LOOP)  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
!       add_phi_arg (phi_new, def, new_loop_entry_e);
  
        /* 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);
  
        if (TREE_CODE (def) == SSA_NAME)
  	{
--- 97,116 ----
         gsi_next (&si_new), gsi_next (&si_orig))
      {
        tree def;
+       source_location locus;
        gimple phi_new = gsi_stmt (si_new);
        gimple phi_orig = gsi_stmt (si_orig);
  
        /* Add the first phi argument for the phi in NEW_LOOP (the one
  	 associated with the entry of NEW_LOOP)  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
!       locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e);
!       add_phi_arg (phi_new, def, new_loop_entry_e, locus);
  
        /* Add the second phi argument for the phi in NEW_LOOP (the one
  	 associated with the latch of NEW_LOOP)  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
+       locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
  
        if (TREE_CODE (def) == SSA_NAME)
  	{
*************** update_phis_for_loop_copy (struct loop *
*** 122,128 ****
  	/* Could be an integer.  */
  	new_ssa_name = def;
  
!       add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
      }
  }
  
--- 125,131 ----
  	/* Could be an integer.  */
  	new_ssa_name = def;
  
!       add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
      }
  }
  
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 150217)
--- tree-ssa-loop-manip.c	(working copy)
*************** create_iv (tree base, tree step, tree va
*** 124,131 ****
  
    stmt = create_phi_node (vb, loop->header);
    SSA_NAME_DEF_STMT (vb) = stmt;
!   add_phi_arg (stmt, initial, loop_preheader_edge (loop));
!   add_phi_arg (stmt, va, loop_latch_edge (loop));
  }
  
  /* Add exit phis for the USE on EXIT.  */
--- 124,131 ----
  
    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 exit phis for the USE on EXIT.  */
*************** add_exit_phis_edge (basic_block exit, tr
*** 155,161 ****
    create_new_def_for (gimple_phi_result (phi), phi,
  		      gimple_phi_result_ptr (phi));
    FOR_EACH_EDGE (e, ei, exit->preds)
!     add_phi_arg (phi, use, e);
  }
  
  /* Add exit phis for VAR that is used in LIVEIN.
--- 155,161 ----
    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 exit phis for VAR that is used in LIVEIN.
*************** split_loop_exit_edge (edge exit)
*** 475,485 ****
--- 475,487 ----
    tree new_name, name;
    use_operand_p op_p;
    gimple_stmt_iterator psi;
+   source_location locus;
  
    for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi))
      {
        phi = gsi_stmt (psi);
        op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
+       locus = gimple_phi_arg_location_from_edge (phi, single_succ_edge (bb));
  
        name = USE_FROM_PTR (op_p);
  
*************** split_loop_exit_edge (edge exit)
*** 493,499 ****
        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);
        SET_USE (op_p, new_name);
      }
  
--- 495,501 ----
        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);
        SET_USE (op_p, new_name);
      }
  
*************** tree_transform_and_unroll_loop (struct l
*** 1013,1020 ****
        phi_rest = create_phi_node (new_init, rest);
        SSA_NAME_DEF_STMT (new_init) = phi_rest;
  
!       add_phi_arg (phi_rest, init, precond_edge);
!       add_phi_arg (phi_rest, next, new_exit);
        SET_USE (op, new_init);
      }
  
--- 1015,1022 ----
        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);
        SET_USE (op, new_init);
      }
  
Index: tree-tailcall.c
===================================================================
*** tree-tailcall.c	(revision 150217)
--- tree-tailcall.c	(working copy)
*************** add_successor_phi_arg (edge e, tree var,
*** 548,554 ****
        break;
  
    gcc_assert (!gsi_end_p (gsi));
!   add_phi_arg (gsi_stmt (gsi), phi_arg, e);
  }
  
  /* Creates a GIMPLE statement which computes the operation specified by
--- 548,554 ----
        break;
  
    gcc_assert (!gsi_end_p (gsi));
!   add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION);
  }
  
  /* Creates a GIMPLE statement which computes the operation specified by
*************** eliminate_tail_call (struct tailcall *t)
*** 773,779 ****
        phi = gsi_stmt (gsi);
        gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
  
!       add_phi_arg (phi, arg, e);
        gsi_next (&gsi);
      }
  
--- 773,779 ----
        phi = gsi_stmt (gsi);
        gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
  
!       add_phi_arg (phi, arg, e, gimple_location (stmt));
        gsi_next (&gsi);
      }
  
*************** create_tailcall_accumulator (const char 
*** 870,876 ****
    add_referenced_var (tmp);
    phi = create_phi_node (tmp, bb);
    /* RET_TYPE can be a float when -ffast-maths is enabled.  */
!   add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb));
    return PHI_RESULT (phi);
  }
   
--- 870,877 ----
    add_referenced_var (tmp);
    phi = create_phi_node (tmp, bb);
    /* RET_TYPE can be a float when -ffast-maths is enabled.  */
!   add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb),
! 	       UNKNOWN_LOCATION);
    return PHI_RESULT (phi);
  }
   
*************** tree_optimize_tail_calls_1 (bool opt_tai
*** 933,939 ****
  		set_default_def (param, new_name);
  		phi = create_phi_node (name, first);
  		SSA_NAME_DEF_STMT (name) = phi;
! 		add_phi_arg (phi, new_name, single_pred_edge (first));
  	      }
  	  phis_constructed = true;
  	}
--- 934,941 ----
  		set_default_def (param, new_name);
  		phi = create_phi_node (name, first);
  		SSA_NAME_DEF_STMT (name) = phi;
! 		add_phi_arg (phi, new_name, single_pred_edge (first), 
! 			     EXPR_LOCATION (param));
  	      }
  	  phis_constructed = true;
  	}
Index: tree.h
===================================================================
*** tree.h	(revision 150217)
--- tree.h	(working copy)
*************** struct GTY(()) phi_arg_d {
*** 1888,1893 ****
--- 1888,1894 ----
       pointer arithmetic with it.  See phi_arg_index_from_use.  */
    struct ssa_use_operand_d imm_use;
    tree def;
+   location_t locus;
  };
  
  
Index: tree-phinodes.c
===================================================================
*** tree-phinodes.c	(revision 150217)
--- tree-phinodes.c	(working copy)
*************** make_phi_node (tree var, int len)
*** 231,236 ****
--- 231,238 ----
    for (i = 0; i < capacity; i++)
      {
        use_operand_p  imm;
+ 
+       gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
        imm = gimple_phi_arg_imm_use_ptr (phi, i);
        imm->use = gimple_phi_arg_def_ptr (phi, i);
        imm->prev = NULL;
*************** resize_phi_node (gimple *phi, size_t len
*** 299,304 ****
--- 301,308 ----
    for (i = gimple_phi_num_args (new_phi); i < len; i++)
      {
        use_operand_p imm;
+ 
+       gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
        imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
        imm->use = gimple_phi_arg_def_ptr (new_phi, i);
        imm->prev = NULL;
*************** create_phi_node (tree var, basic_block b
*** 384,390 ****
     PHI points to the reallocated phi node when we return.  */
  
  void
! add_phi_arg (gimple phi, tree def, edge e)
  {
    basic_block bb = e->dest;
  
--- 388,394 ----
     PHI points to the reallocated phi node when we return.  */
  
  void
! add_phi_arg (gimple phi, tree def, edge e, source_location locus)
  {
    basic_block bb = e->dest;
  
*************** add_phi_arg (gimple phi, tree def, edge 
*** 407,412 ****
--- 411,417 ----
      }
  
    SET_PHI_ARG_DEF (phi, e->dest_idx, def);
+   gimple_phi_arg_set_location (phi, e->dest_idx, locus);
  }
  
  
*************** remove_phi_arg_num (gimple phi, int i)
*** 435,440 ****
--- 440,448 ----
        /* Set use on new node, and link into last element's place.  */
        *(new_p->use) = *(old_p->use);
        relink_imm_use (new_p, old_p);
+       /* Move the location as well.  */
+       gimple_phi_arg_set_location (phi, i, 
+ 				   gimple_phi_arg_location (phi, num_elem - 1));
      }
  
    /* Shrink the vector and return.  Note that we do not have to clear
Index: omp-low.c
===================================================================
*** omp-low.c	(revision 150217)
--- omp-low.c	(working copy)
*************** expand_parallel_call (struct omp_region 
*** 3013,3020 ****
  	    {
  	      gimple phi = create_phi_node (tmp_join, bb);
  	      SSA_NAME_DEF_STMT (tmp_join) = phi;
! 	      add_phi_arg (phi, tmp_then, e_then);
! 	      add_phi_arg (phi, tmp_else, e_else);
  	    }
  
  	  val = tmp_join;
--- 3013,3020 ----
  	    {
  	      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);
  	    }
  
  	  val = tmp_join;
*************** expand_omp_for_static_chunk (struct omp_
*** 4508,4513 ****
--- 4508,4514 ----
  	   gsi_next (&psi), ++i)
  	{
  	  gimple nphi;
+ 	  source_location locus;
  
  	  phi = gsi_stmt (psi);
  	  t = gimple_phi_result (phi);
*************** expand_omp_for_static_chunk (struct omp_
*** 4516,4527 ****
  	  SSA_NAME_DEF_STMT (t) = nphi;
  
  	  t = PHI_ARG_DEF_FROM_EDGE (phi, se);
  	  /* A special case -- fd->loop.v is not yet computed in
  	     iter_part_bb, we need to use v_extra instead.  */
  	  if (t == fd->loop.v)
  	    t = v_extra;
! 	  add_phi_arg (nphi, t, ene);
! 	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re);
  	}
        gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
        redirect_edge_var_map_clear (re);
--- 4517,4531 ----
  	  SSA_NAME_DEF_STMT (t) = nphi;
  
  	  t = PHI_ARG_DEF_FROM_EDGE (phi, se);
+ 	  locus = gimple_phi_arg_location_from_edge (phi, se);
+ 
  	  /* A special case -- fd->loop.v is not yet computed in
  	     iter_part_bb, we need to use v_extra instead.  */
  	  if (t == fd->loop.v)
  	    t = v_extra;
! 	  add_phi_arg (nphi, t, ene, locus);
! 	  locus = redirect_edge_var_map_location (vm);
! 	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
  	}
        gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
        redirect_edge_var_map_clear (re);
*************** expand_omp_for_static_chunk (struct omp_
*** 4536,4543 ****
        /* Make phi node for trip.  */
        phi = create_phi_node (trip_main, iter_part_bb);
        SSA_NAME_DEF_STMT (trip_main) = phi;
!       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb));
!       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb));
      }
  
    set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
--- 4540,4549 ----
        /* Make phi node for trip.  */
        phi = create_phi_node (trip_main, iter_part_bb);
        SSA_NAME_DEF_STMT (trip_main) = phi;
!       add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
! 		   UNKNOWN_LOCATION);
!       add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
! 		   UNKNOWN_LOCATION);
      }
  
    set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
Index: tree-vect-loop-manip.c
===================================================================
*** tree-vect-loop-manip.c	(revision 150217)
--- tree-vect-loop-manip.c	(working copy)
*************** slpeel_update_phis_for_duplicate_loop (s
*** 169,183 ****
         !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig);
         gsi_next (&gsi_new), gsi_next (&gsi_orig))
      {
        phi_new = gsi_stmt (gsi_new);
        phi_orig = gsi_stmt (gsi_orig);
  
        /* step 1.  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
!       add_phi_arg (phi_new, def, new_loop_entry_e);
  
        /* step 2.  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
        if (TREE_CODE (def) != SSA_NAME)
          continue;
  
--- 169,186 ----
         !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig);
         gsi_next (&gsi_new), gsi_next (&gsi_orig))
      {
+       source_location locus;
        phi_new = gsi_stmt (gsi_new);
        phi_orig = gsi_stmt (gsi_orig);
  
        /* step 1.  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
!       locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e);
!       add_phi_arg (phi_new, def, new_loop_entry_e, locus);
  
        /* step 2.  */
        def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
+       locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
        if (TREE_CODE (def) != SSA_NAME)
          continue;
  
*************** slpeel_update_phis_for_duplicate_loop (s
*** 190,196 ****
  	}
  
        /* An ordinary ssa name defined in the loop.  */
!       add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
  
        /* step 3 (case 1).  */
        if (!after)
--- 193,199 ----
  	}
  
        /* An ordinary ssa name defined in the loop.  */
!       add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
  
        /* step 3 (case 1).  */
        if (!after)
*************** slpeel_update_phi_nodes_for_guard1 (edge
*** 383,388 ****
--- 386,392 ----
         !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update);
         gsi_next (&gsi_orig), gsi_next (&gsi_update))
      {
+       source_location loop_locus, guard_locus;;
        orig_phi = gsi_stmt (gsi_orig);
        update_phi = gsi_stmt (gsi_update);
  
*************** slpeel_update_phi_nodes_for_guard1 (edge
*** 395,404 ****
        /* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
              of LOOP. Set the two phi args in NEW_PHI for these edges:  */
        loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0));
        guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop));
  
!       add_phi_arg (new_phi, loop_arg, new_exit_e);
!       add_phi_arg (new_phi, guard_arg, guard_edge);
  
        /* 1.3. Update phi in successor block.  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
--- 399,414 ----
        /* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
              of LOOP. Set the two phi args in NEW_PHI for these edges:  */
        loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0));
+       loop_locus = gimple_phi_arg_location_from_edge (orig_phi, 
+ 						      EDGE_SUCC (loop->latch, 
+ 								 0));
        guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop));
+       guard_locus 
+ 	= gimple_phi_arg_location_from_edge (orig_phi, 
+ 					     loop_preheader_edge (loop));
  
!       add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus);
!       add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus);
  
        /* 1.3. Update phi in successor block.  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
*************** slpeel_update_phi_nodes_for_guard1 (edge
*** 417,423 ****
                                   *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));
  
        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
--- 427,433 ----
                                   *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);
  
        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
*************** slpeel_update_phi_nodes_for_guard2 (edge
*** 545,552 ****
        if (new_name2)
          guard_arg = new_name2;
    
!       add_phi_arg (new_phi, loop_arg, new_exit_e);
!       add_phi_arg (new_phi, guard_arg, guard_edge);
  
        /* 1.3. Update phi in successor block.  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
--- 555,562 ----
        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);
  
        /* 1.3. Update phi in successor block.  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
*************** slpeel_update_phi_nodes_for_guard2 (edge
*** 561,567 ****
                                   *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));
  
        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
--- 571,577 ----
                                   *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);
  
        /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
*************** slpeel_update_phi_nodes_for_guard2 (edge
*** 596,602 ****
  
        /* 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));
  
        /* 3.4. Update phi in successor of GUARD_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
--- 606,613 ----
  
        /* 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);
  
        /* 3.4. Update phi in successor of GUARD_BB:  */
        gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 720,732 ****
        if (phi_arg)
  	{
  	  edge new_loop_exit_edge;
  
  	  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);	
  	}
      }    
     
--- 731,745 ----
        if (phi_arg)
  	{
  	  edge new_loop_exit_edge;
+ 	  source_location locus;
  
+ 	  locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop));
  	  if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
  	    new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
  	  else
  	    new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
    
! 	  add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus);	
  	}
      }    
     
*************** slpeel_tree_duplicate_loop_to_edge_cfg (
*** 764,770 ****
  	  phi = gsi_stmt (gsi);
  	  phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
  	  if (phi_arg)
! 	    add_phi_arg (phi, phi_arg, new_exit_e);	
  	}    
  
        redirect_edge_and_branch_force (entry_e, new_loop->header);
--- 777,784 ----
  	  phi = gsi_stmt (gsi);
  	  phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
  	  if (phi_arg)
! 	    add_phi_arg (phi, phi_arg, new_exit_e,
! 			 gimple_phi_arg_location_from_edge (phi, entry_e));	
  	}    
  
        redirect_edge_and_branch_force (entry_e, new_loop->header);
*************** set_prologue_iterations (basic_block bb_
*** 954,961 ****
      gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
  
    newphi = create_phi_node (var, bb_before_first_loop);
!   add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru);
!   add_phi_arg (newphi, first_niters, e_false);
  
    first_niters = PHI_RESULT (newphi);
  }
--- 968,976 ----
      gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
  
    newphi = create_phi_node (var, bb_before_first_loop);
!   add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru, 
! 	       UNKNOWN_LOCATION);
!   add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION);
  
    first_niters = PHI_RESULT (newphi);
  }
*************** vect_loop_versioning (loop_vec_info loop
*** 2383,2389 ****
        new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
  				  new_exit_bb);
        arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
!       add_phi_arg (new_phi, arg, new_exit_e);
        SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
      } 
  
--- 2398,2405 ----
        new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
  				  new_exit_bb);
        arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
!       add_phi_arg (new_phi, arg, new_exit_e, 
! 		   gimple_phi_arg_location_from_edge (orig_phi, e));
        SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
      } 
  
Index: tree-parloops.c
===================================================================
*** tree-parloops.c	(revision 150217)
--- tree-parloops.c	(working copy)
*************** create_phi_for_local_result (void **slot
*** 900,905 ****
--- 900,906 ----
    gimple new_phi;
    basic_block store_bb;
    tree local_res;
+   source_location locus;
  
    /* STORE_BB is the block where the phi 
       should be stored.  It is the destination of the loop exit.  
*************** create_phi_for_local_result (void **slot
*** 918,928 ****
    local_res
      = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
  		     NULL);
    new_phi = create_phi_node (local_res, store_bb);
    SSA_NAME_DEF_STMT (local_res) = new_phi;
!   add_phi_arg (new_phi, reduc->init, e);
    add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
! 	       FALLTHRU_EDGE (loop->latch));
    reduc->new_phi = new_phi;
  
    return 1;
--- 919,930 ----
    local_res
      = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
  		     NULL);
+   locus = gimple_location (reduc->reduc_stmt);
    new_phi = create_phi_node (local_res, store_bb);
    SSA_NAME_DEF_STMT (local_res) = new_phi;
!   add_phi_arg (new_phi, reduc->init, e, locus);
    add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
! 	       FALLTHRU_EDGE (loop->latch), locus);
    reduc->new_phi = new_phi;
  
    return 1;
*************** transform_to_exit_first_loop (struct loo
*** 1480,1486 ****
  
        nphi = create_phi_node (res, orig_header);
        SSA_NAME_DEF_STMT (res) = nphi;
!       add_phi_arg (nphi, t, hpred);
  
        if (res == control)
  	{
--- 1482,1488 ----
  
        nphi = create_phi_node (res, orig_header);
        SSA_NAME_DEF_STMT (res) = nphi;
!       add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
  
        if (res == control)
  	{
*************** create_parallel_loop (struct loop *loop,
*** 1631,1644 ****
    end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
    for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        phi = gsi_stmt (gsi);
        res = PHI_RESULT (phi);
        stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
!       add_phi_arg (phi,
! 		   PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)),
! 		   guard);
!       add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)),
! 		   end);
      }
    e = redirect_edge_and_branch (exit, nexit->dest);
    PENDING_STMT (e) = NULL;
--- 1633,1652 ----
    end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
    for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
      {
+       source_location locus;
+       tree def;
        phi = gsi_stmt (gsi);
        res = PHI_RESULT (phi);
        stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
! 
!       def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop));
!       locus = gimple_phi_arg_location_from_edge (stmt, 
! 						 loop_preheader_edge (loop));
!       add_phi_arg (phi, def, guard, locus);
! 
!       def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop));
!       locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop));
!       add_phi_arg (phi, def, end, locus);
      }
    e = redirect_edge_and_branch (exit, nexit->dest);
    PENDING_STMT (e) = NULL;
Index: gimple-pretty-print.c
===================================================================
*** gimple-pretty-print.c	(revision 150217)
--- gimple-pretty-print.c	(working copy)
*************** dump_gimple_phi (pretty_printer *buffer,
*** 1150,1155 ****
--- 1150,1171 ----
      }
    for (i = 0; i < gimple_phi_num_args (phi); i++)
      {
+       if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i))
+         {
+ 	  expanded_location xloc;
+ 
+ 	  xloc = expand_location (gimple_phi_arg_location (phi, i));
+ 	  pp_character (buffer, '[');
+ 	  if (xloc.file)
+ 	    {
+ 	      pp_string (buffer, xloc.file);
+ 	      pp_string (buffer, " : ");
+ 	    }
+ 	  pp_decimal_int (buffer, xloc.line);
+ 	  pp_string (buffer, ":");
+ 	  pp_decimal_int (buffer, xloc.column);
+ 	  pp_string (buffer, "] ");
+ 	}
        dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
  			 false);
        pp_character (buffer, '(');
Index: tree-vect-loop.c
===================================================================
*** tree-vect-loop.c	(revision 150217)
--- tree-vect-loop.c	(working copy)
*************** get_initial_def_for_induction (gimple iv
*** 2524,2531 ****
                                                     NULL));
  
    /* Set the arguments of the phi node:  */
!   add_phi_arg (induction_phi, vec_init, pe);
!   add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop));
  
  
    /* In case that vectorization factor (VF) is bigger than the number
--- 2524,2532 ----
                                                     NULL));
  
    /* Set the arguments of the phi node:  */
!   add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
!   add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), 
! 	       UNKNOWN_LOCATION);
  
  
    /* In case that vectorization factor (VF) is bigger than the number
*************** vect_create_epilog_for_reduction (tree v
*** 2934,2945 ****
    for (j = 0; j < ncopies; j++)
      {
        /* 1.1 set the loop-entry arg of the reduction-phi:  */
!       add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop));
  
        /* 1.2 set the loop-latch arg for the reduction-phi:  */
        if (j > 0)
          def = vect_get_vec_def_for_stmt_copy (dt, def);
!       add_phi_arg (phi, def, loop_latch_edge (loop));
  
        if (vect_print_dump_info (REPORT_DETAILS))
  	{
--- 2935,2947 ----
    for (j = 0; j < ncopies; j++)
      {
        /* 1.1 set the loop-entry arg of the reduction-phi:  */
!       add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop), 
! 		   UNKNOWN_LOCATION);
  
        /* 1.2 set the loop-latch arg for the reduction-phi:  */
        if (j > 0)
          def = vect_get_vec_def_for_stmt_copy (dt, def);
!       add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
  
        if (vect_print_dump_info (REPORT_DETAILS))
  	{
*************** vect_finalize_reduction:
*** 3350,3358 ****
                 
                /* Update phi node arguments with vs0 and vs2.  */
                add_phi_arg (vect_phi, vect_phi_init, 
!                            loop_preheader_edge (outer_loop));
                add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), 
!                            loop_latch_edge (outer_loop));
                if (vect_print_dump_info (REPORT_DETAILS))
                  {
                    fprintf (vect_dump, "created double reduction phi node: ");
--- 3352,3360 ----
                 
                /* Update phi node arguments with vs0 and vs2.  */
                add_phi_arg (vect_phi, vect_phi_init, 
!                            loop_preheader_edge (outer_loop), UNKNOWN_LOCATION);
                add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), 
!                            loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
                if (vect_print_dump_info (REPORT_DETAILS))
                  {
                    fprintf (vect_dump, "created double reduction phi node: ");
Index: tree-flow-inline.h
===================================================================
*** tree-flow-inline.h	(revision 150217)
--- tree-flow-inline.h	(working copy)
*************** gimple_phi_arg_edge (gimple gs, size_t i
*** 455,460 ****
--- 455,493 ----
    return EDGE_PRED (gimple_bb (gs), i);
  }
  
+ /* Return the source location of gimple argument I of phi node GS.  */
+ 
+ static inline source_location
+ gimple_phi_arg_location (gimple gs, size_t i)
+ {
+   return gimple_phi_arg (gs, i)->locus;
+ }
+ 
+ /* Return the source location of the argument on edge E of phi node GS.  */
+ 
+ static inline source_location
+ gimple_phi_arg_location_from_edge (gimple gs, edge e)
+ {
+   return gimple_phi_arg (gs, e->dest_idx)->locus;
+ }
+ 
+ /* Set the source location of gimple argument I of phi node GS to LOC.  */
+ 
+ static inline void
+ gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc)
+ {
+   gimple_phi_arg (gs, i)->locus = loc;
+ }
+ 
+ /* Return TRUE if argument I of phi node GS has a location record.  */
+ 
+ static inline bool
+ gimple_phi_arg_has_location (gimple gs, size_t i)
+ {
+   return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
+ }
+ 
+ 
  /* Return the PHI nodes for basic block BB, or NULL if there are no
     PHI nodes.  */
  static inline gimple_seq
*************** redirect_edge_var_map_result (edge_var_m
*** 1196,1201 ****
--- 1229,1242 ----
    return v->result;
  }
  
+ /* Given an edge_var_map V, return the PHI arg location.  */
+ 
+ static inline source_location
+ redirect_edge_var_map_location (edge_var_map *v)
+ {
+   return v->locus;
+ }
+ 
  
  /* Return an SSA_NAME node for variable VAR defined in statement STMT
     in function cfun.  */
Index: tree-vect-data-refs.c
===================================================================
*** tree-vect-data-refs.c	(revision 150217)
--- tree-vect-data-refs.c	(working copy)
*************** vect_setup_realignment (gimple stmt, gim
*** 3049,3055 ****
    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);
  
    return msq;
  }
--- 3049,3055 ----
    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);
  
    return msq;
  }
Index: tree-ssa-phiopt.c
===================================================================
*** tree-ssa-phiopt.c	(revision 150217)
--- tree-ssa-phiopt.c	(working copy)
*************** conditional_replacement (basic_block con
*** 513,518 ****
--- 513,520 ----
  
    if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
      {
+       source_location locus_0, locus_1;
+ 
        new_var2 = create_tmp_var (TREE_TYPE (result), NULL);
        add_referenced_var (new_var2);
        new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
*************** conditional_replacement (basic_block con
*** 521,526 ****
--- 523,535 ----
        gimple_assign_set_lhs (new_stmt, new_var2);
        gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
        new_var = new_var2;
+ 
+       /* Set the locus to the first argument, unless is doesn't have one.  */
+       locus_0 = gimple_phi_arg_location (phi, 0);
+       locus_1 = gimple_phi_arg_location (phi, 1);
+       if (locus_0 == UNKNOWN_LOCATION)
+         locus_0 = locus_1;
+       gimple_set_location (new_stmt, locus_0);
      }
  
    replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
*************** cond_store_replacement (basic_block midd
*** 1177,1182 ****
--- 1186,1192 ----
    tree lhs, rhs, name;
    gimple newphi, new_stmt;
    gimple_stmt_iterator gsi;
+   source_location locus;
    enum tree_code code;
  
    /* Check if middle_bb contains of only one store.  */
*************** cond_store_replacement (basic_block midd
*** 1184,1189 ****
--- 1194,1200 ----
        || gimple_code (assign) != GIMPLE_ASSIGN)
      return false;
  
+   locus = gimple_location (assign);
    lhs = gimple_assign_lhs (assign);
    rhs = gimple_assign_rhs1 (assign);
    if (!INDIRECT_REF_P (lhs))
*************** cond_store_replacement (basic_block midd
*** 1224,1229 ****
--- 1235,1241 ----
    new_stmt = gimple_build_assign (condstoretemp, lhs);
    name = make_ssa_name (condstoretemp, new_stmt);
    gimple_assign_set_lhs (new_stmt, name);
+   gimple_set_location (new_stmt, locus);
    mark_symbols_for_renaming (new_stmt);
    gsi_insert_on_edge (e1, new_stmt);
  
*************** cond_store_replacement (basic_block midd
*** 1231,1238 ****
          holding the old RHS, and the other holding the temporary
          where we stored the old memory contents.  */
    newphi = create_phi_node (condstoretemp, join_bb);
!   add_phi_arg (newphi, rhs, e0);
!   add_phi_arg (newphi, name, e1);
  
    lhs = unshare_expr (lhs);
    new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
--- 1243,1250 ----
          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);
  
    lhs = unshare_expr (lhs);
    new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
Index: cfgexpand.c
===================================================================
*** cfgexpand.c	(revision 150217)
--- cfgexpand.c	(working copy)
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 74,79 ****
--- 74,82 ----
    else
      gcc_unreachable ();
  
+   if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
+     SET_EXPR_LOCATION (t, gimple_location (stmt));
+ 
    return t;
  }
  
Index: graphite.c
===================================================================
*** graphite.c	(revision 150217)
--- graphite.c	(working copy)
*************** add_loop_exit_phis (void **slot, void *s
*** 4555,4561 ****
    tree res = create_new_def_for (gimple_phi_result (phi), phi,
  				 gimple_phi_result_ptr (phi));
  
!   add_phi_arg (phi, new_name, single_pred_edge (bb));
  
    entry->new_name = res;
    *slot = entry;
--- 4555,4561 ----
    tree res = create_new_def_for (gimple_phi_result (phi), phi,
  				 gimple_phi_result_ptr (phi));
  
!   add_phi_arg (phi, new_name, single_pred_edge (bb), UNKNOWN_LOCATION);
  
    entry->new_name = res;
    *slot = entry;
*************** add_guard_exit_phis (void **slot, void *
*** 4617,4624 ****
    tree res = create_new_def_for (gimple_phi_result (phi), phi,
  				 gimple_phi_result_ptr (phi));
  
!   add_phi_arg (phi, name1, true_edge);
!   add_phi_arg (phi, name2, false_edge);
  
    entry->new_name = res;
    *slot = entry;
--- 4617,4624 ----
    tree res = create_new_def_for (gimple_phi_result (phi), phi,
  				 gimple_phi_result_ptr (phi));
  
!   add_phi_arg (phi, name1, true_edge, UNKNOWN_LOCATION);
!   add_phi_arg (phi, name2, false_edge, UNKNOWN_LOCATION);
  
    entry->new_name = res;
    *slot = entry;
*************** scop_add_exit_phis_edge (basic_block exi
*** 5141,5148 ****
  
    create_new_def_for (gimple_phi_result (phi), phi,
  		      gimple_phi_result_ptr (phi));
!   add_phi_arg (phi, use, false_e);
!   add_phi_arg (phi, use, true_e);
  }
  
  /* Add phi nodes for VAR that is used in LIVEIN.  Phi nodes are
--- 5141,5148 ----
  
    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 nodes for VAR that is used in LIVEIN.  Phi nodes are
Index: tree-cfgcleanup.c
===================================================================
*** tree-cfgcleanup.c	(revision 150217)
--- tree-cfgcleanup.c	(working copy)
*************** remove_forwarder_block (basic_block bb)
*** 401,407 ****
  	       gsi_next (&gsi))
  	    {
  	      gimple phi = gsi_stmt (gsi);
! 	      add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s);
  	    }
  	}
      }
--- 401,408 ----
  	       gsi_next (&gsi))
  	    {
  	      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);
  	    }
  	}
      }
*************** remove_forwarder_block_with_phi (basic_b
*** 744,749 ****
--- 745,751 ----
  	{
  	  gimple phi = gsi_stmt (gsi);
  	  tree def = gimple_phi_arg_def (phi, succ->dest_idx);
+ 	  source_location locus = gimple_phi_arg_location_from_edge (phi, succ);
  
  	  if (TREE_CODE (def) == SSA_NAME)
  	    {
*************** remove_forwarder_block_with_phi (basic_b
*** 763,774 ****
  		  if (def == old_arg)
  		    {
  		      def = new_arg;
  		      break;
  		    }
  		}
  	    }
  
! 	  add_phi_arg (phi, def, s);
  	}
  
        redirect_edge_var_map_clear (e);
--- 765,777 ----
  		  if (def == old_arg)
  		    {
  		      def = new_arg;
+ 		      locus = redirect_edge_var_map_location (vm);
  		      break;
  		    }
  		}
  	    }
  
! 	  add_phi_arg (phi, def, s, locus);
  	}
  
        redirect_edge_var_map_clear (e);
Index: tree-ssa-pre.c
===================================================================
*** tree-ssa-pre.c	(revision 150217)
--- tree-ssa-pre.c	(working copy)
*************** insert_into_preds_of_block (basic_block 
*** 3328,3336 ****
        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);
        else
! 	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred);
      }
  
    newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
--- 3328,3337 ----
        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);
        else
! 	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
! 		     UNKNOWN_LOCATION);
      }
  
    newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
Index: tree-predcom.c
===================================================================
*** tree-predcom.c	(revision 150217)
--- tree-predcom.c	(working copy)
*************** initialize_root_vars (struct loop *loop,
*** 1512,1519 ****
  
        phi = create_phi_node (var, loop->header);
        SSA_NAME_DEF_STMT (var) = phi;
!       add_phi_arg (phi, init, entry);
!       add_phi_arg (phi, next, latch);
      }
  }
  
--- 1512,1519 ----
  
        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);
      }
  }
  
*************** initialize_root_vars_lm (struct loop *lo
*** 1576,1583 ****
        next = VEC_index (tree, *vars, 1);
        phi = create_phi_node (var, loop->header);
        SSA_NAME_DEF_STMT (var) = phi;
!       add_phi_arg (phi, init, entry);
!       add_phi_arg (phi, next, latch);
      }
    else
      {
--- 1576,1583 ----
        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);
      }
    else
      {
Index: tree-ssa-dce.c
===================================================================
*** tree-ssa-dce.c	(revision 150217)
--- tree-ssa-dce.c	(working copy)
*************** forward_edge_to_pdom (edge e, basic_bloc
*** 951,956 ****
--- 951,957 ----
  	{
  	  gimple phi = gsi_stmt (gsi);
  	  tree op;
+ 	  source_location locus;
  
  	  /* Dead PHI do not imply control dependency.  */
            if (!gimple_plf (phi, STMT_NECESSARY)
*************** forward_edge_to_pdom (edge e, basic_bloc
*** 975,984 ****
  	      continue;
  	    }
  	  if (!e2)
! 	    op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
  	  else
! 	    op = gimple_phi_arg_def (phi, e2->dest_idx);
! 	  add_phi_arg (phi, op, e);
  	  gcc_assert (e2 || degenerate_phi_p (phi));
  	  gsi_next (&gsi);
  	}
--- 976,991 ----
  	      continue;
  	    }
  	  if (!e2)
! 	    {
! 	      op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
! 	      locus = gimple_phi_arg_location (phi, e->dest_idx == 0 ? 1 : 0);
! 	    }
  	  else
! 	    {
! 	      op = gimple_phi_arg_def (phi, e2->dest_idx);
! 	      locus = gimple_phi_arg_location (phi, e2->dest_idx);
! 	    }
! 	  add_phi_arg (phi, op, e, locus);
  	  gcc_assert (e2 || degenerate_phi_p (phi));
  	  gsi_next (&gsi);
  	}
Index: tree-ssa.c
===================================================================
*** tree-ssa.c	(revision 150217)
--- tree-ssa.c	(working copy)
*************** static struct pointer_map_t *edge_var_ma
*** 53,59 ****
  /* 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)
  {
    void **slot;
    edge_var_map_vector old_head, head;
--- 53,59 ----
  /* 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)
  {
    void **slot;
    edge_var_map_vector old_head, head;
*************** redirect_edge_var_map_add (edge e, tree 
*** 71,76 ****
--- 71,77 ----
      }
    new_node.def = def;
    new_node.result = result;
+   new_node.locus = locus;
  
    VEC_safe_push (edge_var_map, heap, head, &new_node);
    if (old_head != head)
*************** ssa_redirect_edge (edge e, basic_block d
*** 193,206 ****
    for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        tree def;
  
        phi = gsi_stmt (gsi);
        def = gimple_phi_arg_def (phi, e->dest_idx);
  
        if (def == NULL_TREE)
  	continue;
  
!       redirect_edge_var_map_add (e, gimple_phi_result (phi), def);
      }
  
    e = redirect_edge_succ_nodup (e, dest);
--- 194,209 ----
    for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        tree def;
+       source_location locus ;
  
        phi = gsi_stmt (gsi);
        def = gimple_phi_arg_def (phi, e->dest_idx);
+       locus = gimple_phi_arg_location (phi, e->dest_idx);
  
        if (def == NULL_TREE)
  	continue;
  
!       redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
      }
  
    e = redirect_edge_succ_nodup (e, dest);
*************** flush_pending_stmts (edge e)
*** 233,239 ****
  
        phi = gsi_stmt (gsi);
        def = redirect_edge_var_map_def (vm);
!       add_phi_arg (phi, def, e);
      }
  
    redirect_edge_var_map_clear (e);
--- 236,242 ----
  
        phi = gsi_stmt (gsi);
        def = redirect_edge_var_map_def (vm);
!       add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
      }
  
    redirect_edge_var_map_clear (e);
Index: lambda-code.c
===================================================================
*** lambda-code.c	(revision 150217)
--- lambda-code.c	(working copy)
*************** can_convert_to_perfect_nest (struct loop
*** 2343,2348 ****
--- 2343,2352 ----
    return false;
  }
  
+ 
+ DEF_VEC_I(source_location);
+ DEF_VEC_ALLOC_I(source_location,heap);
+ 
  /* Transform the loop nest into a perfect nest, if possible.
     LOOP is the loop nest to transform into a perfect nest
     LBOUNDS are the lower bounds for the loops to transform
*************** perfect_nestify (struct loop *loop,
*** 2400,2405 ****
--- 2404,2410 ----
    gimple stmt;
    tree oldivvar, ivvar, ivvarinced;
    VEC(tree,heap) *phis = NULL;
+   VEC(source_location,heap) *locations = NULL;
    htab_t replacements = NULL;
  
    /* Create the new loop.  */
*************** perfect_nestify (struct loop *loop,
*** 2412,2419 ****
--- 2417,2427 ----
      {
        phi = gsi_stmt (bsi);
        VEC_reserve (tree, heap, phis, 2);
+       VEC_reserve (source_location, heap, locations, 1);
        VEC_quick_push (tree, phis, PHI_RESULT (phi));
        VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0));
+       VEC_quick_push (source_location, locations, 
+ 		      gimple_phi_arg_location (phi, 0));
      }
    e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb);
  
*************** perfect_nestify (struct loop *loop,
*** 2426,2435 ****
      {
        tree def;
        tree phiname;
        def = VEC_pop (tree, phis);
        phiname = VEC_pop (tree, phis);      
        phi = create_phi_node (phiname, preheaderbb);
!       add_phi_arg (phi, def, single_pred_edge (preheaderbb));
      }
    flush_pending_stmts (e);
    VEC_free (tree, heap, phis);
--- 2434,2445 ----
      {
        tree def;
        tree phiname;
+       source_location locus;
        def = VEC_pop (tree, phis);
        phiname = VEC_pop (tree, phis);      
+       locus = VEC_pop (source_location, locations);
        phi = create_phi_node (phiname, preheaderbb);
!       add_phi_arg (phi, def, single_pred_edge (preheaderbb), locus);
      }
    flush_pending_stmts (e);
    VEC_free (tree, heap, phis);
Index: tree-vect-stmts.c
===================================================================
*** tree-vect-stmts.c	(revision 150217)
--- tree-vect-stmts.c	(working copy)
*************** vectorizable_load (gimple stmt, gimple_s
*** 3639,3645 ****
  		{
  		  gcc_assert (phi);
  		  if (i == vec_num - 1 && j == ncopies - 1)
! 		    add_phi_arg (phi, lsq, loop_latch_edge (containing_loop));
  		  msq = lsq;
  		}
  	    }
--- 3639,3646 ----
  		{
  		  gcc_assert (phi);
  		  if (i == vec_num - 1 && j == ncopies - 1)
! 		    add_phi_arg (phi, lsq, loop_latch_edge (containing_loop),
! 				 UNKNOWN_LOCATION);
  		  msq = lsq;
  		}
  	    }
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 150217)
--- tree-inline.c	(working copy)
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1826,1832 ****
  		  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
  		  gsi_insert_seq_on_edge_immediate (new_edge, stmts);
  		}
! 	      add_phi_arg (new_phi, new_arg, new_edge);
  	    }
  	}
      }
--- 1826,1833 ----
  		  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
  		  gsi_insert_seq_on_edge_immediate (new_edge, stmts);
  		}
! 	      add_phi_arg (new_phi, new_arg, new_edge, 
! 			   gimple_phi_arg_location_from_edge (phi, old_edge));
  	    }
  	}
      }
*************** insert_init_stmt (basic_block bb, gimple
*** 2087,2093 ****
     output later.  */
  static gimple
  setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
! 		     basic_block bb, tree *vars)
  {
    gimple init_stmt = NULL;
    tree var;
--- 2088,2094 ----
     output later.  */
  static gimple
  setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn,
! 		     basic_block bb, tree *vars, source_location call_locus)
  {
    gimple init_stmt = NULL;
    tree var;
*************** setup_one_parameter (copy_body_data *id,
*** 2232,2237 ****
--- 2233,2241 ----
        else
          init_stmt = gimple_build_assign (var, rhs);
  
+       /* Set the source location.  */
+       gimple_set_location (init_stmt, call_locus);
+ 
        if (bb && init_stmt)
          insert_init_stmt (bb, init_stmt);
      }
*************** initialize_inlined_parameters (copy_body
*** 2250,2255 ****
--- 2254,2261 ----
    tree p;
    tree vars = NULL_TREE;
    tree static_chain = gimple_call_chain (stmt);
+   source_location locus = gimple_location (stmt);
+   
  
    /* Figure out what the parameters are.  */
    parms = DECL_ARGUMENTS (fn);
*************** initialize_inlined_parameters (copy_body
*** 2260,2266 ****
      {
        tree val;
        val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
!       setup_one_parameter (id, p, val, fn, bb, &vars);
      }
  
    /* Initialize the static chain.  */
--- 2266,2272 ----
      {
        tree val;
        val = i < gimple_call_num_args (stmt) ? gimple_call_arg (stmt, i) : NULL;
!       setup_one_parameter (id, p, val, fn, bb, &vars, locus);
      }
  
    /* Initialize the static chain.  */
*************** initialize_inlined_parameters (copy_body
*** 2271,2277 ****
        /* No static chain?  Seems like a bug in tree-nested.c.  */
        gcc_assert (static_chain);
  
!       setup_one_parameter (id, p, static_chain, fn, bb, &vars);
      }
  
    declare_inline_vars (id->block, vars);
--- 2277,2283 ----
        /* No static chain?  Seems like a bug in tree-nested.c.  */
        gcc_assert (static_chain);
  
!       setup_one_parameter (id, p, static_chain, fn, bb, &vars, locus);
      }
  
    declare_inline_vars (id->block, vars);
*************** tree_function_versioning (tree old_decl,
*** 4587,4593 ****
  	    init = setup_one_parameter (&id, replace_info->old_tree,
  	    			        replace_info->new_tree, id.src_fn,
  				        NULL,
! 				        &vars);
  	    if (init)
  	      VEC_safe_push (gimple, heap, init_stmts, init);
  	  }
--- 4593,4600 ----
  	    init = setup_one_parameter (&id, replace_info->old_tree,
  	    			        replace_info->new_tree, id.src_fn,
  				        NULL,
! 				        &vars,
! 					UNKNOWN_LOCATION);
  	    if (init)
  	      VEC_safe_push (gimple, heap, init_stmts, init);
  	  }
Index: tree-ssa-phiprop.c
===================================================================
*** tree-ssa-phiprop.c	(revision 150217)
--- tree-ssa-phiprop.c	(working copy)
*************** phiprop_insert_phi (basic_block bb, gimp
*** 159,172 ****
--- 159,175 ----
      {
        tree old_arg, new_var;
        gimple tmp;
+       source_location locus;
  
        old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+       locus = gimple_phi_arg_location_from_edge (phi, e);
        while (TREE_CODE (old_arg) == SSA_NAME
  	     && (SSA_NAME_VERSION (old_arg) >= n
  	         || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
  	{
  	  gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
  	  old_arg = gimple_assign_rhs1 (def_stmt);
+ 	  locus = gimple_location (def_stmt);
  	}
  
        if (TREE_CODE (old_arg) == SSA_NAME)
*************** phiprop_insert_phi (basic_block bb, gimp
*** 196,201 ****
--- 199,205 ----
  	  add_referenced_var (new_var);
  	  new_var = make_ssa_name (new_var, tmp);
  	  gimple_assign_set_lhs (tmp, new_var);
+ 	  gimple_set_location (tmp, locus);
  
  	  gsi_insert_on_edge (e, tmp);
  	  update_stmt (tmp);
*************** phiprop_insert_phi (basic_block bb, gimp
*** 209,215 ****
  	    }
  	}
  
!       add_phi_arg (new_phi, new_var, e);
      }
  
    update_stmt (new_phi);
--- 213,219 ----
  	    }
  	}
  
!       add_phi_arg (new_phi, new_var, e, locus);
      }
  
    update_stmt (new_phi);
Index: tree-outof-ssa.c
===================================================================
*** tree-outof-ssa.c	(revision 150217)
--- tree-outof-ssa.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 36,41 ****
--- 36,44 ----
  #include "ssaexpand.h"
  
  
+ DEF_VEC_I(source_location);
+ DEF_VEC_ALLOC_I(source_location,heap);
+ 
  /* Used to hold all the components required to do SSA PHI elimination.
     The node and pred/succ list is a simple linear list of nodes and
     edges represented as pairs of nodes.
*************** typedef struct _elim_graph {
*** 67,72 ****
--- 70,78 ----
    /*  The predecessor and successor edge list.  */
    VEC(int,heap) *edge_list;
  
+   /* Source locus on each edge */
+   VEC(source_location,heap) *edge_locus;
+ 
    /* Visited vector.  */
    sbitmap visited;
  
*************** typedef struct _elim_graph {
*** 82,87 ****
--- 88,96 ----
    /* List of constant copies to emit.  These are pushed on in pairs.  */
    VEC(int,heap) *const_dests;
    VEC(tree,heap) *const_copies;
+ 
+   /* Source locations for any constant copies.  */
+   VEC(source_location,heap) *copy_locus;
  } *elim_graph;
  
  
*************** emit_partition_copy (rtx dest, rtx src, 
*** 150,156 ****
  /* 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)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 159,165 ----
  /* 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)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** insert_partition_copy_on_edge (edge e, i
*** 167,172 ****
--- 176,184 ----
    gcc_assert (SA.partition_to_pseudo[src]);
  
    set_location_for_edge (e);
+   /* If a locus is provided, override the default.  */
+   if (locus)
+     set_curr_insn_source_location (locus);
  
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
  			     SA.partition_to_pseudo[src],
*************** insert_partition_copy_on_edge (edge e, i
*** 180,186 ****
     onto edge E.  */
  
  static void
! insert_value_copy_on_edge (edge e, int dest, tree src)
  {
    rtx seq, x;
    enum machine_mode mode;
--- 192,198 ----
     onto edge E.  */
  
  static void
! insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
  {
    rtx seq, x;
    enum machine_mode mode;
*************** insert_value_copy_on_edge (edge e, int d
*** 197,202 ****
--- 209,217 ----
    gcc_assert (SA.partition_to_pseudo[dest]);
  
    set_location_for_edge (e);
+   /* If a locus is provided, override the default.  */
+   if (locus)
+     set_curr_insn_source_location (locus);
  
    start_sequence ();
    mode = GET_MODE (SA.partition_to_pseudo[dest]);
*************** insert_value_copy_on_edge (edge e, int d
*** 219,225 ****
     onto edge E.  */
  
  static void
! insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 234,241 ----
     onto edge E.  */
  
  static void
! insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
! 			    source_location locus)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** insert_rtx_to_part_on_edge (edge e, int 
*** 233,239 ****
--- 249,259 ----
      }
  
    gcc_assert (SA.partition_to_pseudo[dest]);
+ 
    set_location_for_edge (e);
+   /* If a locus is provided, override the default.  */
+   if (locus)
+     set_curr_insn_source_location (locus);
  
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
  			     src,
*************** insert_rtx_to_part_on_edge (edge e, int 
*** 246,252 ****
     onto edge E.  */
  
  static void
! insert_part_to_rtx_on_edge (edge e, rtx dest, int src)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
--- 266,272 ----
     onto edge E.  */
  
  static void
! insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
  {
    rtx seq;
    if (dump_file && (dump_flags & TDF_DETAILS))
*************** insert_part_to_rtx_on_edge (edge e, rtx 
*** 260,266 ****
--- 280,290 ----
      }
  
    gcc_assert (SA.partition_to_pseudo[src]);
+ 
    set_location_for_edge (e);
+   /* If a locus is provided, override the default.  */
+   if (locus)
+     set_curr_insn_source_location (locus);
  
    seq = emit_partition_copy (dest,
  			     SA.partition_to_pseudo[src],
*************** new_elim_graph (int size)
*** 282,288 ****
--- 306,314 ----
    g->nodes = VEC_alloc (int, heap, 30);
    g->const_dests = VEC_alloc (int, heap, 20);
    g->const_copies = VEC_alloc (tree, heap, 20);
+   g->copy_locus = VEC_alloc (source_location, heap, 10);
    g->edge_list = VEC_alloc (int, heap, 20);
+   g->edge_locus = VEC_alloc (source_location, heap, 10);
    g->stack = VEC_alloc (int, heap, 30);
    
    g->visited = sbitmap_alloc (size);
*************** clear_elim_graph (elim_graph g)
*** 298,303 ****
--- 324,330 ----
  {
    VEC_truncate (int, g->nodes, 0);
    VEC_truncate (int, g->edge_list, 0);
+   VEC_truncate (source_location, g->edge_locus, 0);
  }
  
  
*************** delete_elim_graph (elim_graph g)
*** 312,317 ****
--- 339,347 ----
    VEC_free (tree, heap, g->const_copies);
    VEC_free (int, heap, g->const_dests);
    VEC_free (int, heap, g->nodes);
+   VEC_free (source_location, heap, g->copy_locus);
+   VEC_free (source_location, heap, g->edge_locus);
+ 
    free (g);
  }
  
*************** elim_graph_add_node (elim_graph g, int n
*** 343,352 ****
  /* Add the edge PRED->SUCC to graph G.  */
  
  static inline void
! elim_graph_add_edge (elim_graph g, int pred, int succ)
  {
    VEC_safe_push (int, heap, g->edge_list, pred);
    VEC_safe_push (int, heap, g->edge_list, succ);
  }
  
  
--- 373,383 ----
  /* 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)
  {
    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);
  }
  
  
*************** elim_graph_add_edge (elim_graph g, int p
*** 354,360 ****
     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)
  {
    int y;
    unsigned x;
--- 385,391 ----
     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)
  {
    int y;
    unsigned x;
*************** elim_graph_remove_succ_edge (elim_graph 
*** 364,371 ****
--- 395,405 ----
          VEC_replace (int, g->edge_list, x, -1);
  	y = VEC_index (int, g->edge_list, x + 1);
  	VEC_replace (int, g->edge_list, x + 1, -1);
+ 	*locus = VEC_index (source_location, g->edge_locus, x / 2);
+ 	VEC_replace (source_location, g->edge_locus, x / 2, UNKNOWN_LOCATION);
  	return y;
        }
+   *locus = UNKNOWN_LOCATION;
    return -1;
  }
  
*************** elim_graph_remove_succ_edge (elim_graph 
*** 374,380 ****
     edge list.  VAR will hold the partition number found.  CODE is the
     code fragment executed for every node found.  */
  
! #define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE)		\
  do {									\
    unsigned x_;								\
    int y_;								\
--- 408,414 ----
     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)		\
  do {									\
    unsigned x_;								\
    int y_;								\
*************** do {									\
*** 384,389 ****
--- 418,424 ----
        if (y_ != (NODE))							\
          continue;							\
        (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1);		\
+       (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
        CODE;								\
      }									\
  } while (0)
*************** do {									\
*** 393,399 ****
     GRAPH.  VAR will hold the partition number found.  CODE is the
     code fragment executed for every node found.  */
  
! #define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE)		\
  do {									\
    unsigned x_;								\
    int y_;								\
--- 428,434 ----
     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)		\
  do {									\
    unsigned x_;								\
    int y_;								\
*************** do {									\
*** 403,408 ****
--- 438,444 ----
        if (y_ != (NODE))							\
          continue;							\
        (VAR) = VEC_index (int, (GRAPH)->edge_list, x_);			\
+       (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
        CODE;								\
      }									\
  } while (0)
*************** eliminate_build (elim_graph g)
*** 432,437 ****
--- 468,474 ----
    for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple phi = gsi_stmt (gsi);
+       source_location locus;
  
        p0 = var_to_partition (g->map, gimple_phi_result (phi));
        /* Ignore results which are not in partitions.  */
*************** eliminate_build (elim_graph g)
*** 439,444 ****
--- 476,482 ----
  	continue;
  
        Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
+       locus = gimple_phi_arg_location_from_edge (phi, g->e);
  
        /* If this argument is a constant, or a SSA_NAME which is being
  	 left in SSA form, just queue a copy to be emitted on this
*************** eliminate_build (elim_graph g)
*** 451,456 ****
--- 489,495 ----
  	     on this edge.  */
  	  VEC_safe_push (int, heap, g->const_dests, p0);
  	  VEC_safe_push (tree, heap, g->const_copies, Ti);
+ 	  VEC_safe_push (source_location, heap, g->copy_locus, locus);
  	}
        else
          {
*************** eliminate_build (elim_graph g)
*** 459,465 ****
  	    {
  	      eliminate_name (g, p0);
  	      eliminate_name (g, pi);
! 	      elim_graph_add_edge (g, p0, pi);
  	    }
  	}
      }
--- 498,504 ----
  	    {
  	      eliminate_name (g, p0);
  	      eliminate_name (g, pi);
! 	      elim_graph_add_edge (g, p0, pi, locus);
  	    }
  	}
      }
*************** static void 
*** 472,479 ****
  elim_forward (elim_graph g, int T)
  {
    int S;
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
      {
        if (!TEST_BIT (g->visited, S))
          elim_forward (g, S);
--- 511,520 ----
  elim_forward (elim_graph g, int T)
  {
    int S;
+   source_location locus;
+ 
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
      {
        if (!TEST_BIT (g->visited, S))
          elim_forward (g, S);
*************** static int
*** 488,494 ****
  elim_unvisited_predecessor (elim_graph g, int T)
  {
    int P;
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
      {
        if (!TEST_BIT (g->visited, P))
          return 1;
--- 529,537 ----
  elim_unvisited_predecessor (elim_graph g, int T)
  {
    int P;
!   source_location locus;
! 
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
      {
        if (!TEST_BIT (g->visited, P))
          return 1;
*************** static void
*** 502,514 ****
  elim_backward (elim_graph g, int T)
  {
    int P;
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
      {
        if (!TEST_BIT (g->visited, P))
          {
  	  elim_backward (g, P);
! 	  insert_partition_copy_on_edge (g->e, P, T);
  	}
      });
  }
--- 545,559 ----
  elim_backward (elim_graph g, int T)
  {
    int P;
+   source_location locus;
+ 
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
      {
        if (!TEST_BIT (g->visited, P))
          {
  	  elim_backward (g, P);
! 	  insert_partition_copy_on_edge (g->e, P, T, locus);
  	}
      });
  }
*************** static void 
*** 537,542 ****
--- 582,588 ----
  elim_create (elim_graph g, int T)
  {
    int P, S;
+   source_location locus;
  
    if (elim_unvisited_predecessor (g, T))
      {
*************** elim_create (elim_graph g, int T)
*** 544,566 ****
        rtx U = get_temp_reg (var);
        int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
  
!       insert_part_to_rtx_on_edge (g->e, U, T);
!       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
  	{
  	  if (!TEST_BIT (g->visited, P))
  	    {
  	      elim_backward (g, P);
! 	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp);
  	    }
  	});
      }
    else
      {
!       S = elim_graph_remove_succ_edge (g, T);
        if (S != -1)
  	{
  	  SET_BIT (g->visited, T);
! 	  insert_partition_copy_on_edge (g->e, T, S);
  	}
      }
  }
--- 590,612 ----
        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,
  	{
  	  if (!TEST_BIT (g->visited, P))
  	    {
  	      elim_backward (g, P);
! 	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
  	    }
  	});
      }
    else
      {
!       S = elim_graph_remove_succ_edge (g, T, &locus);
        if (S != -1)
  	{
  	  SET_BIT (g->visited, T);
! 	  insert_partition_copy_on_edge (g->e, T, S, locus);
  	}
      }
  }
*************** eliminate_phi (edge e, elim_graph g)
*** 574,579 ****
--- 620,626 ----
    int x;
  
    gcc_assert (VEC_length (tree, g->const_copies) == 0);
+   gcc_assert (VEC_length (source_location, g->copy_locus) == 0);
  
    /* Abnormal edges already have everything coalesced.  */
    if (e->flags & EDGE_ABNORMAL)
*************** eliminate_phi (edge e, elim_graph g)
*** 610,618 ****
      {
        int dest;
        tree src;
        src = VEC_pop (tree, g->const_copies);
        dest = VEC_pop (int, g->const_dests);
!       insert_value_copy_on_edge (e, dest, src);
      }
  }
  
--- 657,668 ----
      {
        int dest;
        tree src;
+       source_location locus;
+ 
        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);
      }
  }
  
*************** insert_backedge_copies (void)
*** 991,996 ****
--- 1041,1051 ----
  		  name = make_ssa_name (result_var, stmt);
  		  gimple_assign_set_lhs (stmt, name);
  
+ 		  /* copy location if present.  */
+ 		  if (gimple_phi_arg_has_location (phi, i))
+ 		    gimple_set_location (stmt, 
+ 					 gimple_phi_arg_location (phi, i));
+ 
  		  /* Insert the new statement into the block and update
  		     the PHI node.  */
  		  if (last && stmt_ends_bb_p (last))
Index: tree-flow.h
===================================================================
*** tree-flow.h	(revision 150217)
--- tree-flow.h	(working copy)
*************** extern void reserve_phi_args_for_new_edg
*** 579,585 ****
  extern void add_phi_node_to_bb (gimple phi, basic_block bb);
  extern gimple make_phi_node (tree var, int len);
  extern gimple create_phi_node (tree, basic_block);
! extern void add_phi_arg (gimple, tree, edge);
  extern void remove_phi_args (edge);
  extern void remove_phi_node (gimple_stmt_iterator *, bool);
  extern void remove_phi_nodes (basic_block);
--- 579,585 ----
  extern void add_phi_node_to_bb (gimple phi, basic_block bb);
  extern gimple make_phi_node (tree var, int len);
  extern gimple create_phi_node (tree, basic_block);
! extern void add_phi_arg (gimple, tree, edge, source_location);
  extern void remove_phi_args (edge);
  extern void remove_phi_node (gimple_stmt_iterator *, bool);
  extern void remove_phi_nodes (basic_block);
*************** extern bool gimple_stmt_may_fallthru (gi
*** 604,609 ****
--- 604,610 ----
  struct GTY(()) _edge_var_map {
    tree result;			/* PHI result.  */
    tree def;			/* PHI arg definition.  */
+   source_location locus;        /* PHI arg location.  */
  };
  typedef struct _edge_var_map edge_var_map;
  
*************** DEF_VEC_ALLOC_O(edge_var_map, heap);
*** 614,620 ****
  typedef VEC(edge_var_map, heap) *edge_var_map_vector;
  
  extern void init_tree_ssa (struct function *);
! extern void redirect_edge_var_map_add (edge, tree, tree);
  extern void redirect_edge_var_map_clear (edge);
  extern void redirect_edge_var_map_dup (edge, edge);
  extern edge_var_map_vector redirect_edge_var_map_vector (edge);
--- 615,621 ----
  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_clear (edge);
  extern void redirect_edge_var_map_dup (edge, edge);
  extern edge_var_map_vector redirect_edge_var_map_vector (edge);
Index: tree-switch-conversion.c
===================================================================
*** tree-switch-conversion.c	(revision 150217)
--- tree-switch-conversion.c	(working copy)
*************** fix_phi_nodes (edge e1f, edge e2f, basic
*** 638,645 ****
         !gsi_end_p (gsi); gsi_next (&gsi), i++)
      {
        gimple phi = gsi_stmt (gsi);
!       add_phi_arg (phi, info.target_inbound_names[i], e1f);
!       add_phi_arg (phi, info.target_outbound_names[i], e2f);
      }
  
  }
--- 638,645 ----
         !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);
      }
  
  }
Index: tree-cfg.c
===================================================================
*** tree-cfg.c	(revision 150217)
--- tree-cfg.c	(working copy)
*************** reinstall_phi_args (edge new_edge, edge 
*** 2886,2892 ****
   
        gcc_assert (result == gimple_phi_result (phi));
    
!       add_phi_arg (phi, arg, new_edge);
      }
    
    redirect_edge_var_map_clear (old_edge);
--- 2886,2892 ----
   
        gcc_assert (result == gimple_phi_result (phi));
    
!       add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
      }
    
    redirect_edge_var_map_clear (old_edge);
*************** gimple_make_forwarder_block (edge fallth
*** 4840,4846 ****
        new_phi = create_phi_node (var, bb);
        SSA_NAME_DEF_STMT (var) = new_phi;
        gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
!       add_phi_arg (new_phi, gimple_phi_result (phi), fallthru);
      }
  
    /* Add the arguments we have stored on edges.  */
--- 4840,4847 ----
        new_phi = create_phi_node (var, bb);
        SSA_NAME_DEF_STMT (var) = new_phi;
        gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
!       add_phi_arg (new_phi, gimple_phi_result (phi), fallthru, 
! 		   UNKNOWN_LOCATION);
      }
  
    /* Add the arguments we have stored on edges.  */
*************** add_phi_args_after_copy_edge (edge e_cop
*** 5239,5245 ****
        phi = gsi_stmt (psi);
        phi_copy = gsi_stmt (psi_copy);
        def = PHI_ARG_DEF_FROM_EDGE (phi, e);
!       add_phi_arg (phi_copy, def, e_copy);
      }
  }
  
--- 5240,5247 ----
        phi = gsi_stmt (psi);
        phi_copy = gsi_stmt (psi_copy);
        def = PHI_ARG_DEF_FROM_EDGE (phi, e);
!       add_phi_arg (phi_copy, def, e_copy, 
! 		   gimple_phi_arg_location_from_edge (phi, e));
      }
  }
  
*************** gimple_lv_adjust_loop_header_phi (basic_
*** 7058,7064 ****
        phi1 = gsi_stmt (psi1);
        phi2 = gsi_stmt (psi2);
        def = PHI_ARG_DEF (phi2, e2->dest_idx);
!       add_phi_arg (phi1, def, e);
      }
  }
  
--- 7060,7066 ----
        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));
      }
  }
  
Index: ipa-struct-reorg.c
===================================================================
*** ipa-struct-reorg.c	(revision 150217)
--- ipa-struct-reorg.c	(working copy)
*************** make_edge_and_fix_phis_of_dest (basic_bl
*** 658,664 ****
      {
        gimple phi = gsi_stmt (si);
        arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
!       add_phi_arg (phi, arg, new_e); 
      }
  
    return new_e;
--- 658,664 ----
      {
        gimple phi = gsi_stmt (si);
        arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
!       add_phi_arg (phi, arg, new_e, gimple_phi_arg_location_from_edge (phi, e));
      }
  
    return new_e;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]