diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f5b3ba34104665168c31bb3233e35f4262fa953f..47845784fbcd8c81b3ca20473c6f2c81e86dcde5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,82 @@
+2009-07-30  Andrew MacLeod  <amacleod@redhat.com>
+
+	PR debug/26475
+	* tree-into-ssa.c (insert_phi_nodes_for, rewrite_add_phi_arguments): Set
+	location for phi arguments.
+	(rewrite_update_phi_arguments): Find locations for reaching defs.
+	* tree-ssa-threadupdate.c (create_edge_and_update_destination_phis):
+	Add location to add_phi_arg calls.
+	* tree-loop-districbution.c (update_phis_for_loop_copy): Add locations.
+	* tree-ssa-loop-manip.c (create_iv, add_exit_phis_edge,
+	split_loop_exit_edge, tree_transform_and_unroll_loop): Add locations.
+	* tree-tailcall.c (add_successor_phi_arg, eliminate_tail_call,
+	create_tailcall_accumulator, tree_optimize_tail_calls_1): Add locations.
+	* tree.h (struct phi_arg_d): Add location_t to PHI arguments.
+	* tree-phinodes.c (make_phi_node): Initialize location.
+	(resize_phi_node): Initialize location to UNKNOWN_LOCATION.
+	(add_phi_arg): Add location parameter.
+	(remove_phi_arg_num): Move location when moving phi argument.
+	* omp-low.c (expand_parallel_call, expand_omp_for_static_chunk): Set 
+	location.
+	* tree-vect-loop-manip.c (slpeel_update_phis_for_duplicate_loop,
+	slpeel_update_phi_nodes_for_guard1,
+	slpeel_update_phi_nodes_for_guard2,
+	slpeel_tree_duplicate_loop_to_edge_cfg, set_prologue_iterations,
+	vect_loop_versioning): Set locations.
+	* tree-parloops.c (create_phi_for_local_result,
+	transform_to_exit_first_loop, create_parallel_loop): Add locations.
+	* gimple-pretty-print.c (dump_gimple_phi): Dump lineno's if present.
+	* tree-vect-loop.c (get_initial_def_for_induction,
+	vect_create_epilog_for_reduction, vect_finalize_reduction): Add
+	locations.
+	* tree-flow-inline.h (gimple_phi_arg_location): New.  Return locus.
+	(gimple_phi_arg_location_from_edge): New.  Return locus from an edge.
+	(gimple_phi_arg_set_location): New.  Set locus.
+	(gimple_phi_arg_has_location): New.  Check for locus.
+	(redirect_edge_var_map_location): New.  Return locus from var_map.
+	* tree-vect-data-refs.c (vect_setup_realignment): Set location.
+	* tree-ssa-phiopt.c (conditional_replacement): Set locus when
+	combining PHI arguments.
+	(cond_store_replacement): Set location.
+	* cfgexpand.c (gimple_assign_rhs_to_tree): Transfer locus if possible.
+	* grpahite.c (add_loop_exit_phis, add_guard_exit_phis,
+	scop_add_exit_phis_edge): Add locations.
+	* tree-cfgcleanup.c (remove_forwarder_block,
+	remove_forwarder_block_with_phi): Add locations.
+	* tree-ssa-pre.c (insert_into_preds_of_block): Add locations.
+	* tree-predcom.c (initialize_root_vars, initialize_root_vars_lm): Add
+	locations.
+	* tree-ssa-dce.c (forward_edge_to_pdom): Add locations.
+	* tree-ssa.c (redirect_edge_var_map_add, ssa_redirect_edge,
+	flush_pending_stmts): Add source location.
+	* lambda-code.c (perfect_nestify): Maintain location stack with argument
+	stack to preserve locations.
+	* tree-vect-stmts.c (vectorizable_load): Add location.
+	* tree-inline.c (copy_phis_for_bb): Copy locus.
+	(setup_one_parameter): Add call locus to inlined parameter stmts.
+	(initialize_inlined_parameters): Pass in call location as parameter
+	assignment locus.
+	(tree_function_versioning): Pass location to setup_one_parameter.
+	* tree-ssa-phiprop.c (phiprop_insert_phi): Set locations.
+	* tree-outof-ssa.c (struct _elim_graph): Add source_location vecs for
+	copy and edge lists.
+	(insert_partition_copy_on_edge, insert_value_copy_on_edge,
+	insert_rtx_to_part_on_edge, insert_part_to_rtx_on_edge): Provide a 
+	locus parameter and override the stmt default if provided.
+	(new_elim_graph, clear_elim_graph, delete_elim_graph,
+	elim_graph_add_edge, elim_graph_remove_succ_edge,
+	FOR_EACH_ELIM_GRAPH_SUCC, FOR_EACH_ELIM_GRAPH_PRED, eliminate_build,
+	elim_forward, elim_unvisited_predecessor, elim_backward, elim_create,
+	eliminate_phi):  Add locus info in elimination graph for each edge and
+	value copy.
+	(insert_backedge_copies): Copy locus if present.
+	* tree-flow.h (struct _edge_var_map): Add locus field.
+	* tree-switch_conversions.c (fix_phi_nodes): Add locations.
+	* tree-cfg.c (reinstall_phi_args, gimple_make_forwarder_block,
+	add_phi_args_after_copy_edge, gimple_lv_adjust_loop_header_phi): Add 
+	locations.
+	* ipa-struct-reorg.c (make_edge_and_fix_phis_of_dest): Add locations.
+	
 2009-07-30  Martin Jambor  <mjambor@suse.cz>
 
 	PR tree-optimization/40570
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 359433922d5ca5b8e3e56b2784c965ba166010b6..c172c96a5801f6a087041e4c3985c0ade2d949b9 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -74,6 +74,9 @@ gimple_assign_rhs_to_tree (gimple stmt)
   else
     gcc_unreachable ();
 
+  if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
+    SET_EXPR_LOCATION (t, gimple_location (stmt));
+
   return t;
 }
 
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 1deb9c81a0a08e6f0865fa66ae5bf1d38d7f4d11..70ab4e1b8006af4f9c179e5869a3e6ad35f6a39e 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -1150,6 +1150,22 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
     }
   for (i = 0; i < gimple_phi_num_args (phi); i++)
     {
+      if ((flags & TDF_LINENO) && gimple_phi_arg_has_location (phi, i))
+        {
+	  expanded_location xloc;
+
+	  xloc = expand_location (gimple_phi_arg_location (phi, i));
+	  pp_character (buffer, '[');
+	  if (xloc.file)
+	    {
+	      pp_string (buffer, xloc.file);
+	      pp_string (buffer, " : ");
+	    }
+	  pp_decimal_int (buffer, xloc.line);
+	  pp_string (buffer, ":");
+	  pp_decimal_int (buffer, xloc.column);
+	  pp_string (buffer, "] ");
+	}
       dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
 			 false);
       pp_character (buffer, '(');
diff --git a/gcc/graphite.c b/gcc/graphite.c
index a87bca867c98c99a30c9485f1dbd00f3de168ba6..f3bdc4b101ff05c20cfb1c11ea66f71500b95def 100644
--- a/gcc/graphite.c
+++ b/gcc/graphite.c
@@ -4555,7 +4555,7 @@ add_loop_exit_phis (void **slot, void *s)
   tree res = create_new_def_for (gimple_phi_result (phi), phi,
 				 gimple_phi_result_ptr (phi));
 
-  add_phi_arg (phi, new_name, single_pred_edge (bb));
+  add_phi_arg (phi, new_name, single_pred_edge (bb), UNKNOWN_LOCATION);
 
   entry->new_name = res;
   *slot = entry;
@@ -4617,8 +4617,8 @@ add_guard_exit_phis (void **slot, void *s)
   tree res = create_new_def_for (gimple_phi_result (phi), phi,
 				 gimple_phi_result_ptr (phi));
 
-  add_phi_arg (phi, name1, true_edge);
-  add_phi_arg (phi, name2, false_edge);
+  add_phi_arg (phi, name1, true_edge, UNKNOWN_LOCATION);
+  add_phi_arg (phi, name2, false_edge, UNKNOWN_LOCATION);
 
   entry->new_name = res;
   *slot = entry;
@@ -5141,8 +5141,8 @@ scop_add_exit_phis_edge (basic_block exit, tree use, edge false_e, edge true_e)
 
   create_new_def_for (gimple_phi_result (phi), phi,
 		      gimple_phi_result_ptr (phi));
