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]

[debuglocus] More Infrastructure.


This patch adds a bunch more infrastructure.

- debuglocus's are now created at into-ssa
- outof-ssa has been modified to support creating debuglocus when PHI copies are created
- debuglocus lists are supported, but not used yet.
- the print routines now dump the list of debuglocus's for a statement
- A few optimizations deal with debuglocus, but nothing earthshattering.


Nothing too interesting yet, but the guts are now in place. The next steps will be to:
- propagate debuglocus's properly in tree-ssa-copy and outof-ssa, and
- do something with them when generating dwarf info.


Bootstrapped and no new regressions on x86_64-unknown-linux-gnu.

Andrew

2009-03-26  Andrew MacLeod  <amacleod@redhat.com>

	* tree-into-ssa.c (rewrite_stmt): Add debuglocus to statements.
	(rewrite_add_phi_arguments): Replicate just source location to phi args.
	(rewrite_into_ssa): Create debug table if it doesn't exist.
	* debuglocus.c (DEBUGLOCUS_INDEX): Macro to return index from locus.
	(init_debuglocus_table): Fix comment.
	(create_debuglocus_table): Create a single static table.
	(destroy_debuglocus_table): Delete elements from the table.
	(current_debuglocus_table): New. Return current table.
	(get_debuglocus_entry): Remove debuglocus_index type.
	(get_debuglocus): Always takes a debuglocus source location as a
	parameter.
	(create_debuglocus_entry): Use current_debuglocus_table().
	(create_duplicate_debuglocus): Clean up interface calls.
	(decl_needs_debuglocus_p): New. check if decl needs debuglocus.
	(debuglocus_index_from_pointer): New. Get table index.
	(debuglocus_from_pointer): New. Create locus from pointer.
	(create_debuglocus_for_decl): New. Create new entry.
	(create_debuglocus_for_decl_and_locus): New. Create new entry and set
	the locus field.
	(replace_gimple_locus_with_debuglocus): New. Replace locus on a stmt
	with a debuglocus.
	(merge_debuglocus): New. Merge 2 debuglocus lists.
	(find_debuglocus): New. Find a debuglocus within a list.
	(find_and_detach_debuglocus): New. Find and remove locus from a list.
	(find_and_detach_or_create_debuglocus): New. Find and remove from a
	list, or create a debuglocus if it isn't there.
	(debuglocus_iter_start): New. Start iteration over a list.
	(debuglocus_iter_next): New. Continue iteration over a list.
	(debuglocus_var_iter_start): New. Start iteration for decls over a list.
	(debuglocus_var_iter_next): New. Continue iteration.
	* debuglocus.h (DEBUGLOCUS_INDEX, GET_DEBUGLOCUS, 
	GET_LOCUS_FROM_DEBUGLOCUS, IS_DEBUGLOCUS_P): Remove.
	(debuglocus_iterator): New type.
	(FOR_EACH_DEBUGLOCUS): New iterator macro.
	(FOR_EACH_DEBUGLOCUS_VAR): New iterator macro.
	(is_debuglocus): New. Check is source locus is a debuglocus.
	(copy_debuglocus): Call new is_debuglocus routine.
	(locus_from_debuglocus): Rename from debuglocus_lookup_locus.
	* tree-pretty-print.c (dump_generic_node): Show debuglocus decls.
	* tree.c (expand_location): Use new routines, save debuglocus.
	* tree-phinodes.c (make_phi_node): Initialize original decl field.
	* gimple-pretty-print.c (dump_gimple_phi, dump_gimple_stmt,
	dump_implicit_edges): Show debuglocus decls.
	* function.h (struct function): Remove debuglocus table.
	* print-rtl.c (print_rtx): Show debuglocus decls.
	* tree-ssa-phiopt.c (conditional_replacement): Propagate debuglocus
	when merging/collapsing PHI nodes.
	* print-tree.c (print_node): Show debuglocus decls.
	* cfglayout.c (insn_debuglocus): Use renamed routines.
	* tree-inline.c (copy_phis_for_bb): Deep copy debuglocus's.
	(initialize_inlined_parameters): Just copy source locus for now.
	* tree-outof-ssa.c (struct _elim_graph): Change source_location lists
	to a phi argument pointer list.
	(insert_copy_on_edge): Use PhiArg pointer to create a debuglocus.
	(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): Work with Phi argument pointer rather than locus.
	* Makefile.in: Adjust debuglocus.h dependancies.
	* gimple.h (struct gimple_statement_phi): Add original_decl field.
	(gimple_copy_location): New. Deep copy of locus field.
	(gimple_source_location): New. Make debuglocus transparent.
	(gimple_phi_original_decl): New. Get original decl PHI was created for.



Index: tree-into-ssa.c
===================================================================
*** tree-into-ssa.c	(revision 145094)
--- tree-into-ssa.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 48,53 ****
--- 48,54 ----
  #include "ggc.h"
  #include "params.h"
  #include "vecprim.h"
+ #include "debuglocus.h"
  
  
  /* This file builds the SSA form for a function as described in:
*************** rewrite_stmt (struct dom_walk_data *walk
*** 1360,1365 ****
--- 1361,1373 ----
  	gcc_assert (DECL_P (var));
  	SET_DEF (def_p, make_ssa_name (var, stmt));
  	register_new_def (DEF_FROM_PTR (def_p), var);
+ 
+ 	/* Add a debuglocus if appropriate.  */
+ 	if (decl_needs_debuglocus_p (var))
+ 	  {
+ 	    debuglocus_p dlocus = create_debuglocus_for_decl (var);
+ 	    replace_gimple_locus_with_debuglocus (stmt, dlocus);
+ 	  }
        }
  }
  
*************** rewrite_add_phi_arguments (struct dom_wa
*** 1397,1404 ****
  	    {
  	      use_operand_p use = PHI_ARG_DEF_PTR_FROM_EDGE(phi, e);
  	      int index = PHI_ARG_INDEX_FROM_USE (use);
! 	      source_location locus = gimple_location (stmt);
! 
  	      gimple_phi_arg_set_location (phi, index, locus);
  	    }
  	}
--- 1405,1415 ----
  	    {
  	      use_operand_p use = PHI_ARG_DEF_PTR_FROM_EDGE(phi, e);
  	      int index = PHI_ARG_INDEX_FROM_USE (use);
! 	      /* Initially, Don't replicate the debuglocus into the arg.  
! 		 THe PHI node has a debuglocus for the original variable,
! 		 and any copies inserted that do not have a debuglocus on
! 		 the argument will have one generated from the PHI node.  */
! 	      source_location locus = gimple_source_location (stmt);
  	      gimple_phi_arg_set_location (phi, index, locus);
  	    }
  	}
*************** rewrite_into_ssa (void)
*** 2247,2252 ****
--- 2258,2266 ----
    
    timevar_push (TV_TREE_SSA_OTHER);
  
+   /* Initialize the debuglocus structures.  */
+   create_debuglocus_table ();
+ 
    /* Initialize operand data structures.  */
    init_ssa_operands ();
  
Index: debuglocus.c
===================================================================
*** debuglocus.c	(revision 145094)
--- debuglocus.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 46,51 ****
--- 46,53 ----
    
  #define DEBUGLOCUS_VEC_SIZE	8192
  #define DEBUGLOCUS_VEC_MEM	(DEBUGLOCUS_VEC_SIZE * sizeof (debuglocus))
+ #define DEBUGLOCUS_INDEX(LOCUS) ((LOCUS) & ~DEBUGLOCUS_BIT)
+ 
  
  
  /* Create and initialize a new debuglocus table.  */
*************** init_debuglocus_table (void)
*** 60,90 ****
    dlocus = (debuglocus_p) xmalloc (DEBUGLOCUS_VEC_MEM);
    VEC_safe_push (debuglocus_p, heap, tab->table, dlocus);
  
!   /* Reserve space numbner 0 for the NULL entry.  */
    tab->size = 1;
    return tab;
  }
  
  
! /* Create a debuglocus table for the current function.  */
  void
  create_debuglocus_table (void)
  {
!   cfun->debuglocus_table = init_debuglocus_table ();
  }
  
  
