This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[debuglocus] More Infrastructure.
- From: Andrew MacLeod <amacleod at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 26 Mar 2009 17:48:34 -0400
- Subject: [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. */