-  add_phi_arg (phi, use, false_e);
-  add_phi_arg (phi, use, true_e);
+  add_phi_arg (phi, use, false_e, UNKNOWN_LOCATION);
+  add_phi_arg (phi, use, true_e, UNKNOWN_LOCATION);
 }
 
 /* Add phi nodes for VAR that is used in LIVEIN.  Phi nodes are
diff --git a/gcc/ipa-struct-reorg.c b/gcc/ipa-struct-reorg.c
index 199c5855e2eb9664ec05516f2acaaf0be8fbca8c..bc84eee372b483fce4e0bd3670d78517c525f051 100644
--- a/gcc/ipa-struct-reorg.c
+++ b/gcc/ipa-struct-reorg.c
@@ -658,7 +658,7 @@ make_edge_and_fix_phis_of_dest (basic_block bb, edge e)
     {
       gimple phi = gsi_stmt (si);
       arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
-      add_phi_arg (phi, arg, new_e); 
+      add_phi_arg (phi, arg, new_e, gimple_phi_arg_location_from_edge (phi, e));
     }
 
   return new_e;
diff --git a/gcc/lambda-code.c b/gcc/lambda-code.c
index 852be11153cc2a0e0d0944357ff94db4b5814124..e7a49951a67c51a5dfd0670cb89bf73c0cf37a92 100644
--- a/gcc/lambda-code.c
+++ b/gcc/lambda-code.c
@@ -2343,6 +2343,10 @@ can_convert_to_perfect_nest (struct loop *loop)
   return false;
 }
 
+
+DEF_VEC_I(source_location);
+DEF_VEC_ALLOC_I(source_location,heap);
+
 /* Transform the loop nest into a perfect nest, if possible.
    LOOP is the loop nest to transform into a perfect nest
    LBOUNDS are the lower bounds for the loops to transform
@@ -2400,6 +2404,7 @@ perfect_nestify (struct loop *loop,
   gimple stmt;
   tree oldivvar, ivvar, ivvarinced;
   VEC(tree,heap) *phis = NULL;
+  VEC(source_location,heap) *locations = NULL;
   htab_t replacements = NULL;
 
   /* Create the new loop.  */
@@ -2412,8 +2417,11 @@ perfect_nestify (struct loop *loop,
     {
       phi = gsi_stmt (bsi);
       VEC_reserve (tree, heap, phis, 2);
+      VEC_reserve (source_location, heap, locations, 1);
       VEC_quick_push (tree, phis, PHI_RESULT (phi));
       VEC_quick_push (tree, phis, PHI_ARG_DEF (phi, 0));
+      VEC_quick_push (source_location, locations, 
+		      gimple_phi_arg_location (phi, 0));
     }
   e = redirect_edge_and_branch (single_succ_edge (preheaderbb), headerbb);
 
@@ -2426,10 +2434,12 @@ perfect_nestify (struct loop *loop,
     {
       tree def;
       tree phiname;
+      source_location locus;
       def = VEC_pop (tree, phis);
       phiname = VEC_pop (tree, phis);      
+      locus = VEC_pop (source_location, locations);
       phi = create_phi_node (phiname, preheaderbb);
-      add_phi_arg (phi, def, single_pred_edge (preheaderbb));
+      add_phi_arg (phi, def, single_pred_edge (preheaderbb), locus);
     }
   flush_pending_stmts (e);
   VEC_free (tree, heap, phis);
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 82827bf762a647d912d8e3f9fde0ade6e43810ac..3a4a1f40c55b131debe03826c8882c87005f168a 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -3013,8 +3013,8 @@ expand_parallel_call (struct omp_region *region, basic_block bb,
 	    {
 	      gimple phi = create_phi_node (tmp_join, bb);
 	      SSA_NAME_DEF_STMT (tmp_join) = phi;
-	      add_phi_arg (phi, tmp_then, e_then);
-	      add_phi_arg (phi, tmp_else, e_else);
+	      add_phi_arg (phi, tmp_then, e_then, UNKNOWN_LOCATION);
+	      add_phi_arg (phi, tmp_else, e_else, UNKNOWN_LOCATION);
 	    }
 
 	  val = tmp_join;
@@ -4508,6 +4508,7 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 	   gsi_next (&psi), ++i)
 	{
 	  gimple nphi;
+	  source_location locus;
 
 	  phi = gsi_stmt (psi);
 	  t = gimple_phi_result (phi);
@@ -4516,12 +4517,15 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
 	  SSA_NAME_DEF_STMT (t) = nphi;
 
 	  t = PHI_ARG_DEF_FROM_EDGE (phi, se);
+	  locus = gimple_phi_arg_location_from_edge (phi, se);
+
 	  /* A special case -- fd->loop.v is not yet computed in
 	     iter_part_bb, we need to use v_extra instead.  */
 	  if (t == fd->loop.v)
 	    t = v_extra;
-	  add_phi_arg (nphi, t, ene);
-	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re);
+	  add_phi_arg (nphi, t, ene, locus);
+	  locus = redirect_edge_var_map_location (vm);
+	  add_phi_arg (nphi, redirect_edge_var_map_def (vm), re, locus);
 	}
       gcc_assert (!gsi_end_p (psi) && i == VEC_length (edge_var_map, head));
       redirect_edge_var_map_clear (re);
@@ -4536,8 +4540,10 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
       /* Make phi node for trip.  */
       phi = create_phi_node (trip_main, iter_part_bb);
       SSA_NAME_DEF_STMT (trip_main) = phi;
-      add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb));
-      add_phi_arg (phi, trip_init, single_succ_edge (entry_bb));
+      add_phi_arg (phi, trip_back, single_succ_edge (trip_update_bb),
+		   UNKNOWN_LOCATION);
+      add_phi_arg (phi, trip_init, single_succ_edge (entry_bb),
+		   UNKNOWN_LOCATION);
     }
 
   set_immediate_dominator (CDI_DOMINATORS, trip_update_bb, cont_bb);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 49345c2535bb7fc7e15e967be95e0e399bb28cfc..a6097edf3fe2f9d7f43d2af3f5dbfc6ace9f92a1 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -2886,7 +2886,7 @@ reinstall_phi_args (edge new_edge, edge old_edge)
  
       gcc_assert (result == gimple_phi_result (phi));
   
-      add_phi_arg (phi, arg, new_edge);
+      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
     }
   
   redirect_edge_var_map_clear (old_edge);
@@ -4840,7 +4840,8 @@ gimple_make_forwarder_block (edge fallthru)
       new_phi = create_phi_node (var, bb);
       SSA_NAME_DEF_STMT (var) = new_phi;
       gimple_phi_set_result (phi, make_ssa_name (SSA_NAME_VAR (var), phi));
-      add_phi_arg (new_phi, gimple_phi_result (phi), fallthru);
+      add_phi_arg (new_phi, gimple_phi_result (phi), fallthru, 
+		   UNKNOWN_LOCATION);
     }
 
   /* Add the arguments we have stored on edges.  */
@@ -5239,7 +5240,8 @@ add_phi_args_after_copy_edge (edge e_copy)
       phi = gsi_stmt (psi);
       phi_copy = gsi_stmt (psi_copy);
       def = PHI_ARG_DEF_FROM_EDGE (phi, e);
-      add_phi_arg (phi_copy, def, e_copy);
+      add_phi_arg (phi_copy, def, e_copy, 
+		   gimple_phi_arg_location_from_edge (phi, e));
     }
 }
 
@@ -7058,7 +7060,7 @@ gimple_lv_adjust_loop_header_phi (basic_block first, basic_block second,
       phi1 = gsi_stmt (psi1);
       phi2 = gsi_stmt (psi2);
       def = PHI_ARG_DEF (phi2, e2->dest_idx);
-      add_phi_arg (phi1, def, e);
+      add_phi_arg (phi1, def, e, gimple_phi_arg_location_from_edge (phi2, e2));
     }
 }
 
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index fdd7d780ade207592d1e1dd76c04d7f77a9e65c2..34cfc80bbee756e5bc15d0537b3e5685a02491fe 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -401,7 +401,8 @@ remove_forwarder_block (basic_block bb)
 	       gsi_next (&gsi))
 	    {
 	      gimple phi = gsi_stmt (gsi);
-	      add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s);
+	      source_location l = gimple_phi_arg_location_from_edge (phi, succ);
+	      add_phi_arg (phi, gimple_phi_arg_def (phi, succ->dest_idx), s, l);
 	    }
 	}
     }
@@ -744,6 +745,7 @@ remove_forwarder_block_with_phi (basic_block bb)
 	{
 	  gimple phi = gsi_stmt (gsi);
 	  tree def = gimple_phi_arg_def (phi, succ->dest_idx);
+	  source_location locus = gimple_phi_arg_location_from_edge (phi, succ);
 
 	  if (TREE_CODE (def) == SSA_NAME)
 	    {
@@ -763,12 +765,13 @@ remove_forwarder_block_with_phi (basic_block bb)
 		  if (def == old_arg)
 		    {
 		      def = new_arg;
+		      locus = redirect_edge_var_map_location (vm);
 		      break;
 		    }
 		}
 	    }
 
-	  add_phi_arg (phi, def, s);
+	  add_phi_arg (phi, def, s, locus);
 	}
 
       redirect_edge_var_map_clear (e);
diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h
index e6de3772c3c004872e3b03b8e3eb521021de436c..f56ecea7db7bd24d75fa0f050644035378856b23 100644
--- a/gcc/tree-flow-inline.h
+++ b/gcc/tree-flow-inline.h
@@ -455,6 +455,39 @@ gimple_phi_arg_edge (gimple gs, size_t i)
   return EDGE_PRED (gimple_bb (gs), i);
 }
 
+/* Return the source location of gimple argument I of phi node GS.  */
+
+static inline source_location
+gimple_phi_arg_location (gimple gs, size_t i)
+{
+  return gimple_phi_arg (gs, i)->locus;
+}
+
+/* Return the source location of the argument on edge E of phi node GS.  */
+
+static inline source_location
+gimple_phi_arg_location_from_edge (gimple gs, edge e)
+{
+  return gimple_phi_arg (gs, e->dest_idx)->locus;
+}
+
+/* Set the source location of gimple argument I of phi node GS to LOC.  */
+
+static inline void
+gimple_phi_arg_set_location (gimple gs, size_t i, source_location loc)
+{
+  gimple_phi_arg (gs, i)->locus = loc;
+}
+
+/* Return TRUE if argument I of phi node GS has a location record.  */
+
+static inline bool
+gimple_phi_arg_has_location (gimple gs, size_t i)
+{
+  return gimple_phi_arg_location (gs, i) != UNKNOWN_LOCATION;
+}
+
+
 /* Return the PHI nodes for basic block BB, or NULL if there are no
    PHI nodes.  */
 static inline gimple_seq
@@ -1196,6 +1229,14 @@ redirect_edge_var_map_result (edge_var_map *v)
   return v->result;
 }
 
+/* Given an edge_var_map V, return the PHI arg location.  */
+
+static inline source_location
+redirect_edge_var_map_location (edge_var_map *v)
+{
+  return v->locus;
+}
+
 
 /* Return an SSA_NAME node for variable VAR defined in statement STMT
    in function cfun.  */
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index f9f0da200250c38392727112f53ce0844e3fad4b..69dc446b8b8a0c8c0f15546be311d7b8315e3e59 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -579,7 +579,7 @@ extern void reserve_phi_args_for_new_edge (basic_block);
 extern void add_phi_node_to_bb (gimple phi, basic_block bb);
 extern gimple make_phi_node (tree var, int len);
 extern gimple create_phi_node (tree, basic_block);
-extern void add_phi_arg (gimple, tree, edge);
+extern void add_phi_arg (gimple, tree, edge, source_location);
 extern void remove_phi_args (edge);
 extern void remove_phi_node (gimple_stmt_iterator *, bool);
 extern void remove_phi_nodes (basic_block);
@@ -604,6 +604,7 @@ extern bool gimple_stmt_may_fallthru (gimple);
 struct GTY(()) _edge_var_map {
   tree result;			/* PHI result.  */
   tree def;			/* PHI arg definition.  */
+  source_location locus;        /* PHI arg location.  */
 };
 typedef struct _edge_var_map edge_var_map;
 
@@ -614,7 +615,7 @@ DEF_VEC_ALLOC_O(edge_var_map, heap);
 typedef VEC(edge_var_map, heap) *edge_var_map_vector;
 
 extern void init_tree_ssa (struct function *);
-extern void redirect_edge_var_map_add (edge, tree, tree);
+extern void redirect_edge_var_map_add (edge, tree, tree, source_location);
 extern void redirect_edge_var_map_clear (edge);
 extern void redirect_edge_var_map_dup (edge, edge);
 extern edge_var_map_vector redirect_edge_var_map_vector (edge);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index e62c5c1e7925f748d74ff4c4370f8cc98383f922..f79ba75808816aaf09cb1f7c2cc855d0aa686920 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1828,7 +1828,8 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
 		  new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
 		  gsi_insert_seq_on_edge_immediate (new_edge, stmts);
 		}
-	      add_phi_arg (new_phi, new_arg, new_edge);
+	      add_phi_arg (new_phi, new_arg, new_edge, 
+			   gimple_phi_arg_location_from_edge (phi, old_edge));
 	    }
 	}
     }
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index ab827eadc578a8bd52aaaa945f20fe80d8a388a0..bdec08063e49ae9fb203f119734e194e65fe648f 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -1114,7 +1114,7 @@ insert_phi_nodes_for (tree var, bitmap phi_insertion_points, bool update_p)
 	     renamer will use the symbol on the LHS to get its
 	     reaching definition.  */
 	  FOR_EACH_EDGE (e, ei, bb->preds)
-	    add_phi_arg (phi, var, e);
+	    add_phi_arg (phi, var, e, UNKNOWN_LOCATION);
 	}
       else
 	{
@@ -1320,9 +1320,12 @@ rewrite_add_phi_arguments (basic_block bb)
 	   gsi_next (&gsi))
 	{
 	  tree currdef;
+	  gimple stmt;
+
 	  phi = gsi_stmt (gsi);
 	  currdef = get_reaching_def (SSA_NAME_VAR (gimple_phi_result (phi)));
-	  add_phi_arg (phi, currdef, e);
+	  stmt = SSA_NAME_DEF_STMT (currdef);
+	  add_phi_arg (phi, currdef, e, gimple_location (stmt));
 	}
     }
 }
@@ -1857,7 +1860,7 @@ rewrite_update_phi_arguments (basic_block bb)
       phis = VEC_index (gimple_vec, phis_to_rewrite, e->dest->index);
       for (i = 0; VEC_iterate (gimple, phis, i, phi); i++)
 	{
-	  tree arg, lhs_sym;
+	  tree arg, lhs_sym, reaching_def = NULL;
 	  use_operand_p arg_p;
 
   	  gcc_assert (rewrite_uses_p (phi));
@@ -1875,18 +1878,41 @@ rewrite_update_phi_arguments (basic_block bb)
 	      /* When updating a PHI node for a recently introduced
 		 symbol we may find NULL arguments.  That's why we
 		 take the symbol from the LHS of the PHI node.  */
-	      SET_USE (arg_p, get_reaching_def (lhs_sym));
+	      reaching_def = get_reaching_def (lhs_sym);
+
 	    }
 	  else
 	    {
 	      tree sym = DECL_P (arg) ? arg : SSA_NAME_VAR (arg);
 
 	      if (symbol_marked_for_renaming (sym))
-		SET_USE (arg_p, get_reaching_def (sym));
+		reaching_def = get_reaching_def (sym);
 	      else if (is_old_name (arg))
-		SET_USE (arg_p, get_reaching_def (arg));
+		reaching_def = get_reaching_def (arg);
+	    }
+
+          /* Update the argument if there is a reaching def.  */
+	  if (reaching_def)
+	    {
+	      gimple stmt;
+	      source_location locus;
+	      int arg_i = PHI_ARG_INDEX_FROM_USE (arg_p);
+
+	      SET_USE (arg_p, reaching_def);
+	      stmt = SSA_NAME_DEF_STMT (reaching_def);
+
+	      /* Single element PHI nodes  behave like copies, so get the 
+		 location from the phi argument.  */
+	      if (gimple_code (stmt) == GIMPLE_PHI && 
+		  gimple_phi_num_args (stmt) == 1)
+		locus = gimple_phi_arg_location (stmt, 0);
+	      else
+		locus = gimple_location (stmt);
+
+	      gimple_phi_arg_set_location (phi, arg_i, locus);
 	    }
 
+
 	  if (e->flags & EDGE_ABNORMAL)
 	    SSA_NAME_OCCURS_IN_ABNORMAL_PHI (USE_FROM_PTR (arg_p)) = 1;
 	}
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 575025473cbc07235d31cd00e735775c4861f4c1..b9b6ea3cd43bbd6291f87f2d58e1a6db01da2b84 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -97,17 +97,20 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
        gsi_next (&si_new), gsi_next (&si_orig))
     {
       tree def;
+      source_location locus;
       gimple phi_new = gsi_stmt (si_new);
       gimple phi_orig = gsi_stmt (si_orig);
 
       /* Add the first phi argument for the phi in NEW_LOOP (the one
 	 associated with the entry of NEW_LOOP)  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_entry_e);
-      add_phi_arg (phi_new, def, new_loop_entry_e);
+      locus = gimple_phi_arg_location_from_edge (phi_orig, orig_entry_e);
+      add_phi_arg (phi_new, def, new_loop_entry_e, locus);
 
       /* Add the second phi argument for the phi in NEW_LOOP (the one
 	 associated with the latch of NEW_LOOP)  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
+      locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
 
       if (TREE_CODE (def) == SSA_NAME)
 	{
@@ -122,7 +125,7 @@ update_phis_for_loop_copy (struct loop *orig_loop, struct loop *new_loop)
 	/* Could be an integer.  */
 	new_ssa_name = def;
 
-      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
+      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
     }
 }
 
diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c
index 4ed8e9fbdf063f736a12132c6316a7c7d77d1947..696c7259eedd752f3ee6d30dc147f4928ba7cb73 100644
--- a/gcc/tree-outof-ssa.c
+++ b/gcc/tree-outof-ssa.c
@@ -36,6 +36,9 @@ along with GCC; see the file COPYING3.  If not see
 #include "ssaexpand.h"
 
 
+DEF_VEC_I(source_location);
+DEF_VEC_ALLOC_I(source_location,heap);
+
 /* Used to hold all the components required to do SSA PHI elimination.
    The node and pred/succ list is a simple linear list of nodes and
    edges represented as pairs of nodes.
@@ -67,6 +70,9 @@ typedef struct _elim_graph {
   /*  The predecessor and successor edge list.  */
   VEC(int,heap) *edge_list;
 
+  /* Source locus on each edge */
+  VEC(source_location,heap) *edge_locus;
+
   /* Visited vector.  */
   sbitmap visited;
 
@@ -82,6 +88,9 @@ typedef struct _elim_graph {
   /* List of constant copies to emit.  These are pushed on in pairs.  */
   VEC(int,heap) *const_dests;
   VEC(tree,heap) *const_copies;
+
+  /* Source locations for any constant copies.  */
+  VEC(source_location,heap) *copy_locus;
 } *elim_graph;
 
 
@@ -150,7 +159,7 @@ emit_partition_copy (rtx dest, rtx src, int unsignedsrcp)
 /* Insert a copy instruction from partition SRC to DEST onto edge E.  */
 
 static void