! /* Destroy the current function's debuglocus table.  */
  void
  destroy_debuglocus_table (void)
  {
!   cfun->debuglocus_table = NULL;
  }
  
  
  /* Return a pointer to the debuglocus in table TAB at index I.  */
  static debuglocus_p
! get_debuglocus_entry (debuglocus_table_t *tab, debuglocus_index i)
  {
    int v,e;
    debuglocus_p table_vec;
--- 62,111 ----
    dlocus = (debuglocus_p) xmalloc (DEBUGLOCUS_VEC_MEM);
    VEC_safe_push (debuglocus_p, heap, tab->table, dlocus);
  
!   /* Reserve space number 0 for the NULL entry.  */
    tab->size = 1;
    return tab;
  }
  
  
! static debuglocus_table_t *debugtable = NULL;
! 
! /* Create the current debuglocus table.  */
  void
  create_debuglocus_table (void)
  {
!   if (debugtable == NULL)
!     debugtable = init_debuglocus_table ();
  }
  
  
! /* Destroy the current debuglocus table.  */
  void
  destroy_debuglocus_table (void)
  {
!   if (debugtable)
!     {
!       unsigned int x;
!       for (x = 0; x < VEC_length (debuglocus_p, debugtable->table); x++)
!         free (VEC_index (debuglocus_p, debugtable->table, x));
!       VEC_free (debuglocus_p, heap, debugtable->table);
!       free (debugtable);
!     }
!   debugtable = NULL;
! }
! 
! 
! /* Return the currently active debugtable.  */
! static inline debuglocus_table_t *
! current_debuglocus_table (void)
! {
!   return debugtable;
  }
  
  
  /* Return a pointer to the debuglocus in table TAB at index I.  */
  static debuglocus_p
! get_debuglocus_entry (debuglocus_table_t *tab, unsigned int i)
  {
    int v,e;
    debuglocus_p table_vec;
*************** get_debuglocus_entry (debuglocus_table_t
*** 100,108 ****
  
  /* Return a pointer to the debuglocus entry at index I in the current table.  */
  debuglocus_p
! get_debuglocus (debuglocus_index i)
  {
!   return get_debuglocus_entry (cfun->debuglocus_table, i);
  }
  
  
--- 121,132 ----
  
  /* Return a pointer to the debuglocus entry at index I in the current table.  */
  debuglocus_p
! get_debuglocus (source_location dlocus)
  {
!   gcc_assert (is_debuglocus (dlocus));
! 
!   dlocus = DEBUGLOCUS_INDEX (dlocus);
!   return get_debuglocus_entry (current_debuglocus_table (), dlocus);
  }
  
  
*************** new_debuglocus_entry (debuglocus_table_t
*** 139,145 ****
  debuglocus_p
  create_debuglocus_entry (void)
  {
!   return new_debuglocus_entry (cfun->debuglocus_table);
  }
  
  
--- 163,169 ----
  debuglocus_p
  create_debuglocus_entry (void)
  {
!   return new_debuglocus_entry (current_debuglocus_table ());
  }
  
  
*************** create_duplicate_debuglocus (source_loca
*** 151,160 ****
    int root_i, new_i, src_i, dest_i, prev_dest_i;
    debuglocus_p root_p, new_p, src_p, dest_p, prev_dest_p;
  
!   gcc_assert (IS_DEBUGLOCUS_P (locus));
  
    root_i = DEBUGLOCUS_INDEX (locus);   /* Root is the locus being copied.  */
!   root_p = get_debuglocus (root_i);
  
    new_p = create_debuglocus_entry ();  /* New is the copy of root.  */
    /* The order field starts as the index of the new debuglocus.  */
--- 175,184 ----
    int root_i, new_i, src_i, dest_i, prev_dest_i;
    debuglocus_p root_p, new_p, src_p, dest_p, prev_dest_p;
  
!   gcc_assert (is_debuglocus (locus));
  
    root_i = DEBUGLOCUS_INDEX (locus);   /* Root is the locus being copied.  */
!   root_p = get_debuglocus_entry (current_debuglocus_table (), root_i);
  
    new_p = create_debuglocus_entry ();  /* New is the copy of root.  */
    /* The order field starts as the index of the new debuglocus.  */
*************** create_duplicate_debuglocus (source_loca
*** 171,179 ****
    /* Now duplicate and link in any other locus's which are linked to root.  */
    for (src_i = root_p->next; src_i != root_i; src_i = src_p->next)
     {
!      src_p = get_debuglocus (src_i);  /* Src is the node being copied.  */
!      dest_p = create_debuglocus_entry (); /* Dest is the new node.  */
       dest_i = dest_p->order;
       /* Initialize links  */
       prev_dest_p->next = dest_i;
       dest_p->prev = prev_dest_i;
--- 195,205 ----
    /* Now duplicate and link in any other locus's which are linked to root.  */
    for (src_i = root_p->next; src_i != root_i; src_i = src_p->next)
     {
!      /* Src is the node being copied. Dest is the new node.  */
!      src_p = get_debuglocus_entry (current_debuglocus_table (), src_i);  
!      dest_p = create_debuglocus_entry (); 
       dest_i = dest_p->order;
+ 
       /* Initialize links  */
       prev_dest_p->next = dest_i;
       dest_p->prev = prev_dest_i;
*************** create_duplicate_debuglocus (source_loca
*** 195,197 ****
--- 221,516 ----
    /* Return the debuglocus for the new copy.  */
    return new_i | DEBUGLOCUS_BIT;
  }
+ 
+ 
+ /* Decide whether VAR should have a debuglocus emitted.  */
+ bool
+ decl_needs_debuglocus_p (tree var)
+ {
+   if (TREE_CODE (var) != VAR_DECL
+       && TREE_CODE (var) != PARM_DECL)
+     return false;
+ 
+   if (DECL_IGNORED_P (var))
+     return false;
+ 
+   if (!DECL_NAME (var)) {
+       tree origin = DECL_ABSTRACT_ORIGIN (var);
+ 
+       if (!origin)
+ 	return false;
+ 
+       if (!DECL_P (origin))
+ 	return false;
+ 
+       if (!DECL_NAME (origin))
+ 	return false;
+     }
+ 
+   if (!is_gimple_reg (var))
+     return false;
+ 
+   return true;
+ }
+ 
+ 
+ /* Return the source_location setting for the debuglocus table entry DLOCUS.  */
+ static source_location 
+ debuglocus_index_from_pointer (debuglocus_p dlocus)
+ {
+   unsigned int x;
+   source_location idx = UNKNOWN_LOCATION;
+   debuglocus_table_t *tab = current_debuglocus_table();
+ 
+   for (x = 0; x  < VEC_length (debuglocus_p, tab->table); x++)
+     {
+       debuglocus_p ptr = VEC_index (debuglocus_p, tab->table, x);
+       /* Find the table this pointer belongs to.  */
+       if (ptr <= dlocus && dlocus < ptr + DEBUGLOCUS_VEC_SIZE)
+         {
+           idx = ((x * DEBUGLOCUS_VEC_SIZE) + (dlocus - ptr));
+ 	  break;
+ 	}
+     }
+ 
+   gcc_assert (idx != UNKNOWN_LOCATION);
+   gcc_assert (idx > 0 && idx < tab->size);
+ 
+   return idx;
+ }
+ 
+ 
+ /* Return the source_location setting for the debuglocus table entry DLOCUS.  */
+ static source_location 
+ debuglocus_from_pointer (debuglocus_p dlocus)
+ {
+   source_location res = debuglocus_index_from_pointer (dlocus);
+   res = res | DEBUGLOCUS_BIT;
+   gcc_assert (dlocus == get_debuglocus (res));
+ 
+   return res;
+ }
+ 
+ 
+ /* Create and return a new debuglocus entry for a decl VAR.  */
+ debuglocus_p 
+ create_debuglocus_for_decl (tree var)
+ {
+   debuglocus_p ptr = create_debuglocus_entry();
+   ptr->decl = var;
+   return ptr;
+ }
+ 
+ 
+ /* Create a new debuglocus entry for decl VAR and source location LOCUS.  */
+ source_location
+ create_debuglocus_for_decl_and_locus (tree var, source_location locus)
+ {
+   debuglocus_p ptr = create_debuglocus_for_decl (var);
+   ptr->locus = locus;
+   return debuglocus_from_pointer (ptr);
+ }
+ 
+ 
+ /* Replace the locus in STMT with the debuglocus entry DLOCUS.  */
+ void
+ replace_gimple_locus_with_debuglocus (gimple stmt, debuglocus_p dlocus)
+ {
+   source_location locus = gimple_location (stmt);
+ 
+   /* Conflicting locus's shouldn't occurr.  */
+   gcc_assert (dlocus->locus == UNKNOWN_LOCATION || 
+ 	      locus == UNKNOWN_LOCATION  || 
+ 	      locus == dlocus->locus);
+ 
+   if (locus != dlocus->locus)
+     {
+       if (dlocus->locus == UNKNOWN_LOCATION)
+         dlocus->locus = locus;
+     }
+  
+   /* If stmt already has a debuglocus, then merge this one.  Typically this
+      happens when there are multiple results, as in an ASM */
+   if (is_debuglocus (locus))
+     {
+       debuglocus_p curr = get_debuglocus (locus);
+       merge_debuglocus (curr, dlocus);
+     } 
+   else
+     gimple_set_location (stmt, debuglocus_from_pointer (dlocus));
+ }
+ 
+ 
+ /* Merge the debuglocus list FROM to TO.  */
+ void
+ merge_debuglocus (debuglocus_p to, debuglocus_p from)
+ {
+   source_location from_last_i, to_last_i, tmp;
+   debuglocus_p from_last_p, to_last_p;
+   debuglocus_table_t *tab = current_debuglocus_table ();
+ 
+   from_last_i = from->prev;
+   from_last_p = get_debuglocus_entry (tab, from_last_i);
+   to_last_i = to->prev;
+   to_last_p = get_debuglocus_entry (tab, to_last_i);
+   
+   /* Update the circular list next fields.  */
+   tmp = to_last_p->next;
+   to_last_p->next = from_last_p->next;
+   from_last_p->next = tmp;
+ 
+   /* Update the circular list prev fields.  */
+   tmp = to->prev;
+   to->prev= from->prev;
+   from->prev = tmp;
+ }
+ 
+ 
+ debuglocus_p
+ find_debuglocus (gimple stmt, tree decl, source_location locus)
+ {
+   source_location dlocus = gimple_location (stmt);
+   debuglocus_iterator iter;
+   debuglocus_p ptr;
+ 
+   if (!is_debuglocus (dlocus))
+     return NULL;
+   
+   /* Find a matching entry.  */
+   FOR_EACH_DEBUGLOCUS (dlocus, ptr, iter)
+     if (ptr->decl == decl && ptr->locus == locus)
+       break;
+ 
+   return ptr;
+ }
+ 
+ 
+ /* Examine the debuglocus list on STMT, looking for an entry for DECL with
+    location LOCUS.  If found, delink it from the list and return a pointer.
+    Otherwise return NULL.  */
+ debuglocus_p 
+ find_and_detach_debuglocus (gimple stmt, tree decl, source_location locus)
+ {
+   debuglocus_p ptr = find_debuglocus (stmt, decl, locus);
+ 
+   /* If an entry is found, remove it from the list and return it.  */
+   if (ptr)
+     {
+       int self = debuglocus_index_from_pointer (ptr);
+       debuglocus_p prev, next;
+       debuglocus_table_t * tab;
+ 
+       /* If this is the original debuglocus on the stmt, leave it since the
+          stmt is presumably still live and will need it.  */
+       if (gimple_location (stmt) == (DEBUGLOCUS_BIT | self))
+         return NULL;
+ 
+       /* Make sure this isnt the only object in the list.  */
+       gcc_assert (ptr->next != self || ptr->prev != self);
+       gcc_assert (ptr->next != ptr->prev);
+ 
+       /* Update the links for the list and the entry.  */
+       tab = current_debuglocus_table ();
+       prev = get_debuglocus_entry (tab, ptr->prev);
+       next = get_debuglocus_entry (tab, ptr->next);
+       prev->next = ptr->next;
+       next->prev = ptr->prev;
+       ptr->next = ptr->prev = self;
+     }
+ 
+   return ptr;
+ }
+ 
+ 
+ /* Examine the debuglocus list on STMT, looking for an entry for DECL with
+    location DLOCUS.  If found, delink it from the list and return a pointer.
+    Otherwise create a new debuglocus for the source location DLOCUS and
+    return it.  */
+ source_location
+ find_and_detach_or_create_debuglocus (gimple stmt, tree decl, 
+ 				      source_location dlocus)
+ {
+   debuglocus_p ptr = find_and_detach_debuglocus (stmt, decl, dlocus);
+   source_location locus = locus_from_debuglocus (dlocus);
+   if (!ptr)
+     {
+       ptr = create_debuglocus_for_decl (decl);
+       ptr->locus = locus;
+     }
+ 
+   gcc_assert (ptr != NULL);
+ 
+   return debuglocus_from_pointer (ptr);
+ }
+ 
+ 
+ /* Initialize iterator ITER over the list of debuglocus for LOCUS.  Return the
+    first pointer or NULL.  */
+ debuglocus_p
+ debuglocus_iter_start (debuglocus_iterator *iter, source_location locus)
+ {
+   if (!is_debuglocus (locus))
+     {
+       iter->start_dlocus = NULL;
+       iter->current_dlocus = NULL;
+       return NULL;
+     }
+   iter->start_dlocus = iter->current_dlocus = get_debuglocus (locus);
+   return iter->current_dlocus;
+ }
+ 
+ 
+ /* Move to the next debuglocus for ITER. Return the pointer or NULL.  */
+ debuglocus_p 
+ debuglocus_iter_next (debuglocus_iterator * iter)
+ {
+   debuglocus_p next;
+ 
+   next = get_debuglocus_entry (current_debuglocus_table (), 
+ 			       iter->current_dlocus->next);
+ 
+   /* If this matches the first one visited, the list is done.  */
+   if (next == iter->start_dlocus)
+     next = NULL;
+ 
+   iter->current_dlocus = next;
+   return next;
+ }
+ 
+ 
+ /* Initialize iterator ITER over the list of debuglocus for LOCUS.  Return the
+    first decl or NULL.  */
+ tree
+ debuglocus_var_iter_start (debuglocus_iterator *iter, source_location locus)
+ {
+   if (!is_debuglocus (locus))
+     {
+       iter->start_dlocus = NULL;
+       iter->current_dlocus = NULL;
+       return NULL;
+     }
+   iter->start_dlocus = iter->current_dlocus = get_debuglocus (locus);
+   return iter->current_dlocus->decl;
+ }
+ 
+ 
+ /* Move to the next debuglocus for ITER. Return the pointer or NULL.  */
+ tree
+ debuglocus_var_iter_next (debuglocus_iterator * iter)
+ {
+   debuglocus_p next;
+ 
+   next = get_debuglocus_entry (current_debuglocus_table (), 
+ 			       iter->current_dlocus->next);
+ 
+   /* If this matches the first one visited, the list is done.  */
+   if (next == iter->start_dlocus)
+     next = NULL;
+   iter->current_dlocus = next;
+ 
+   if (next)
+     return next->decl;
+   return NULL;
+ }
+ 
+ 
Index: debuglocus.h
===================================================================
*** debuglocus.h	(revision 145094)
--- debuglocus.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 23,36 ****
  
  /* No entry. Used for terminating lists and returning no matches.  */
  #define DEBUGLOCUS_NONE			0
- #define IS_DEBUGLOCUS_P(LOCUS) 		(((LOCUS) & DEBUGLOCUS_BIT) != 0)
- #define DEBUGLOCUS_INDEX(LOCUS) 	((LOCUS) & ~DEBUGLOCUS_BIT)
- #define GET_DEBUGLOCUS(I)		(get_debuglocus (I))
- #define GET_LOCUS_FROM_DEBUGLOCUS(DL)	(debuglocus_lookup_locus (DL))
  
  struct debuglocus_entry_d GTY((skip)) {
    tree decl;			/* debug decl  */
!   int order;			/* Linear ordering for emission sorting.  */
    source_location locus;	/* locus of statement.  */
    int prev;			/* prev link for multiple entries on a stmt.  */
    int next;			/* next link for multiple entries on a stmt.  */
--- 23,32 ----
  
  /* No entry. Used for terminating lists and returning no matches.  */
  #define DEBUGLOCUS_NONE			0
  
  struct debuglocus_entry_d GTY((skip)) {
    tree decl;			/* debug decl  */
!   int order;			/* Ordering for emission sorting.  */
    source_location locus;	/* locus of statement.  */
    int prev;			/* prev link for multiple entries on a stmt.  */
    int next;			/* next link for multiple entries on a stmt.  */
*************** DEF_VEC_ALLOC_P(debuglocus_p, heap);
*** 48,74 ****
     memory in use.  The table can never shrink in size.  */
  
  struct debuglocus_table_d GTY((skip)) {
!   int size;			  /* Current number of debuglocus entries.  */
    VEC(debuglocus_p, heap) *table;   /* list of Table segments.  */
  };
  
  typedef struct debuglocus_table_d debuglocus_table_t;
  
  
- typedef int debuglocus_index;
- 
  void create_debuglocus_table(void);
  void destroy_debuglocus_table(void);
  debuglocus_p create_debuglocus_entry (void);
! debuglocus_p get_debuglocus (debuglocus_index);
  source_location create_duplicate_debuglocus (source_location locus);
  
  
  /* Copy a locus, performing a deep copy if it is a debuglocus.  */
  static inline source_location 
  copy_debuglocus (source_location locus)
  {
!   if (!IS_DEBUGLOCUS_P (locus))
      return locus;
    else
      return create_duplicate_debuglocus (locus);
--- 44,124 ----
     memory in use.  The table can never shrink in size.  */
  
  struct debuglocus_table_d GTY((skip)) {
!   unsigned int size;		    /* Current number of debuglocus entries.  */
    VEC(debuglocus_p, heap) *table;   /* list of Table segments.  */
  };
  
  typedef struct debuglocus_table_d debuglocus_table_t;
  
  
  void create_debuglocus_table(void);
  void destroy_debuglocus_table(void);
  debuglocus_p create_debuglocus_entry (void);
! debuglocus_p get_debuglocus (source_location locus);
  source_location create_duplicate_debuglocus (source_location locus);
+ bool decl_needs_debuglocus_p (tree);
+ debuglocus_p create_debuglocus_for_decl (tree);
+ source_location create_debuglocus_for_decl_and_locus (tree, source_location);
+ void replace_gimple_locus_with_debuglocus (gimple, debuglocus_p);
+ void merge_debuglocus (debuglocus_p, debuglocus_p);
+ debuglocus_p find_debuglocus (gimple, tree, source_location);
+ debuglocus_p find_and_detach_debuglocus (gimple, tree, source_location);
+ source_location find_and_detach_or_create_debuglocus (gimple, tree, source_location);
+ 
+ /* Iterate over the different debuglocus's in a single list. No iterations are 
+    performed if ther locus is just a regular source location.  
+ 
+    usage:
+    source_location locus = gimple_location (stmt);
+    debuglocus_iterator iter;
+    debuglocus_p ptr;
+    FOR_EACH_DEBUGLOCUS (locus, ptr, iter)
+      dump_debuglocus_pointer (ptr);		
+    if (!ptr)
+      printf ("loop was exited early\n");
+      
+    ptr is guaranteed to be NULL if the loop is allowed to execute to the
+    end, otherwise it will have the value when the exits happens.  
+    
+    This is an 'unsafe' iteration, meaning the list cannot be modified on the
+    fly while traversing the list.  */
+ 
+ typedef struct {
+   debuglocus_p start_dlocus;
+   debuglocus_p current_dlocus;
+ } debuglocus_iterator;
+ 
+ debuglocus_p debuglocus_iter_start (debuglocus_iterator *, source_location);
+ debuglocus_p debuglocus_iter_next (debuglocus_iterator *);
+ 
+ #define FOR_EACH_DEBUGLOCUS(LOCUS, DLOCUS_P, ITER)		\
+   for (DLOCUS_P = debuglocus_iter_start (&(ITER), (LOCUS));	\
+        (ITER).current_dlocus != NULL;				\
+        DLOCUS_P = debuglocus_iter_next (&(ITER)))
+ 
+ tree debuglocus_var_iter_start (debuglocus_iterator *, source_location);
+ tree debuglocus_var_iter_next (debuglocus_iterator *);
+ 
+ /* Another iterator, onoly this just returns the DECL in each debuglocus.  */
+ #define FOR_EACH_DEBUGLOCUS_VAR(LOCUS, VAR, ITER)		\
+   for (VAR = debuglocus_var_iter_start (&(ITER), (LOCUS));	\
+        (ITER).current_dlocus != NULL;				\
+        VAR = debuglocus_var_iter_next (&(ITER)))
+ 
+ 
+ /* Return true if LOCUS is a debuglocus.  */
+ static inline bool
+ is_debuglocus (source_location locus)
+ {
+   return (locus & DEBUGLOCUS_BIT) != 0;
+ }
  
  
  /* Copy a locus, performing a deep copy if it is a debuglocus.  */
  static inline source_location 
  copy_debuglocus (source_location locus)
  {
!   if (!is_debuglocus (locus))
      return locus;
    else
      return create_duplicate_debuglocus (locus);
*************** copy_debuglocus (source_location locus)
*** 77,89 ****
  
  /* Return the source locus associated with a debuglocus.  */
  static inline source_location
! debuglocus_lookup_locus (source_location dlocus)
  {
!   debuglocus_p ptr;
! 
!   gcc_assert (IS_DEBUGLOCUS_P (dlocus));
!   ptr = get_debuglocus (DEBUGLOCUS_INDEX (dlocus));
!   return ptr->locus;
  }
- 
  #endif
--- 127,140 ----
  
  /* Return the source locus associated with a debuglocus.  */
  static inline source_location
! locus_from_debuglocus (source_location dlocus)
  {
!   if (is_debuglocus (dlocus))
!     {
!       debuglocus_p ptr = get_debuglocus (dlocus);
!       return ptr->locus;
!     }
!   else
!     return dlocus;
  }
  #endif
Index: tree-pretty-print.c
===================================================================
*** tree-pretty-print.c	(revision 145094)
--- tree-pretty-print.c	(working copy)
*************** dump_generic_node (pretty_printer *buffe
*** 457,463 ****
  	}
        pp_decimal_int (buffer, xloc.line);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	pp_character (buffer, '*');
        pp_string (buffer, "] ");
      }
  
--- 457,472 ----
  	}
        pp_decimal_int (buffer, xloc.line);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	{
! 	  tree decl;
! 	  debuglocus_iterator iter;
! 
! 	  FOR_EACH_DEBUGLOCUS_VAR (xloc.debuglocus, decl, iter)
! 	    {
! 	      pp_character (buffer, '*');
! 	      dump_generic_node (buffer, decl, 0, 0, false);
! 	    }
! 	}
        pp_string (buffer, "] ");
      }
  
Index: tree.c
===================================================================
*** tree.c	(revision 145094)
--- tree.c	(working copy)
*************** expand_location (source_location loc)
*** 3572,3581 ****
      {
        const struct line_map *map;
        /* Look through a debuglocus.  */
!       if (IS_DEBUGLOCUS_P (loc))
          {
! 	  loc = GET_LOCUS_FROM_DEBUGLOCUS (loc);
! 	  xloc.debuglocus = DEBUGLOCUS_INDEX (loc);
  	}
        else
          xloc.debuglocus = DEBUGLOCUS_NONE;
--- 3572,3581 ----
      {
        const struct line_map *map;
        /* Look through a debuglocus.  */
!       if (is_debuglocus (loc))
          {
! 	  xloc.debuglocus = loc;
! 	  loc = locus_from_debuglocus (loc);
  	}
        else
          xloc.debuglocus = DEBUGLOCUS_NONE;
Index: tree-phinodes.c
===================================================================
*** tree-phinodes.c	(revision 145094)
--- tree-phinodes.c	(working copy)
*************** make_phi_node (tree var, int len)
*** 224,232 ****
    phi->gimple_phi.nargs = len;
    phi->gimple_phi.capacity = capacity;
    if (TREE_CODE (var) == SSA_NAME)
!     gimple_phi_set_result (phi, var);
    else
!     gimple_phi_set_result (phi, make_ssa_name (var, phi));
  
    for (i = 0; i < capacity; i++)
      {
--- 224,238 ----
    phi->gimple_phi.nargs = len;
    phi->gimple_phi.capacity = capacity;
    if (TREE_CODE (var) == SSA_NAME)
!     {
!       gimple_phi_set_result (phi, var);
!       phi->gimple_phi.original_decl = SSA_NAME_VAR (var); 
!     }
    else
!     {
!       gimple_phi_set_result (phi, make_ssa_name (var, phi));
!       phi->gimple_phi.original_decl = var; 
!     }
  
    for (i = 0; i < capacity; i++)
      {
Index: gimple-pretty-print.c
===================================================================
*** gimple-pretty-print.c	(revision 145094)
--- gimple-pretty-print.c	(working copy)
*************** dump_gimple_phi (pretty_printer *buffer,
*** 1196,1202 ****
  	    }
  	  pp_decimal_int (buffer, xloc.line);
  	  if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	    pp_character (buffer, '*');
  	  pp_string (buffer, "] ");
  	}
        if (i < gimple_phi_num_args (phi) - 1)
--- 1196,1211 ----
  	    }
  	  pp_decimal_int (buffer, xloc.line);
  	  if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	    {
! 	      tree decl;
! 	      debuglocus_iterator iter;
! 
! 	      FOR_EACH_DEBUGLOCUS_VAR (xloc.debuglocus, decl, iter)
! 	        {
! 		  pp_character (buffer, '*');
! 		  dump_generic_node (buffer, decl, 0, 0, false);
! 	        }
! 	    }
  	  pp_string (buffer, "] ");
  	}
        if (i < gimple_phi_num_args (phi) - 1)
*************** dump_gimple_stmt (pretty_printer *buffer
*** 1499,1505 ****
  	}
        pp_decimal_int (buffer, xloc.line);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	pp_character (buffer, '*');
        pp_string (buffer, "] ");
      }
  
--- 1508,1523 ----
  	}
        pp_decimal_int (buffer, xloc.line);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	{
! 	  tree decl;
! 	  debuglocus_iterator iter;
! 
! 	  FOR_EACH_DEBUGLOCUS_VAR (xloc.debuglocus, decl, iter)
! 	    {
! 	      pp_character (buffer, '*');
! 	      dump_generic_node (buffer, decl, 0, 0, false);
! 	    }
! 	}
        pp_string (buffer, "] ");
      }
  
*************** dump_implicit_edges (pretty_printer *buf
*** 1850,1856 ****
  	    }
  	  pp_decimal_int (buffer, goto_xloc.line);
  	  if (goto_xloc.debuglocus != DEBUGLOCUS_NONE)
! 	    pp_character (buffer, '*');
  	  pp_string (buffer, "] ");
  	}
  
--- 1868,1883 ----
  	    }
  	  pp_decimal_int (buffer, goto_xloc.line);
  	  if (goto_xloc.debuglocus != DEBUGLOCUS_NONE)
! 	    {
! 	      tree decl;
! 	      debuglocus_iterator iter;
! 
! 	      FOR_EACH_DEBUGLOCUS_VAR (goto_xloc.debuglocus, decl, iter)
! 		{
! 		  pp_character (buffer, '*');
! 		  dump_generic_node (buffer, decl, 0, 0, false);
! 		}
! 	    }
  	  pp_string (buffer, "] ");
  	}
  
Index: function.h
===================================================================
*** function.h	(revision 145094)
--- function.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 25,31 ****
  #include "tree.h"
  #include "hashtab.h"
  #include "varray.h"
- #include "debuglocus.h"
  
  /* Stack of pending (incomplete) sequences saved by `start_sequence'.
     Each element describes one pending sequence.
--- 25,30 ----
*************** struct function GTY(())
*** 528,536 ****
    /* Line number of the end of the function.  */
    location_t function_end_locus;
  
-   /* Debuglocus table.  */
-   struct debuglocus_table_d * GTY ((skip)) debuglocus_table;
- 
    /* Properties used by the pass manager.  */
    unsigned int curr_properties;
    unsigned int last_verified;
--- 527,532 ----
Index: print-rtl.c
===================================================================
*** print-rtl.c	(revision 145094)
--- print-rtl.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 40,45 ****
--- 40,46 ----
  #include "flags.h"
  #include "hard-reg-set.h"
  #include "basic-block.h"
+ #include "debuglocus.h"
  #endif
  
  static FILE *outfile;
*************** print_rtx (const_rtx in_rtx)
*** 395,401 ****
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
  	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
! 	      fprintf(outfile, " %s:%i%s", insn_file (in_rtx), insn_line (in_rtx), (insn_debuglocus (in_rtx) ? "*" : ""));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
--- 396,414 ----
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
  	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
! 	      {
! 		tree decl;
! 		debuglocus_iterator iter;
! 		location_t locus = locator_location (INSN_LOCATOR (in_rtx));
! 
! 		fprintf (outfile, " %s:%i", insn_file (in_rtx), 
! 					    insn_line (in_rtx));
! 		FOR_EACH_DEBUGLOCUS_VAR (locus, decl, iter)
! 		  {
! 		    fprintf (outfile, "*");
! 		    print_decl_name (outfile, decl);
! 		  }
! 	      }
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
Index: tree-ssa-phiopt.c
===================================================================
*** tree-ssa-phiopt.c	(revision 145094)
--- tree-ssa-phiopt.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 36,41 ****
--- 36,42 ----
  #include "langhooks.h"
  #include "pointer-set.h"
  #include "domwalk.h"
+ #include "debuglocus.h"
  
  static unsigned int tree_ssa_phiopt (void);
  static unsigned int tree_ssa_phiopt_worker (bool);
*************** conditional_replacement (basic_block con
*** 524,534 ****
        gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
        new_var = new_var2;
  
!       /* Set the locus to the first argument, unless it 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);
      }
  
--- 525,550 ----
        gsi_insert_before (&gsi, new_stmt, GSI_SAME_STMT);
        new_var = new_var2;
  
!       /* Attach the debuglocus information for whichever argument has a 
! 	 debuglocus.  If both have a debuglocus, merge them.  */
! 
        locus_0 = gimple_phi_arg_location (phi, 0);
        locus_1 = gimple_phi_arg_location (phi, 1);
! 
!       if (is_debuglocus (locus_1))
! 	{
! 	 if (is_debuglocus (locus_0))
! 	   merge_debuglocus (get_debuglocus (locus_0), 
! 			     get_debuglocus (locus_1));
! 	 else
! 	   /* Only locus_1 is a debuglocus, so use it.  */
! 	   locus_0 = locus_1;
!        }
!       else
!         /* Locus_1 isn't a debuglocus, so only use it if locus_0 is unknown.  */
! 	if (locus_0 == UNKNOWN_LOCATION)
! 	  locus_0 = locus_1;
! 
        gimple_set_location (new_stmt, locus_0);
      }
  
Index: print-tree.c
===================================================================
*** print-tree.c	(revision 145094)
--- print-tree.c	(working copy)
*************** print_node (FILE *file, const char *pref
*** 457,463 ****
        fprintf (file, " file %s line %d col %d", xloc.file, xloc.line,
  	       xloc.column);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
!         fprintf (file, "* ");
  
        if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
  	{	  
--- 457,472 ----
        fprintf (file, " file %s line %d col %d", xloc.file, xloc.line,
  	       xloc.column);
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
! 	{
! 	  tree decl;
! 	  debuglocus_iterator iter;
! 
! 	  FOR_EACH_DEBUGLOCUS_VAR (xloc.debuglocus, decl, iter)
! 	    {
! 	      fprintf (file , "*");
! 	      print_generic_expr (file, decl, 0);
! 	    }
! 	}
  
        if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
  	{	  
Index: cfglayout.c
===================================================================
*** cfglayout.c	(revision 145094)
--- cfglayout.c	(working copy)
*************** insn_debuglocus (const_rtx insn)
*** 570,576 ****
        expanded_location xloc;
        xloc = expand_location (locator_location (loc));
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
!         ptr = GET_DEBUGLOCUS (xloc.debuglocus);
      }
    return ptr;
  }
--- 570,576 ----
        expanded_location xloc;
        xloc = expand_location (locator_location (loc));
        if (xloc.debuglocus != DEBUGLOCUS_NONE)
!         ptr = get_debuglocus (xloc.debuglocus);
      }
    return ptr;
  }
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 145094)
--- tree-inline.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 53,58 ****
--- 53,59 ----
  #include "tree-pass.h"
  #include "target.h"
  #include "integrate.h"
+ #include "debuglocus.h"
  
  /* I'm not real happy about this, but we need to handle gimple and
     non-gimple trees.  */
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1780,1785 ****
--- 1781,1788 ----
  	  for (x = 0; x < gimple_phi_num_args (new_phi); x++)
  	    {
  	      source_location locus = gimple_phi_arg_location (phi, x);
+ 	      /* Perform a deep copy of any debuglocus's.  */
+ 	      locus = copy_debuglocus (locus);
  	      gimple_phi_arg_set_location (new_phi, x, locus);
  	    }
  	  
*************** initialize_inlined_parameters (copy_body
*** 2194,2201 ****
    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);
--- 2197,2207 ----
    tree p;
    tree vars = NULL_TREE;
    tree static_chain = gimple_call_chain (stmt);
!   source_location locus;
! 
!   /* For now, only copy the actual source location of the param.  This will be
!      used as the locus that the parameter debuglocus's will be attached to.  */
!   locus = gimple_source_location (stmt);
  
    /* Figure out what the parameters are.  */
    parms = DECL_ARGUMENTS (fn);
Index: tree-outof-ssa.c
===================================================================
*** tree-outof-ssa.c	(revision 145094)
--- tree-outof-ssa.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 34,42 ****
  #include "tree-pass.h"
  #include "toplev.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
--- 34,43 ----
  #include "tree-pass.h"
  #include "toplev.h"
  
+ typedef struct phi_arg_d *phi_arg_ptr;
  
! DEF_VEC_P(phi_arg_ptr);
! DEF_VEC_ALLOC_P(phi_arg_ptr,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
*************** typedef struct _elim_graph {
*** 69,76 ****
    /*  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;
--- 70,77 ----
    /*  The predecessor and successor edge list.  */
    VEC(int,heap) *edge_list;
  
!   /* PHI argument on each edge */
!   VEC(phi_arg_ptr,heap) *edge_arg;
  
    /* Visited vector.  */
    sbitmap visited;
*************** typedef struct _elim_graph {
*** 87,94 ****
    /* List of constant copies to emit.  These are pushed on in pairs.  */
    VEC(tree,heap) *const_copies;
  
!   /* Source locations for any constant copies.  */
!   VEC(source_location,heap) *copy_locus;
  } *elim_graph;
  
  
--- 88,95 ----
    /* List of constant copies to emit.  These are pushed on in pairs.  */
    VEC(tree,heap) *const_copies;
  
!   /* PHI arguement for any constant copies.  */
!   VEC(phi_arg_ptr,heap) *copy_arg;
  } *elim_graph;
  
  
*************** create_temp (tree t)
*** 145,159 ****
  
  
  /* This helper function fill insert a copy from a constant or variable SRC to 
!    variable DEST on edge E.  */
  
  static void
! insert_copy_on_edge (edge e, tree dest, tree src, source_location locus)
  {
    gimple copy;
  
    copy = gimple_build_assign (dest, src);
    set_is_used (dest);
    gimple_set_location (copy, locus);
  
    if (TREE_CODE (src) == ADDR_EXPR)
--- 146,172 ----
  
  
  /* This helper function fill insert a copy from a constant or variable SRC to 
!    variable DEST on edge E.  PHI_ARG provides a source argument for locus
!    information.  NULL means there is no locus info.  */
  
  static void
! insert_copy_on_edge (edge e, tree dest, tree src, phi_arg_ptr phi_arg)
  {
    gimple copy;
+   source_location locus = UNKNOWN_LOCATION;
  
    copy = gimple_build_assign (dest, src);
    set_is_used (dest);
+   if (phi_arg)
+     {
+       use_operand_p use_p = &(phi_arg->imm_use);
+       tree decl = gimple_phi_original_decl (USE_STMT (use_p));
+ 
+       locus = phi_arg->locus;
+       /* Create a debuglocus if one is needed and there isn't one.  */
+       if (!is_debuglocus (locus) && decl_needs_debuglocus_p (decl))
+ 	locus = create_debuglocus_for_decl_and_locus (decl, locus);
+     }
    gimple_set_location (copy, locus);
  
    if (TREE_CODE (src) == ADDR_EXPR)
*************** new_elim_graph (int size)
*** 185,193 ****
  
    g->nodes = VEC_alloc (tree, heap, 30);
    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);
--- 198,206 ----
  
    g->nodes = VEC_alloc (tree, heap, 30);
    g->const_copies = VEC_alloc (tree, heap, 20);
!   g->copy_arg = VEC_alloc (phi_arg_ptr, heap, 10);
    g->edge_list = VEC_alloc (int, heap, 20);
!   g->edge_arg = VEC_alloc (phi_arg_ptr, heap, 10);
    g->stack = VEC_alloc (int, heap, 30);
    
    g->visited = sbitmap_alloc (size);
*************** clear_elim_graph (elim_graph g)
*** 203,209 ****
  {
    VEC_truncate (tree, g->nodes, 0);
    VEC_truncate (int, g->edge_list, 0);
!   VEC_truncate (source_location, g->edge_locus, 0);
  }
  
  
--- 216,222 ----
  {
    VEC_truncate (tree, g->nodes, 0);
    VEC_truncate (int, g->edge_list, 0);
!   VEC_truncate (phi_arg_ptr, g->edge_arg, 0);
  }
  
  
*************** delete_elim_graph (elim_graph g)
*** 217,224 ****
    VEC_free (int, heap, g->edge_list);
    VEC_free (tree, heap, g->const_copies);
    VEC_free (tree, heap, g->nodes);
!   VEC_free (source_location, heap, g->copy_locus);
!   VEC_free (source_location, heap, g->edge_locus);
    free (g);
  }
  
--- 230,237 ----
    VEC_free (int, heap, g->edge_list);
    VEC_free (tree, heap, g->const_copies);
    VEC_free (tree, heap, g->nodes);
!   VEC_free (phi_arg_ptr, heap, g->copy_arg);
!   VEC_free (phi_arg_ptr, heap, g->edge_arg);
    free (g);
  }
  
*************** elim_graph_add_node (elim_graph g, tree 
*** 250,260 ****
  /* 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);
  }
  
  
--- 263,273 ----
  /* Add the edge PRED->SUCC to graph G.  */
  
  static inline void
! elim_graph_add_edge (elim_graph g, int pred, int succ, phi_arg_ptr arg)
  {
    VEC_safe_push (int, heap, g->edge_list, pred);
    VEC_safe_push (int, heap, g->edge_list, succ);
!   VEC_safe_push (phi_arg_ptr, heap, g->edge_arg, arg);
  }
  
  
*************** elim_graph_add_edge (elim_graph g, int p
*** 262,268 ****
     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;
--- 275,281 ----
     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, phi_arg_ptr *arg)
  {
    int y;
    unsigned x;
*************** elim_graph_remove_succ_edge (elim_graph 
*** 272,282 ****
          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;
  }
  
--- 285,295 ----
          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);
! 	*arg= VEC_index (phi_arg_ptr, g->edge_arg, x / 2);
! 	VEC_replace (phi_arg_ptr, g->edge_arg, x / 2, NULL);
  	return y;
        }
!   *arg = NULL;
    return -1;
  }
  