-insert_partition_copy_on_edge (edge e, int dest, int src)
+insert_partition_copy_on_edge (edge e, int dest, int src, source_location locus)
 {
   rtx seq;
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -167,6 +176,9 @@ insert_partition_copy_on_edge (edge e, int dest, int src)
   gcc_assert (SA.partition_to_pseudo[src]);
 
   set_location_for_edge (e);
+  /* If a locus is provided, override the default.  */
+  if (locus)
+    set_curr_insn_source_location (locus);
 
   seq = emit_partition_copy (SA.partition_to_pseudo[dest],
 			     SA.partition_to_pseudo[src],
@@ -180,7 +192,7 @@ insert_partition_copy_on_edge (edge e, int dest, int src)
    onto edge E.  */
 
 static void
-insert_value_copy_on_edge (edge e, int dest, tree src)
+insert_value_copy_on_edge (edge e, int dest, tree src, source_location locus)
 {
   rtx seq, x;
   enum machine_mode mode;
@@ -197,6 +209,9 @@ insert_value_copy_on_edge (edge e, int dest, tree src)
   gcc_assert (SA.partition_to_pseudo[dest]);
 
   set_location_for_edge (e);
+  /* If a locus is provided, override the default.  */
+  if (locus)
+    set_curr_insn_source_location (locus);
 
   start_sequence ();
   mode = GET_MODE (SA.partition_to_pseudo[dest]);
@@ -219,7 +234,8 @@ insert_value_copy_on_edge (edge e, int dest, tree src)
    onto edge E.  */
 
 static void
-insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
+insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp,
+			    source_location locus)
 {
   rtx seq;
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -233,7 +249,11 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
     }
 
   gcc_assert (SA.partition_to_pseudo[dest]);
+
   set_location_for_edge (e);
+  /* If a locus is provided, override the default.  */
+  if (locus)
+    set_curr_insn_source_location (locus);
 
   seq = emit_partition_copy (SA.partition_to_pseudo[dest],
 			     src,
@@ -246,7 +266,7 @@ insert_rtx_to_part_on_edge (edge e, int dest, rtx src, int unsignedsrcp)
    onto edge E.  */
 
 static void
-insert_part_to_rtx_on_edge (edge e, rtx dest, int src)
+insert_part_to_rtx_on_edge (edge e, rtx dest, int src, source_location locus)
 {
   rtx seq;
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -260,7 +280,11 @@ insert_part_to_rtx_on_edge (edge e, rtx dest, int src)
     }
 
   gcc_assert (SA.partition_to_pseudo[src]);
+
   set_location_for_edge (e);
+  /* If a locus is provided, override the default.  */
+  if (locus)
+    set_curr_insn_source_location (locus);
 
   seq = emit_partition_copy (dest,
 			     SA.partition_to_pseudo[src],
@@ -282,7 +306,9 @@ new_elim_graph (int size)
   g->nodes = VEC_alloc (int, heap, 30);
   g->const_dests = VEC_alloc (int, heap, 20);
   g->const_copies = VEC_alloc (tree, heap, 20);
+  g->copy_locus = VEC_alloc (source_location, heap, 10);
   g->edge_list = VEC_alloc (int, heap, 20);
+  g->edge_locus = VEC_alloc (source_location, heap, 10);
   g->stack = VEC_alloc (int, heap, 30);
   
   g->visited = sbitmap_alloc (size);
@@ -298,6 +324,7 @@ clear_elim_graph (elim_graph g)
 {
   VEC_truncate (int, g->nodes, 0);
   VEC_truncate (int, g->edge_list, 0);
+  VEC_truncate (source_location, g->edge_locus, 0);
 }
 
 
@@ -312,6 +339,9 @@ delete_elim_graph (elim_graph g)
   VEC_free (tree, heap, g->const_copies);
   VEC_free (int, heap, g->const_dests);
   VEC_free (int, heap, g->nodes);
+  VEC_free (source_location, heap, g->copy_locus);
+  VEC_free (source_location, heap, g->edge_locus);
+
   free (g);
 }
 
@@ -343,10 +373,11 @@ elim_graph_add_node (elim_graph g, int node)
 /* Add the edge PRED->SUCC to graph G.  */
 
 static inline void
-elim_graph_add_edge (elim_graph g, int pred, int succ)
+elim_graph_add_edge (elim_graph g, int pred, int succ, source_location locus)
 {
   VEC_safe_push (int, heap, g->edge_list, pred);
   VEC_safe_push (int, heap, g->edge_list, succ);
+  VEC_safe_push (source_location, heap, g->edge_locus, locus);
 }
 
 
@@ -354,7 +385,7 @@ elim_graph_add_edge (elim_graph g, int pred, int succ)
    return the successor node.  -1 is returned if there is no such edge.  */
 
 static inline int
-elim_graph_remove_succ_edge (elim_graph g, int node)
+elim_graph_remove_succ_edge (elim_graph g, int node, source_location *locus)
 {
   int y;
   unsigned x;
@@ -364,8 +395,11 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
         VEC_replace (int, g->edge_list, x, -1);
 	y = VEC_index (int, g->edge_list, x + 1);
 	VEC_replace (int, g->edge_list, x + 1, -1);
+	*locus = VEC_index (source_location, g->edge_locus, x / 2);
+	VEC_replace (source_location, g->edge_locus, x / 2, UNKNOWN_LOCATION);
 	return y;
       }
+  *locus = UNKNOWN_LOCATION;
   return -1;
 }
 
@@ -374,7 +408,7 @@ elim_graph_remove_succ_edge (elim_graph g, int node)
    edge list.  VAR will hold the partition number found.  CODE is the
    code fragment executed for every node found.  */
 
-#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, CODE)		\
+#define FOR_EACH_ELIM_GRAPH_SUCC(GRAPH, NODE, VAR, LOCUS, CODE)		\
 do {									\
   unsigned x_;								\
   int y_;								\
@@ -384,6 +418,7 @@ do {									\
       if (y_ != (NODE))							\
         continue;							\
       (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1);		\
+      (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
       CODE;								\
     }									\
 } while (0)
@@ -393,7 +428,7 @@ do {									\
    GRAPH.  VAR will hold the partition number found.  CODE is the
    code fragment executed for every node found.  */
 
-#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, CODE)		\
+#define FOR_EACH_ELIM_GRAPH_PRED(GRAPH, NODE, VAR, LOCUS, CODE)		\
 do {									\
   unsigned x_;								\
   int y_;								\
@@ -403,6 +438,7 @@ do {									\
       if (y_ != (NODE))							\
         continue;							\
       (VAR) = VEC_index (int, (GRAPH)->edge_list, x_);			\
+      (LOCUS) = VEC_index (source_location, (GRAPH)->edge_locus, x_ / 2); \
       CODE;								\
     }									\
 } while (0)
@@ -432,6 +468,7 @@ eliminate_build (elim_graph g)
   for (gsi = gsi_start_phis (g->e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       gimple phi = gsi_stmt (gsi);
+      source_location locus;
 
       p0 = var_to_partition (g->map, gimple_phi_result (phi));
       /* Ignore results which are not in partitions.  */
@@ -439,6 +476,7 @@ eliminate_build (elim_graph g)
 	continue;
 
       Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
+      locus = gimple_phi_arg_location_from_edge (phi, g->e);
 
       /* If this argument is a constant, or a SSA_NAME which is being
 	 left in SSA form, just queue a copy to be emitted on this
@@ -451,6 +489,7 @@ eliminate_build (elim_graph g)
 	     on this edge.  */
 	  VEC_safe_push (int, heap, g->const_dests, p0);
 	  VEC_safe_push (tree, heap, g->const_copies, Ti);
+	  VEC_safe_push (source_location, heap, g->copy_locus, locus);
 	}
       else
         {
@@ -459,7 +498,7 @@ eliminate_build (elim_graph g)
 	    {
 	      eliminate_name (g, p0);
 	      eliminate_name (g, pi);
-	      elim_graph_add_edge (g, p0, pi);
+	      elim_graph_add_edge (g, p0, pi, locus);
 	    }
 	}
     }
@@ -472,8 +511,10 @@ static void
 elim_forward (elim_graph g, int T)
 {
   int S;
+  source_location locus;
+
   SET_BIT (g->visited, T);
-  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S,
+  FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, locus,
     {
       if (!TEST_BIT (g->visited, S))
         elim_forward (g, S);
@@ -488,7 +529,9 @@ static int
 elim_unvisited_predecessor (elim_graph g, int T)
 {
   int P;
-  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
+  source_location locus;
+
+  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
     {
       if (!TEST_BIT (g->visited, P))
         return 1;
@@ -502,13 +545,15 @@ static void
 elim_backward (elim_graph g, int T)
 {
   int P;
+  source_location locus;
+
   SET_BIT (g->visited, T);
-  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
+  FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
     {
       if (!TEST_BIT (g->visited, P))
         {
 	  elim_backward (g, P);
-	  insert_partition_copy_on_edge (g->e, P, T);
+	  insert_partition_copy_on_edge (g->e, P, T, locus);
 	}
     });
 }
@@ -537,6 +582,7 @@ static void
 elim_create (elim_graph g, int T)
 {
   int P, S;
+  source_location locus;
 
   if (elim_unvisited_predecessor (g, T))
     {
@@ -544,23 +590,23 @@ elim_create (elim_graph g, int T)
       rtx U = get_temp_reg (var);
       int unsignedsrcp = TYPE_UNSIGNED (TREE_TYPE (var));
 
-      insert_part_to_rtx_on_edge (g->e, U, T);
-      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, 
+      insert_part_to_rtx_on_edge (g->e, U, T, UNKNOWN_LOCATION);
+      FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
 	{
 	  if (!TEST_BIT (g->visited, P))
 	    {
 	      elim_backward (g, P);
-	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp);
+	      insert_rtx_to_part_on_edge (g->e, P, U, unsignedsrcp, locus);
 	    }
 	});
     }
   else
     {
-      S = elim_graph_remove_succ_edge (g, T);
+      S = elim_graph_remove_succ_edge (g, T, &locus);
       if (S != -1)
 	{
 	  SET_BIT (g->visited, T);
-	  insert_partition_copy_on_edge (g->e, T, S);
+	  insert_partition_copy_on_edge (g->e, T, S, locus);
 	}
     }
 }
@@ -574,6 +620,7 @@ eliminate_phi (edge e, elim_graph g)
   int x;
 
   gcc_assert (VEC_length (tree, g->const_copies) == 0);
+  gcc_assert (VEC_length (source_location, g->copy_locus) == 0);
 
   /* Abnormal edges already have everything coalesced.  */
   if (e->flags & EDGE_ABNORMAL)
@@ -610,9 +657,12 @@ eliminate_phi (edge e, elim_graph g)
     {
       int dest;
       tree src;
+      source_location locus;
+
       src = VEC_pop (tree, g->const_copies);
       dest = VEC_pop (int, g->const_dests);
-      insert_value_copy_on_edge (e, dest, src);
+      locus = VEC_pop (source_location, g->copy_locus);
+      insert_value_copy_on_edge (e, dest, src, locus);
     }
 }
 
@@ -991,6 +1041,11 @@ insert_backedge_copies (void)
 		  name = make_ssa_name (result_var, stmt);
 		  gimple_assign_set_lhs (stmt, name);
 
+		  /* copy location if present.  */
+		  if (gimple_phi_arg_has_location (phi, i))
+		    gimple_set_location (stmt, 
+					 gimple_phi_arg_location (phi, i));
+
 		  /* Insert the new statement into the block and update
 		     the PHI node.  */
 		  if (last && stmt_ends_bb_p (last))
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index f9a2e40d480d4cb501edba7048ebf4048470b5c7..9acf0ff75f0db8f798e042837d5e53e075d6e388 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -747,6 +747,7 @@ create_phi_for_local_result (void **slot, void *data)
   gimple new_phi;
   basic_block store_bb;
   tree local_res;
+  source_location locus;
 
   /* STORE_BB is the block where the phi 
      should be stored.  It is the destination of the loop exit.  
@@ -765,11 +766,12 @@ create_phi_for_local_result (void **slot, void *data)
   local_res
     = make_ssa_name (SSA_NAME_VAR (gimple_assign_lhs (reduc->reduc_stmt)),
 		     NULL);
+  locus = gimple_location (reduc->reduc_stmt);
   new_phi = create_phi_node (local_res, store_bb);
   SSA_NAME_DEF_STMT (local_res) = new_phi;
-  add_phi_arg (new_phi, reduc->init, e);
+  add_phi_arg (new_phi, reduc->init, e, locus);
   add_phi_arg (new_phi, gimple_assign_lhs (reduc->reduc_stmt),
-	       FALLTHRU_EDGE (loop->latch));
+	       FALLTHRU_EDGE (loop->latch), locus);
   reduc->new_phi = new_phi;
 
   return 1;
@@ -1219,7 +1221,7 @@ transform_to_exit_first_loop (struct loop *loop, htab_t reduction_list, tree nit
 
       nphi = create_phi_node (res, orig_header);
       SSA_NAME_DEF_STMT (res) = nphi;
-      add_phi_arg (nphi, t, hpred);
+      add_phi_arg (nphi, t, hpred, UNKNOWN_LOCATION);
 
       if (res == control)
 	{
@@ -1370,14 +1372,20 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
   end = make_edge (loop->latch, ex_bb, EDGE_FALLTHRU);
   for (gsi = gsi_start_phis (ex_bb); !gsi_end_p (gsi); gsi_next (&gsi))
     {
+      source_location locus;
+      tree def;
       phi = gsi_stmt (gsi);
       res = PHI_RESULT (phi);
       stmt = SSA_NAME_DEF_STMT (PHI_ARG_DEF_FROM_EDGE (phi, exit));
-      add_phi_arg (phi,
-		   PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop)),
-		   guard);
-      add_phi_arg (phi, PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop)),
-		   end);
+
+      def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_preheader_edge (loop));
+      locus = gimple_phi_arg_location_from_edge (stmt, 
+						 loop_preheader_edge (loop));
+      add_phi_arg (phi, def, guard, locus);
+
+      def = PHI_ARG_DEF_FROM_EDGE (stmt, loop_latch_edge (loop));
+      locus = gimple_phi_arg_location_from_edge (stmt, loop_latch_edge (loop));
+      add_phi_arg (phi, def, end, locus);
     }
   e = redirect_edge_and_branch (exit, nexit->dest);
   PENDING_STMT (e) = NULL;
diff --git a/gcc/tree-phinodes.c b/gcc/tree-phinodes.c
index 2907807690a58f2689c5da496cb34b32173418ad..a48ae01fe8d433d128d7113c7762af72ba9b4556 100644
--- a/gcc/tree-phinodes.c
+++ b/gcc/tree-phinodes.c
@@ -231,6 +231,8 @@ make_phi_node (tree var, int len)
   for (i = 0; i < capacity; i++)
     {
       use_operand_p  imm;
+
+      gimple_phi_arg_set_location (phi, i, UNKNOWN_LOCATION);
       imm = gimple_phi_arg_imm_use_ptr (phi, i);
       imm->use = gimple_phi_arg_def_ptr (phi, i);
       imm->prev = NULL;
@@ -299,6 +301,8 @@ resize_phi_node (gimple *phi, size_t len)
   for (i = gimple_phi_num_args (new_phi); i < len; i++)
     {
       use_operand_p imm;
+
+      gimple_phi_arg_set_location (new_phi, i, UNKNOWN_LOCATION);
       imm = gimple_phi_arg_imm_use_ptr (new_phi, i);
       imm->use = gimple_phi_arg_def_ptr (new_phi, i);
       imm->prev = NULL;
@@ -384,7 +388,7 @@ create_phi_node (tree var, basic_block bb)
    PHI points to the reallocated phi node when we return.  */
 
 void
-add_phi_arg (gimple phi, tree def, edge e)
+add_phi_arg (gimple phi, tree def, edge e, source_location locus)
 {
   basic_block bb = e->dest;
 
@@ -407,6 +411,7 @@ add_phi_arg (gimple phi, tree def, edge e)
     }
 
   SET_PHI_ARG_DEF (phi, e->dest_idx, def);
+  gimple_phi_arg_set_location (phi, e->dest_idx, locus);
 }
 
 
@@ -435,6 +440,9 @@ remove_phi_arg_num (gimple phi, int i)
       /* Set use on new node, and link into last element's place.  */
       *(new_p->use) = *(old_p->use);
       relink_imm_use (new_p, old_p);
+      /* Move the location as well.  */
+      gimple_phi_arg_set_location (phi, i, 
+				   gimple_phi_arg_location (phi, num_elem - 1));
     }
 
   /* Shrink the vector and return.  Note that we do not have to clear
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 5d8bf4d27042eccf106e0e6f97b0b9030e93cb0b..0ce35f5de86a5918945173f07686142e6c623a3f 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -1512,8 +1512,8 @@ initialize_root_vars (struct loop *loop, chain_p chain, bitmap tmp_vars)
 
       phi = create_phi_node (var, loop->header);
       SSA_NAME_DEF_STMT (var) = phi;
-      add_phi_arg (phi, init, entry);
-      add_phi_arg (phi, next, latch);
+      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
+      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
     }
 }
 
@@ -1576,8 +1576,8 @@ initialize_root_vars_lm (struct loop *loop, dref root, bool written,
       next = VEC_index (tree, *vars, 1);
       phi = create_phi_node (var, loop->header);
       SSA_NAME_DEF_STMT (var) = phi;
-      add_phi_arg (phi, init, entry);
-      add_phi_arg (phi, next, latch);
+      add_phi_arg (phi, init, entry, UNKNOWN_LOCATION);
+      add_phi_arg (phi, next, latch, UNKNOWN_LOCATION);
     }
   else
     {
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index c1f4e7f647b41b5eaeae007f6a2aab6fa852b8f2..2eec3147886e6d65db5b26c4266d3b4a669e1a6a 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -951,6 +951,7 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
 	{
 	  gimple phi = gsi_stmt (gsi);
 	  tree op;
+	  source_location locus;
 
 	  /* Dead PHI do not imply control dependency.  */
           if (!gimple_plf (phi, STMT_NECESSARY)
@@ -975,10 +976,16 @@ forward_edge_to_pdom (edge e, basic_block post_dom_bb)
 	      continue;
 	    }
 	  if (!e2)
-	    op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
+	    {
+	      op = gimple_phi_arg_def (phi, e->dest_idx == 0 ? 1 : 0);
+	      locus = gimple_phi_arg_location (phi, e->dest_idx == 0 ? 1 : 0);
+	    }
 	  else
-	    op = gimple_phi_arg_def (phi, e2->dest_idx);
-	  add_phi_arg (phi, op, e);
+	    {
+	      op = gimple_phi_arg_def (phi, e2->dest_idx);
+	      locus = gimple_phi_arg_location (phi, e2->dest_idx);
+	    }
+	  add_phi_arg (phi, op, e, locus);
 	  gcc_assert (e2 || degenerate_phi_p (phi));
 	  gsi_next (&gsi);
 	}
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index c4a40b084a6e491fb92cf7b12de522f15a136ef0..e43c0bc404a5479cfeb9209449fe94acff3ef75d 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -125,8 +125,8 @@ create_iv (tree base, tree step, tree var, struct loop *loop,
 
   stmt = create_phi_node (vb, loop->header);
   SSA_NAME_DEF_STMT (vb) = stmt;
-  add_phi_arg (stmt, initial, loop_preheader_edge (loop));
-  add_phi_arg (stmt, va, loop_latch_edge (loop));
+  add_phi_arg (stmt, initial, loop_preheader_edge (loop), UNKNOWN_LOCATION);
+  add_phi_arg (stmt, va, loop_latch_edge (loop), UNKNOWN_LOCATION);
 }
 
 /* Add exit phis for the USE on EXIT.  */
@@ -156,7 +156,7 @@ add_exit_phis_edge (basic_block exit, tree use)
   create_new_def_for (gimple_phi_result (phi), phi,
 		      gimple_phi_result_ptr (phi));
   FOR_EACH_EDGE (e, ei, exit->preds)
-    add_phi_arg (phi, use, e);
+    add_phi_arg (phi, use, e, UNKNOWN_LOCATION);
 }
 
 /* Add exit phis for VAR that is used in LIVEIN.
@@ -476,11 +476,13 @@ split_loop_exit_edge (edge exit)
   tree new_name, name;
   use_operand_p op_p;
   gimple_stmt_iterator psi;
+  source_location locus;
 
   for (psi = gsi_start_phis (dest); !gsi_end_p (psi); gsi_next (&psi))
     {
       phi = gsi_stmt (psi);
       op_p = PHI_ARG_DEF_PTR_FROM_EDGE (phi, single_succ_edge (bb));
+      locus = gimple_phi_arg_location_from_edge (phi, single_succ_edge (bb));
 
       name = USE_FROM_PTR (op_p);
 
@@ -494,7 +496,7 @@ split_loop_exit_edge (edge exit)
       new_name = duplicate_ssa_name (name, NULL);
       new_phi = create_phi_node (new_name, bb);
       SSA_NAME_DEF_STMT (new_name) = new_phi;
-      add_phi_arg (new_phi, name, exit);
+      add_phi_arg (new_phi, name, exit, locus);
       SET_USE (op_p, new_name);
     }
 
@@ -1014,8 +1016,8 @@ tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
       phi_rest = create_phi_node (new_init, rest);
       SSA_NAME_DEF_STMT (new_init) = phi_rest;
 
-      add_phi_arg (phi_rest, init, precond_edge);
-      add_phi_arg (phi_rest, next, new_exit);
+      add_phi_arg (phi_rest, init, precond_edge, UNKNOWN_LOCATION);
+      add_phi_arg (phi_rest, next, new_exit, UNKNOWN_LOCATION);
       SET_USE (op, new_init);
     }
 
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 8c3f71d32b6a73e3faeb85adad3349054b00ccad..97847f4c8882fe9bd3fddc27db0a6892783a2618 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -513,6 +513,8 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
 
   if (!useless_type_conversion_p (TREE_TYPE (result), TREE_TYPE (new_var)))
     {
+      source_location locus_0, locus_1;
+
       new_var2 = create_tmp_var (TREE_TYPE (result), NULL);
       add_referenced_var (new_var2);
       new_stmt = gimple_build_assign_with_ops (CONVERT_EXPR, new_var2,
@@ -521,6 +523,13 @@ conditional_replacement (basic_block cond_bb, basic_block middle_bb,
       gimple_assign_set_lhs (new_stmt, new_var2);
       gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
       new_var = new_var2;
+
+      /* Set the locus to the first argument, unless is doesn't have one.  */
+      locus_0 = gimple_phi_arg_location (phi, 0);
+      locus_1 = gimple_phi_arg_location (phi, 1);
+      if (locus_0 == UNKNOWN_LOCATION)
+        locus_0 = locus_1;
+      gimple_set_location (new_stmt, locus_0);
     }
 
   replace_phi_edge_with_variable (cond_bb, e1, phi, new_var);