*************** elim_graph_remove_succ_edge (elim_graph 
*** 285,291 ****
     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_;								\
--- 298,304 ----
     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, ARG, CODE)		\
  do {									\
    unsigned x_;								\
    int y_;								\
*************** do {									\
*** 295,301 ****
        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)
--- 308,314 ----
        if (y_ != (NODE))							\
          continue;							\
        (VAR) = VEC_index (int, (GRAPH)->edge_list, x_ + 1);		\
!       (ARG) = VEC_index (phi_arg_ptr, (GRAPH)->edge_arg, x_ / 2); \
        CODE;								\
      }									\
  } while (0)
*************** do {									\
*** 305,311 ****
     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_;								\
--- 318,324 ----
     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, ARG, CODE)		\
  do {									\
    unsigned x_;								\
    int y_;								\
*************** do {									\
*** 315,321 ****
        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)
--- 328,334 ----
        if (y_ != (NODE))							\
          continue;							\
        (VAR) = VEC_index (int, (GRAPH)->edge_list, x_);			\
!       (ARG) = VEC_index (phi_arg_ptr, (GRAPH)->edge_arg, x_ / 2); \
        CODE;								\
      }									\
  } while (0)
*************** eliminate_build (elim_graph g, basic_blo
*** 345,351 ****
    for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple phi = gsi_stmt (gsi);
!       source_location locus;
  
        T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi));
        