@@ -1177,6 +1186,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
   tree lhs, rhs, name;
   gimple newphi, new_stmt;
   gimple_stmt_iterator gsi;
+  source_location locus;
   enum tree_code code;
 
   /* Check if middle_bb contains of only one store.  */
@@ -1184,6 +1194,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
       || gimple_code (assign) != GIMPLE_ASSIGN)
     return false;
 
+  locus = gimple_location (assign);
   lhs = gimple_assign_lhs (assign);
   rhs = gimple_assign_rhs1 (assign);
   if (!INDIRECT_REF_P (lhs))
@@ -1224,6 +1235,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
   new_stmt = gimple_build_assign (condstoretemp, lhs);
   name = make_ssa_name (condstoretemp, new_stmt);
   gimple_assign_set_lhs (new_stmt, name);
+  gimple_set_location (new_stmt, locus);
   mark_symbols_for_renaming (new_stmt);
   gsi_insert_on_edge (e1, new_stmt);
 
@@ -1231,8 +1243,8 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
         holding the old RHS, and the other holding the temporary
         where we stored the old memory contents.  */
   newphi = create_phi_node (condstoretemp, join_bb);
-  add_phi_arg (newphi, rhs, e0);
-  add_phi_arg (newphi, name, e1);
+  add_phi_arg (newphi, rhs, e0, locus);
+  add_phi_arg (newphi, name, e1, locus);
 
   lhs = unshare_expr (lhs);
   new_stmt = gimple_build_assign (lhs, PHI_RESULT (newphi));
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 022e4af9a4847f83928b591d4fa8ffc8ef170473..bac2303899f1e7847de2994f1a407a93087d0a14 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -159,14 +159,17 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
     {
       tree old_arg, new_var;
       gimple tmp;
+      source_location locus;
 
       old_arg = PHI_ARG_DEF_FROM_EDGE (phi, e);
+      locus = gimple_phi_arg_location_from_edge (phi, e);
       while (TREE_CODE (old_arg) == SSA_NAME
 	     && (SSA_NAME_VERSION (old_arg) >= n
 	         || phivn[SSA_NAME_VERSION (old_arg)].value == NULL_TREE))
 	{
 	  gimple def_stmt = SSA_NAME_DEF_STMT (old_arg);
 	  old_arg = gimple_assign_rhs1 (def_stmt);
+	  locus = gimple_location (def_stmt);
 	}
 
       if (TREE_CODE (old_arg) == SSA_NAME)
@@ -196,6 +199,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
 	  add_referenced_var (new_var);
 	  new_var = make_ssa_name (new_var, tmp);
 	  gimple_assign_set_lhs (tmp, new_var);
+	  gimple_set_location (tmp, locus);
 
 	  gsi_insert_on_edge (e, tmp);
 	  update_stmt (tmp);
@@ -209,7 +213,7 @@ phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt,
 	    }
 	}
 