--- 358,364 ----
    for (gsi = gsi_start_phis (B); !gsi_end_p (gsi); gsi_next (&gsi))
      {
        gimple phi = gsi_stmt (gsi);
!       phi_arg_ptr arg;
  
        T0 = var_to_partition_to_var (g->map, gimple_phi_result (phi));
        
*************** eliminate_build (elim_graph g, basic_blo
*** 354,360 ****
  	continue;
  
        Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
!       locus = gimple_phi_arg_location (phi, g->e->dest_idx);
  
        /* 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
--- 367,373 ----
  	continue;
  
        Ti = PHI_ARG_DEF (phi, g->e->dest_idx);
!       arg = gimple_phi_arg (phi, g->e->dest_idx);
  
        /* 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, basic_blo
*** 367,373 ****
  	     on this edge.  */
  	  VEC_safe_push (tree, heap, g->const_copies, T0);
  	  VEC_safe_push (tree, heap, g->const_copies, Ti);
! 	  VEC_safe_push (source_location, heap, g->copy_locus, locus);
  	}
        else
          {
--- 380,386 ----
  	     on this edge.  */
  	  VEC_safe_push (tree, heap, g->const_copies, T0);
  	  VEC_safe_push (tree, heap, g->const_copies, Ti);
! 	  VEC_safe_push (phi_arg_ptr, heap, g->copy_arg, arg);
  	}
        else
          {
*************** eliminate_build (elim_graph g, basic_blo
*** 378,384 ****
  	      eliminate_name (g, Ti);
  	      p0 = var_to_partition (g->map, T0);
  	      pi = var_to_partition (g->map, Ti);
! 	      elim_graph_add_edge (g, p0, pi, locus);
  	    }
  	}
      }