-      add_phi_arg (new_phi, new_var, e);
+      add_phi_arg (new_phi, new_var, e, locus);
     }
 
   update_stmt (new_phi);
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 9e3754b37fcf2c82e4bbfe00922bb86733b17f9d..237c250a5f0069aec225ce9a3b1c21834c098dad 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3328,9 +3328,10 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
       gcc_assert (get_expr_type (ae) == type
 		  || useless_type_conversion_p (type, get_expr_type (ae)));
       if (ae->kind == CONSTANT)
-	add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred);
+	add_phi_arg (phi, PRE_EXPR_CONSTANT (ae), pred, UNKNOWN_LOCATION);
       else
-	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred);
+	add_phi_arg (phi, PRE_EXPR_NAME (avail[pred->src->index]), pred,
+		     UNKNOWN_LOCATION);
     }
 
   newphi = get_or_alloc_expr_for_name (gimple_phi_result (phi));
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index b6d2fafaa0fd377fb2d24657ddd32bc5223a7c00..71a34957bdf0387e19a42a1ab00cc11eeadc7ba8 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -325,9 +325,11 @@ create_edge_and_update_destination_phis (struct redirection_data *rd)
   for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       gimple phi = gsi_stmt (gsi);
-
+      source_location locus;
       int indx = rd->outgoing_edge->dest_idx;
-      add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e);
+
+      locus = gimple_phi_arg_location (phi, indx);
+      add_phi_arg (phi, gimple_phi_arg_def (phi, indx), e, locus);
     }
 }
 
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 7ec04f70fadb97b931aa0816460b5c29c2278541..e8033cd46caf5827259dc2cc7f2e214869e9acbe 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -53,7 +53,7 @@ static struct pointer_map_t *edge_var_maps;
 /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
 
 void
-redirect_edge_var_map_add (edge e, tree result, tree def)
+redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
 {
   void **slot;
   edge_var_map_vector old_head, head;
@@ -71,6 +71,7 @@ redirect_edge_var_map_add (edge e, tree result, tree def)
     }
   new_node.def = def;
   new_node.result = result;
+  new_node.locus = locus;
 
   VEC_safe_push (edge_var_map, heap, head, &new_node);
   if (old_head != head)
@@ -193,14 +194,16 @@ ssa_redirect_edge (edge e, basic_block dest)
   for (gsi = gsi_start_phis (e->dest); !gsi_end_p (gsi); gsi_next (&gsi))
     {
       tree def;
+      source_location locus ;
 
       phi = gsi_stmt (gsi);
       def = gimple_phi_arg_def (phi, e->dest_idx);
+      locus = gimple_phi_arg_location (phi, e->dest_idx);
 
       if (def == NULL_TREE)
 	continue;
 
-      redirect_edge_var_map_add (e, gimple_phi_result (phi), def);
+      redirect_edge_var_map_add (e, gimple_phi_result (phi), def, locus);
     }
 
   e = redirect_edge_succ_nodup (e, dest);
@@ -233,7 +236,7 @@ flush_pending_stmts (edge e)
 
       phi = gsi_stmt (gsi);
       def = redirect_edge_var_map_def (vm);
-      add_phi_arg (phi, def, e);
+      add_phi_arg (phi, def, e, redirect_edge_var_map_location (vm));
     }
 
   redirect_edge_var_map_clear (e);
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index a5494827b37f23306b75d87e2c7f9b801bd91d2e..1309e822fe2b426f327842bbade2c377e5617757 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -638,8 +638,8 @@ fix_phi_nodes (edge e1f, edge e2f, basic_block bbf)
        !gsi_end_p (gsi); gsi_next (&gsi), i++)
     {
       gimple phi = gsi_stmt (gsi);
-      add_phi_arg (phi, info.target_inbound_names[i], e1f);
-      add_phi_arg (phi, info.target_outbound_names[i], e2f);
+      add_phi_arg (phi, info.target_inbound_names[i], e1f, UNKNOWN_LOCATION);
+      add_phi_arg (phi, info.target_outbound_names[i], e2f, UNKNOWN_LOCATION);
     }
 
 }
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index f2d58dd6e4ac0ba7cd570e76b3cf23b064e8c054..efd6bc2c029702b770f1bb0c1c18155c8fa17cf8 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -548,7 +548,7 @@ add_successor_phi_arg (edge e, tree var, tree phi_arg)
       break;
 
   gcc_assert (!gsi_end_p (gsi));
-  add_phi_arg (gsi_stmt (gsi), phi_arg, e);
+  add_phi_arg (gsi_stmt (gsi), phi_arg, e, UNKNOWN_LOCATION);
 }
 
 /* Creates a GIMPLE statement which computes the operation specified by
@@ -773,7 +773,7 @@ eliminate_tail_call (struct tailcall *t)
       phi = gsi_stmt (gsi);
       gcc_assert (param == SSA_NAME_VAR (PHI_RESULT (phi)));
 
-      add_phi_arg (phi, arg, e);
+      add_phi_arg (phi, arg, e, gimple_location (stmt));
       gsi_next (&gsi);
     }
 
@@ -870,7 +870,8 @@ create_tailcall_accumulator (const char *label, basic_block bb, tree init)
   add_referenced_var (tmp);
   phi = create_phi_node (tmp, bb);
   /* RET_TYPE can be a float when -ffast-maths is enabled.  */
-  add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb));
+  add_phi_arg (phi, fold_convert (ret_type, init), single_pred_edge (bb),
+	       UNKNOWN_LOCATION);
   return PHI_RESULT (phi);
 }
  
@@ -933,7 +934,8 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls)
 		set_default_def (param, new_name);
 		phi = create_phi_node (name, first);
 		SSA_NAME_DEF_STMT (name) = phi;
-		add_phi_arg (phi, new_name, single_pred_edge (first));
+		add_phi_arg (phi, new_name, single_pred_edge (first), 
+			     EXPR_LOCATION (param));
 	      }
 	  phis_constructed = true;
 	}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 7646cc1ad0f290d0290349dce17da5301fadfa29..facde06969e4db701ab9b0f7e036ffe13589d97b 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -3049,7 +3049,7 @@ vect_setup_realignment (gimple stmt, gimple_stmt_iterator *gsi,
   msq = make_ssa_name (vec_dest, NULL);
   phi_stmt = create_phi_node (msq, containing_loop->header);
   SSA_NAME_DEF_STMT (msq) = phi_stmt;
-  add_phi_arg (phi_stmt, msq_init, pe);
+  add_phi_arg (phi_stmt, msq_init, pe, UNKNOWN_LOCATION);
 
   return msq;
 }
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index eaf263c4270c8675c4878930f42741b5d9e9247b..c0b15cd98a548662fb3432e8195a022c4be2501c 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -169,15 +169,18 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
        !gsi_end_p (gsi_new) && !gsi_end_p (gsi_orig);
        gsi_next (&gsi_new), gsi_next (&gsi_orig))
     {
+      source_location locus;
       phi_new = gsi_stmt (gsi_new);
       phi_orig = gsi_stmt (gsi_orig);
 
       /* step 1.  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, entry_arg_e);
-      add_phi_arg (phi_new, def, new_loop_entry_e);
+      locus = gimple_phi_arg_location_from_edge (phi_orig, entry_arg_e);
+      add_phi_arg (phi_new, def, new_loop_entry_e, locus);
 
       /* step 2.  */
       def = PHI_ARG_DEF_FROM_EDGE (phi_orig, orig_loop_latch);
+      locus = gimple_phi_arg_location_from_edge (phi_orig, orig_loop_latch);
       if (TREE_CODE (def) != SSA_NAME)
         continue;
 
@@ -190,7 +193,7 @@ slpeel_update_phis_for_duplicate_loop (struct loop *orig_loop,
 	}
 
       /* An ordinary ssa name defined in the loop.  */
-      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop));
+      add_phi_arg (phi_new, new_ssa_name, loop_latch_edge (new_loop), locus);
 
       /* step 3 (case 1).  */
       if (!after)