--- 391,397 ----
  	      eliminate_name (g, Ti);
  	      p0 = var_to_partition (g->map, T0);
  	      pi = var_to_partition (g->map, Ti);
! 	      elim_graph_add_edge (g, p0, pi, arg);
  	    }
  	}
      }
*************** static void 
*** 391,400 ****
  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);
--- 404,413 ----
  elim_forward (elim_graph g, int T)
  {
    int S;
!   phi_arg_ptr arg;
  
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_SUCC (g, T, S, arg,
      {
        if (!TEST_BIT (g->visited, S))
          elim_forward (g, S);
*************** static int
*** 409,417 ****
  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;
--- 422,430 ----
  elim_unvisited_predecessor (elim_graph g, int T)
  {
    int P;
!   phi_arg_ptr arg;
  
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, arg,
      {
        if (!TEST_BIT (g->visited, P))
          return 1;
*************** static void
*** 425,434 ****
  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))
          {
--- 438,447 ----
  elim_backward (elim_graph g, int T)
  {
    int P;
!   phi_arg_ptr arg;
  
    SET_BIT (g->visited, T);
!   FOR_EACH_ELIM_GRAPH_PRED (g, T, P, arg,
      {
        if (!TEST_BIT (g->visited, P))
          {
*************** elim_backward (elim_graph g, int T)
*** 436,442 ****
  	  insert_copy_on_edge (g->e, 
  			       partition_to_var (g->map, P), 
  			       partition_to_var (g->map, T),
! 			       locus);
  	}
      });
  }
--- 449,455 ----
  	  insert_copy_on_edge (g->e, 
  			       partition_to_var (g->map, P), 
  			       partition_to_var (g->map, T),
! 			       arg);
  	}
      });
  }