@@ -383,6 +386,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
        !gsi_end_p (gsi_orig) && !gsi_end_p (gsi_update);
        gsi_next (&gsi_orig), gsi_next (&gsi_update))
     {
+      source_location loop_locus, guard_locus;;
       orig_phi = gsi_stmt (gsi_orig);
       update_phi = gsi_stmt (gsi_update);
 
@@ -395,10 +399,16 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
       /* 1.2. NEW_MERGE_BB has two incoming edges: GUARD_EDGE and the exit-edge
             of LOOP. Set the two phi args in NEW_PHI for these edges:  */
       loop_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, EDGE_SUCC (loop->latch, 0));
+      loop_locus = gimple_phi_arg_location_from_edge (orig_phi, 
+						      EDGE_SUCC (loop->latch, 
+								 0));
       guard_arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, loop_preheader_edge (loop));
+      guard_locus 
+	= gimple_phi_arg_location_from_edge (orig_phi, 
+					     loop_preheader_edge (loop));
 
-      add_phi_arg (new_phi, loop_arg, new_exit_e);
-      add_phi_arg (new_phi, guard_arg, guard_edge);
+      add_phi_arg (new_phi, loop_arg, new_exit_e, loop_locus);
+      add_phi_arg (new_phi, guard_arg, guard_edge, guard_locus);
 
       /* 1.3. Update phi in successor block.  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == loop_arg
@@ -417,7 +427,7 @@ slpeel_update_phi_nodes_for_guard1 (edge guard_edge, struct loop *loop,
                                  *new_exit_bb);
 
       /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop.  */
-      add_phi_arg (new_phi, loop_arg, single_exit (loop));
+      add_phi_arg (new_phi, loop_arg, single_exit (loop), loop_locus);
 
       /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@@ -545,8 +555,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
       if (new_name2)
         guard_arg = new_name2;
   
-      add_phi_arg (new_phi, loop_arg, new_exit_e);
-      add_phi_arg (new_phi, guard_arg, guard_edge);
+      add_phi_arg (new_phi, loop_arg, new_exit_e, UNKNOWN_LOCATION);
+      add_phi_arg (new_phi, guard_arg, guard_edge, UNKNOWN_LOCATION);
 
       /* 1.3. Update phi in successor block.  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi, e) == orig_def);
@@ -561,7 +571,7 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
                                  *new_exit_bb);
 
       /* 2.2. NEW_EXIT_BB has one incoming edge: the exit-edge of the loop.  */
-      add_phi_arg (new_phi, loop_arg, single_exit (loop));
+      add_phi_arg (new_phi, loop_arg, single_exit (loop), UNKNOWN_LOCATION);
 
       /* 2.3. Update phi in successor of NEW_EXIT_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, new_exit_e) == loop_arg);
@@ -596,7 +606,8 @@ slpeel_update_phi_nodes_for_guard2 (edge guard_edge, struct loop *loop,
 
       /* 3.3. GUARD_BB has one incoming edge:  */
       gcc_assert (EDGE_COUNT (guard_edge->src->preds) == 1);
-      add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0));
+      add_phi_arg (new_phi, arg, EDGE_PRED (guard_edge->src, 0), 
+		   UNKNOWN_LOCATION);
 
       /* 3.4. Update phi in successor of GUARD_BB:  */
       gcc_assert (PHI_ARG_DEF_FROM_EDGE (update_phi2, guard_edge)
@@ -720,13 +731,15 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
       if (phi_arg)
 	{
 	  edge new_loop_exit_edge;
+	  source_location locus;
 
+	  locus = gimple_phi_arg_location_from_edge (phi, single_exit (loop));
 	  if (EDGE_SUCC (new_loop->header, 0)->dest == new_loop->latch)
 	    new_loop_exit_edge = EDGE_SUCC (new_loop->header, 1);
 	  else
 	    new_loop_exit_edge = EDGE_SUCC (new_loop->header, 0);
   
-	  add_phi_arg (phi, phi_arg, new_loop_exit_edge);	
+	  add_phi_arg (phi, phi_arg, new_loop_exit_edge, locus);	
 	}
     }    
    
@@ -764,7 +777,8 @@ slpeel_tree_duplicate_loop_to_edge_cfg (struct loop *loop, edge e)
 	  phi = gsi_stmt (gsi);
 	  phi_arg = PHI_ARG_DEF_FROM_EDGE (phi, entry_e);
 	  if (phi_arg)
-	    add_phi_arg (phi, phi_arg, new_exit_e);	
+	    add_phi_arg (phi, phi_arg, new_exit_e,
+			 gimple_phi_arg_location_from_edge (phi, entry_e));	
 	}    
 
       redirect_edge_and_branch_force (entry_e, new_loop->header);
@@ -954,8 +968,9 @@ set_prologue_iterations (basic_block bb_before_first_loop,
     gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT);
 
   newphi = create_phi_node (var, bb_before_first_loop);
-  add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru);
-  add_phi_arg (newphi, first_niters, e_false);
+  add_phi_arg (newphi, prologue_after_cost_adjust_name, e_fallthru, 
+	       UNKNOWN_LOCATION);
+  add_phi_arg (newphi, first_niters, e_false, UNKNOWN_LOCATION);
 
   first_niters = PHI_RESULT (newphi);
 }
@@ -2383,7 +2398,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo, bool do_versioning,
       new_phi = create_phi_node (SSA_NAME_VAR (PHI_RESULT (orig_phi)),
 				  new_exit_bb);
       arg = PHI_ARG_DEF_FROM_EDGE (orig_phi, e);
-      add_phi_arg (new_phi, arg, new_exit_e);
+      add_phi_arg (new_phi, arg, new_exit_e, 
+		   gimple_phi_arg_location_from_edge (orig_phi, e));
       SET_PHI_ARG_DEF (orig_phi, e->dest_idx, PHI_RESULT (new_phi));
     } 
 
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index b7b9d7893e5038dd2f27ecb1fe819bbd30cc48ed..113dc0ff0e6bc20ef67bb8e7d7389e013b523fcd 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2524,8 +2524,9 @@ get_initial_def_for_induction (gimple iv_phi)
                                                    NULL));
 
   /* Set the arguments of the phi node:  */
-  add_phi_arg (induction_phi, vec_init, pe);
-  add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop));
+  add_phi_arg (induction_phi, vec_init, pe, UNKNOWN_LOCATION);
+  add_phi_arg (induction_phi, vec_def, loop_latch_edge (iv_loop), 
+	       UNKNOWN_LOCATION);
 
 
   /* In case that vectorization factor (VF) is bigger than the number
@@ -2934,12 +2935,13 @@ vect_create_epilog_for_reduction (tree vect_def, gimple stmt,
   for (j = 0; j < ncopies; j++)
     {
       /* 1.1 set the loop-entry arg of the reduction-phi:  */
-      add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop));
+      add_phi_arg (phi, vec_initial_def, loop_preheader_edge (loop), 
+		   UNKNOWN_LOCATION);
 
       /* 1.2 set the loop-latch arg for the reduction-phi:  */
       if (j > 0)
         def = vect_get_vec_def_for_stmt_copy (dt, def);
-      add_phi_arg (phi, def, loop_latch_edge (loop));
+      add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
 
       if (vect_print_dump_info (REPORT_DETAILS))
 	{
@@ -3350,9 +3352,9 @@ vect_finalize_reduction:
                
               /* Update phi node arguments with vs0 and vs2.  */
               add_phi_arg (vect_phi, vect_phi_init, 
-                           loop_preheader_edge (outer_loop));
+                           loop_preheader_edge (outer_loop), UNKNOWN_LOCATION);
               add_phi_arg (vect_phi, PHI_RESULT (epilog_stmt), 
-                           loop_latch_edge (outer_loop));
+                           loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
               if (vect_print_dump_info (REPORT_DETAILS))
                 {
                   fprintf (vect_dump, "created double reduction phi node: ");
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 50900775a04eb97e6bd84b4b67e95b9448caa50d..aacf768a4cf7f6035cdaf3437a69b05356275ef5 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -3639,7 +3639,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
 		{
 		  gcc_assert (phi);
 		  if (i == vec_num - 1 && j == ncopies - 1)
-		    add_phi_arg (phi, lsq, loop_latch_edge (containing_loop));
+		    add_phi_arg (phi, lsq, loop_latch_edge (containing_loop),
+				 UNKNOWN_LOCATION);
 		  msq = lsq;
 		}
 	    }
diff --git a/gcc/tree.h b/gcc/tree.h
index d972cfe334e490c89c30ea2ee8cc603f6aece060..a1370fa5e55726367db6d78f4106e79cb6a755d4 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1888,6 +1888,7 @@ struct GTY(()) phi_arg_d {
      pointer arithmetic with it.  See phi_arg_index_from_use.  */
   struct ssa_use_operand_d imm_use;
   tree def;
+  location_t locus;
 };