*************** elim_create (elim_graph g, int T)
*** 449,455 ****
  {
    tree U;
    int P, S;
!   source_location locus;
  
    if (elim_unvisited_predecessor (g, T))
      {
--- 462,468 ----
  {
    tree U;
    int P, S;
!   phi_arg_ptr arg;
  
    if (elim_unvisited_predecessor (g, T))
      {
*************** elim_create (elim_graph g, int T)
*** 457,464 ****
        insert_copy_on_edge (g->e, 
  			   U, 
  			   partition_to_var (g->map, T), 
! 			   UNKNOWN_LOCATION);
!       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, locus,
  	{
  	  if (!TEST_BIT (g->visited, P))
  	    {
--- 470,477 ----
        insert_copy_on_edge (g->e, 
  			   U, 
  			   partition_to_var (g->map, T), 
! 			   NULL);
!       FOR_EACH_ELIM_GRAPH_PRED (g, T, P, arg,
  	{
  	  if (!TEST_BIT (g->visited, P))
  	    {
*************** elim_create (elim_graph g, int T)
*** 466,485 ****
  	      insert_copy_on_edge (g->e, 
  				   partition_to_var (g->map, P), 
  				   U,
! 				   locus);
  	    }
  	});
      }
    else
      {
!       S = elim_graph_remove_succ_edge (g, T, &locus);
        if (S != -1)
  	{
  	  SET_BIT (g->visited, T);
  	  insert_copy_on_edge (g->e, 
  			       partition_to_var (g->map, T), 
  			       partition_to_var (g->map, S),
! 			       locus);
  	}
      }
    
--- 479,498 ----
  	      insert_copy_on_edge (g->e, 
  				   partition_to_var (g->map, P), 
  				   U,
! 				   arg);
  	    }
  	});
      }
    else
      {
!       S = elim_graph_remove_succ_edge (g, T, &arg);
        if (S != -1)
  	{
  	  SET_BIT (g->visited, T);
  	  insert_copy_on_edge (g->e, 
  			       partition_to_var (g->map, T), 
  			       partition_to_var (g->map, S),
! 			       arg);
  	}
      }
    
*************** eliminate_phi (edge e, elim_graph g)
*** 495,501 ****
    basic_block B = e->dest;
  
    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)
--- 508,514 ----
    basic_block B = e->dest;
  
    gcc_assert (VEC_length (tree, g->const_copies) == 0);
!   gcc_assert (VEC_length (phi_arg_ptr, g->copy_arg) == 0);
  
    /* Abnormal edges already have everything coalesced.  */
    if (e->flags & EDGE_ABNORMAL)
*************** eliminate_phi (edge e, elim_graph g)
*** 532,543 ****
    while (VEC_length (tree, g->const_copies) > 0)
      {
        tree src, dest;
!       source_location locus;
  
        src = VEC_pop (tree, g->const_copies);
        dest = VEC_pop (tree, g->const_copies);
!       locus = VEC_pop (source_location, g->copy_locus);
!       insert_copy_on_edge (e, dest, src, locus);
      }
  }
  
--- 545,556 ----
    while (VEC_length (tree, g->const_copies) > 0)
      {
        tree src, dest;
!       phi_arg_ptr arg;
  
        src = VEC_pop (tree, g->const_copies);
        dest = VEC_pop (tree, g->const_copies);
!       arg = VEC_pop (phi_arg_ptr, g->copy_arg);
!       insert_copy_on_edge (e, dest, src, arg);
      }
  }
  
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 145094)
--- Makefile.in	(working copy)
*************** BASIC_BLOCK_H = basic-block.h $(BITMAP_H
*** 812,818 ****
            hard-reg-set.h $(PREDICT_H) vec.h $(FUNCTION_H) \
            cfghooks.h $(OBSTACK_H)
  GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \
! 	$(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h
  GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
  COVERAGE_H = coverage.h $(GCOV_IO_H)
  DEMANGLE_H = $(srcdir)/../include/demangle.h
--- 812,819 ----
            hard-reg-set.h $(PREDICT_H) vec.h $(FUNCTION_H) \
            cfghooks.h $(OBSTACK_H)
  GIMPLE_H = gimple.h gimple.def gsstruct.def pointer-set.h vec.h \
! 	$(GGC_H) $(BASIC_BLOCK_H) $(TM_H) $(TARGET_H) tree-ssa-operands.h \
! 	debuglocus.h
  GCOV_IO_H = gcov-io.h gcov-iov.h auto-host.h
  COVERAGE_H = coverage.h $(GCOV_IO_H)
  DEMANGLE_H = $(srcdir)/../include/demangle.h
*************** RECOG_H = recog.h
*** 820,826 ****
  ALIAS_H = alias.h coretypes.h
  EMIT_RTL_H = emit-rtl.h
  FLAGS_H = flags.h options.h
! FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) varray.h debuglocus.h
  EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
  OPTABS_H = optabs.h insn-codes.h
  REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H)
--- 821,827 ----
  ALIAS_H = alias.h coretypes.h
  EMIT_RTL_H = emit-rtl.h
  FLAGS_H = flags.h options.h
! FUNCTION_H = function.h $(TREE_H) $(HASHTAB_H) varray.h
  EXPR_H = expr.h insn-config.h $(FUNCTION_H) $(RTL_H) $(FLAGS_H) $(TREE_H) $(MACHMODE_H) $(EMIT_RTL_H)
  OPTABS_H = optabs.h insn-codes.h
  REGS_H = regs.h varray.h $(MACHMODE_H) $(OBSTACK_H) $(BASIC_BLOCK_H) $(FUNCTION_H)
*************** tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) 
*** 2059,2065 ****
     all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
     $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
     $(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
!    $(OBSTACK_H) pointer-set.h fixed-value.h
  tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \
     tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
--- 2060,2066 ----
     all-tree.def $(FLAGS_H) $(FUNCTION_H) $(PARAMS_H) \
     $(TOPLEV_H) $(GGC_H) $(HASHTAB_H) $(TARGET_H) output.h $(TM_P_H) langhooks.h \
     $(REAL_H) gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
!    $(OBSTACK_H) pointer-set.h fixed-value.h debuglocus.h
  tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
     $(TREE_H) langhooks.h $(TOPLEV_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) \
     tree-iterator.h tree-pass.h $(DIAGNOSTIC_H) $(REAL_H) fixed-value.h
*************** tree-into-ssa.o : tree-into-ssa.c $(TREE
*** 2094,2100 ****
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     langhooks.h domwalk.h tree-pass.h $(GGC_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
     $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h
  tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_SSA_LIVE_H) $(BITMAP_H)
--- 2095,2101 ----
     $(FUNCTION_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     langhooks.h domwalk.h tree-pass.h $(GGC_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
     $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) hard-reg-set.h $(HASHTAB_H) \
!    $(GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) vecprim.h debuglocus.h
  tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
     $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     $(TREE_SSA_LIVE_H) $(BITMAP_H)
*************** tree-ssa-ifcombine.o : tree-ssa-ifcombin
*** 2122,2128 ****
  tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
     $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \
!    $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h
  tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(EXPR_H) \
     $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \
--- 2123,2129 ----
  tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(GGC_H) $(TREE_H) $(RTL_H) $(TM_P_H) $(BASIC_BLOCK_H) \
     $(TREE_FLOW_H) tree-pass.h $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \
!    $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h debuglocus.h
  tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(RTL_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(EXPR_H) \
     $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) tree-pass.h \
*************** tree-stdarg.o: tree-stdarg.c $(CONFIG_H)
*** 2400,2406 ****
     tree-stdarg.h $(TARGET_H) langhooks.h
  tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(TOPLEV_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
!    tree-ssa-propagate.h debuglocus.h
  gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
     $(GGC_H) $(GIMPLE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) gt-gimple.h \
     $(TREE_FLOW_H) value-prof.h $(FLAGS_H)
--- 2401,2407 ----
     tree-stdarg.h $(TARGET_H) langhooks.h
  tree-object-size.o: tree-object-size.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
     $(TM_H) $(TREE_H) $(TOPLEV_H) $(DIAGNOSTIC_H) $(TREE_FLOW_H) tree-pass.h \
!    tree-ssa-propagate.h 
  gimple.o : gimple.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
     $(GGC_H) $(GIMPLE_H) $(GIMPLE_H) $(DIAGNOSTIC_H) gt-gimple.h \
     $(TREE_FLOW_H) value-prof.h $(FLAGS_H)
*************** rtl.o : rtl.c $(CONFIG_H) $(SYSTEM_H) co
*** 2476,2482 ****
  
  print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
      $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
!     $(BCONFIG_H) $(REAL_H)
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
--- 2477,2483 ----
  
  print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
      $(RTL_H) $(TREE_H) hard-reg-set.h $(BASIC_BLOCK_H) $(FLAGS_H) \
!     $(BCONFIG_H) $(REAL_H) debuglocus.h
  rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TOPLEV_H) \
     $(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
     $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H) \
Index: gimple.h
===================================================================
*** gimple.h	(revision 145094)
--- gimple.h	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 29,34 ****
--- 29,35 ----
  #include "hard-reg-set.h"
  #include "basic-block.h"
  #include "tree-ssa-operands.h"
+ #include "debuglocus.h"
  
  DEF_VEC_P(gimple);
  DEF_VEC_ALLOC_P(gimple,heap);
*************** struct gimple_statement_phi GTY(())
*** 476,481 ****
--- 477,486 ----
    tree result;
  
    /* [ WORD 7 ]  */
+   /* Original decl for creating debuglocus info during out-of-ssa.  */
+   tree original_decl;
+ 
+   /* [ WORD 8 ]  */
    struct phi_arg_d GTY ((length ("%h.nargs"))) args[1];
  };
  
*************** gimple_location (const_gimple g)
*** 1097,1102 ****
--- 1102,1119 ----
    return g->gsbase.location;
  }
  
+ static inline location_t
+ gimple_copy_location (const_gimple g)
+ {
+   return copy_debuglocus (g->gsbase.location);
+ }
+ 
+ static inline location_t
+ gimple_source_location (const_gimple g)
+ {
+   return locus_from_debuglocus (g->gsbase.location);
+ }
+ 
  /* Return pointer to location information for statement G.  */
  
  static inline const location_t *
*************** gimple_phi_set_result (gimple gs, tree r
*** 3096,3101 ****
--- 3113,3125 ----
    gs->gimple_phi.result = result;
  }
  
+ /* Return the original debug decl for GIMPLE_PHI GS.  */
+ static inline tree
+ gimple_phi_original_decl (gimple gs)
+ {
+   GIMPLE_CHECK (gs, GIMPLE_PHI);
+   return gs->gimple_phi.original_decl;
+ }
  
  /* Return the PHI argument corresponding to incoming edge INDEX for
     GIMPLE_PHI GS.  */

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