[patch] PR 41700: propagate vtable slot index across insn split
Cary Coutant
ccoutant@google.com
Mon Oct 26 21:18:00 GMT 2009
The attached patch is a fix for PR 41700, where
g++.dg/debug/dwarf2/icf.C is failing on PA-RISC and Itanium. The
problem is that the vtable slot index for the virtual call is
associated with the UID of a call insn during expandcfg, but on
certain targets, that call insn is later split, causing a new UID to
be generated. This patch adds a new debug hook to copy the vtable slot
index from the old CALL_INSN to the new one, and modifies try_split()
to call the hook.
Bootstrapped and tested on x86_64-linux. Also verified to fix the
failure (by Steve and Dave) on PA-32 and Itanium; waiting to hear the
results of PA-64 testing.
OK for trunk (assuming PA-64 succeeds)?
-cary
gcc/ChangeLog:
PR debug/41700
* dwarf2out.c (dwarf2_debug_hooks): Add entries for new hook (two
locations in the source).
(store_vcall_insn): New function.
(lookup_vcall_insn): New function.
(dwarf2out_virtual_call_token): Use store_vcall_insn.
(dwarf2out_copy_virtual_call_token): New function.
(dwarf2out_virtual_call): Use lookup_vcall_insn.
* emit-rtl.c (try_split): Call copy_virtual_call_token debug hook.
* debug.h (struct gcc_debug_hooks): Add copy_virtual_call_token hook.
* debug.c (do_nothing_debug_hooks): Add dummy entry for new hook.
(debug_nothing_sint_sint): New dummy function.
* dbxout.c (dbx_debug_hooks): Add dummy entry for new hooks.
(xcoff_debug_hooks): Likewise.
* sdbout.c (sdb_debug_hooks): Likewise.
* vmsdbgout.c (vmsdbg_debug_hooks): Likewise.
* doc/invoke.texi (-fenable-icf-debug): New option.
-------------- next part --------------
Index: vmsdbgout.c
===================================================================
--- vmsdbgout.c (revision 153570)
+++ vmsdbgout.c (working copy)
@@ -217,6 +217,7 @@ const struct gcc_debug_hooks vmsdbg_debu
debug_nothing_void, /* switch_text_section */
debug_nothing_tree, /* direct_call */
debug_nothing_tree_int, /* virtual_call_token */
+ debug_nothing_sint_sint, /* copy_virtual_call_token */
debug_nothing_uid, /* virtual_call */
debug_nothing_tree_tree, /* set_name */
0 /* start_end_main_source_file */
Index: debug.c
===================================================================
--- debug.c (revision 153570)
+++ debug.c (working copy)
@@ -53,6 +53,7 @@ const struct gcc_debug_hooks do_nothing_
debug_nothing_void, /* switch_text_section */
debug_nothing_tree, /* direct_call */
debug_nothing_tree_int, /* virtual_call_token */
+ debug_nothing_sint_sint, /* copy_virtual_call_token */
debug_nothing_uid, /* virtual_call */
debug_nothing_tree_tree, /* set_name */
0 /* start_end_main_source_file */
@@ -127,6 +128,12 @@ debug_nothing_int_int (unsigned int line
}
void
+debug_nothing_sint_sint (int ouid ATTRIBUTE_UNUSED,
+ int nuid ATTRIBUTE_UNUSED)
+{
+}
+
+void
debug_nothing_tree_int (tree decl ATTRIBUTE_UNUSED,
int local ATTRIBUTE_UNUSED)
{
Index: debug.h
===================================================================
--- debug.h (revision 153570)
+++ debug.h (working copy)
@@ -143,6 +143,12 @@ struct gcc_debug_hooks
point. */
void (* virtual_call_token) (tree addr, int insn_uid);
+ /* Copies the OBJ_TYPE_REF_TOKEN for a virtual call from OLD_UID to
+ NEW_UID. Called from emit-rtl.c:try_split when a CALL_INSN is
+ split, so that the vtable slot index remains associated with the
+ new CALL_INSN. */
+ void (* copy_virtual_call_token) (int old_uid, int new_uid);
+
/* Records a virtual call given INSN_UID, which is the UID of the call
instruction. The UID is then mapped to the vtable slot index noted
during the lowering phase. Called from final_scan_insn when ICF
@@ -168,6 +174,7 @@ extern void debug_nothing_int_charstar_i
int, bool);
extern void debug_nothing_int (unsigned int);
extern void debug_nothing_int_int (unsigned int, unsigned int);
+extern void debug_nothing_sint_sint (int, int);
extern void debug_nothing_tree (tree);
extern void debug_nothing_tree_tree (tree, tree);
extern void debug_nothing_tree_int (tree, int);
Index: dbxout.c
===================================================================
--- dbxout.c (revision 153570)
+++ dbxout.c (working copy)
@@ -376,6 +376,7 @@ const struct gcc_debug_hooks dbx_debug_h
debug_nothing_void, /* switch_text_section */
debug_nothing_tree, /* direct_call */
debug_nothing_tree_int, /* virtual_call_token */
+ debug_nothing_sint_sint, /* copy_virtual_call_token */
debug_nothing_uid, /* virtual_call */
debug_nothing_tree_tree, /* set_name */
0 /* start_end_main_source_file */
@@ -413,6 +414,7 @@ const struct gcc_debug_hooks xcoff_debug
debug_nothing_void, /* switch_text_section */
debug_nothing_tree, /* direct_call */
debug_nothing_tree_int, /* virtual_call_token */
+ debug_nothing_sint_sint, /* copy_virtual_call_token */
debug_nothing_uid, /* virtual_call */
debug_nothing_tree_tree, /* set_name */
0 /* start_end_main_source_file */
Index: dwarf2out.c
===================================================================
--- dwarf2out.c (revision 153570)
+++ dwarf2out.c (working copy)
@@ -5418,6 +5418,7 @@ static void dwarf2out_abstract_function
static void dwarf2out_var_location (rtx);
static void dwarf2out_direct_call (tree);
static void dwarf2out_virtual_call_token (tree, int);
+static void dwarf2out_copy_virtual_call_token (int, int);
static void dwarf2out_virtual_call (int);
static void dwarf2out_begin_function (tree);
static void dwarf2out_set_name (tree, tree);
@@ -5457,6 +5458,7 @@ const struct gcc_debug_hooks dwarf2_debu
dwarf2out_switch_text_section,
dwarf2out_direct_call,
dwarf2out_virtual_call_token,
+ dwarf2out_copy_virtual_call_token,
dwarf2out_virtual_call,
dwarf2out_set_name,
1 /* start_end_main_source_file */
@@ -19990,6 +19992,42 @@ vcall_insn_table_eq (const void *x, cons
== ((const struct vcall_insn *) y)->insn_uid);
}
+/* Associate VTABLE_SLOT with INSN_UID in the VCALL_INSN_TABLE. */
+
+static void
+store_vcall_insn (unsigned int vtable_slot, int insn_uid)
+{
+ struct vcall_insn *item = GGC_NEW (struct vcall_insn);
+ struct vcall_insn **slot;
+
+ gcc_assert (item);
+ item->insn_uid = insn_uid;
+ item->vtable_slot = vtable_slot;
+ slot = (struct vcall_insn **)
+ htab_find_slot_with_hash (vcall_insn_table, &item,
+ (hashval_t) insn_uid, INSERT);
+ *slot = item;
+}
+
+/* Return the VTABLE_SLOT associated with INSN_UID. */
+
+static unsigned int
+lookup_vcall_insn (unsigned int insn_uid)
+{
+ struct vcall_insn item;
+ struct vcall_insn *p;
+
+ item.insn_uid = insn_uid;
+ item.vtable_slot = 0;
+ p = (struct vcall_insn *) htab_find_with_hash (vcall_insn_table,
+ (void *) &item,
+ (hashval_t) insn_uid);
+ if (p == NULL)
+ return (unsigned int) -1;
+ return p->vtable_slot;
+}
+
+
/* Called when lowering indirect calls to RTL. We make a note of INSN_UID
and the OBJ_TYPE_REF_TOKEN from ADDR. For C++ virtual calls, the token
is the vtable slot index that we will need to put in the virtual call
@@ -20002,21 +20040,23 @@ dwarf2out_virtual_call_token (tree addr,
{
tree token = OBJ_TYPE_REF_TOKEN (addr);
if (TREE_CODE (token) == INTEGER_CST)
- {
- struct vcall_insn *item = GGC_NEW (struct vcall_insn);
- struct vcall_insn **slot;
-
- gcc_assert (item);
- item->insn_uid = insn_uid;
- item->vtable_slot = TREE_INT_CST_LOW (token);
- slot = (struct vcall_insn **)
- htab_find_slot_with_hash (vcall_insn_table, &item,
- (hashval_t) insn_uid, INSERT);
- *slot = item;
- }
+ store_vcall_insn (TREE_INT_CST_LOW (token), insn_uid);
}
}
+/* Called when scheduling RTL, when a CALL_INSN is split. Copies the
+ OBJ_TYPE_REF_TOKEN previously associated with OLD_UID and associate it
+ with NEW_UID. */
+
+static void
+dwarf2out_copy_virtual_call_token (int old_uid, int new_uid)
+{
+ unsigned int vtable_slot = lookup_vcall_insn (old_uid);
+
+ if (vtable_slot != (unsigned int) -1)
+ store_vcall_insn (vtable_slot, new_uid);
+}
+
/* Called by the final INSN scan whenever we see a virtual function call.
Make an entry into the virtual call table, recording the point of call
and the slot index of the vtable entry used to call the virtual member
@@ -20026,20 +20066,14 @@ dwarf2out_virtual_call_token (tree addr,
static void
dwarf2out_virtual_call (int insn_uid)
{
+ unsigned int vtable_slot = lookup_vcall_insn (insn_uid);
vcall_entry e;
- struct vcall_insn item;
- struct vcall_insn *p;
- item.insn_uid = insn_uid;
- item.vtable_slot = 0;
- p = (struct vcall_insn *) htab_find_with_hash (vcall_insn_table,
- (void *) &item,
- (hashval_t) insn_uid);
- if (p == NULL)
+ if (vtable_slot == (unsigned int) -1)
return;
e.poc_label_num = poc_label_num++;
- e.vtable_slot = p->vtable_slot;
+ e.vtable_slot = vtable_slot;
VEC_safe_push (vcall_entry, gc, vcall_table, &e);
/* Drop a label at the return point to mark the point of call. */
@@ -21330,6 +21364,7 @@ const struct gcc_debug_hooks dwarf2_debu
0, /* switch_text_section */
0, /* direct_call */
0, /* virtual_call_token */
+ 0, /* copy_virtual_call_token */
0, /* virtual_call */
0, /* set_name */
0 /* start_end_main_source_file */
Index: sdbout.c
===================================================================
--- sdbout.c (revision 153570)
+++ sdbout.c (working copy)
@@ -340,6 +340,7 @@ const struct gcc_debug_hooks sdb_debug_h
debug_nothing_void, /* switch_text_section */
debug_nothing_tree, /* direct_call */
debug_nothing_tree_int, /* virtual_call_token */
+ debug_nothing_sint_sint, /* copy_virtual_call_token */
debug_nothing_uid, /* virtual_call */
debug_nothing_tree_tree, /* set_name */
0 /* start_end_main_source_file */
@@ -1732,6 +1733,7 @@ const struct gcc_debug_hooks sdb_debug_h
0, /* switch_text_section */
0, /* direct_call */
0, /* virtual_call_token */
+ 0, /* copy_virtual_call_token */
0, /* virtual_call */
0, /* set_name */
0 /* start_end_main_source_file */
Index: emit-rtl.c
===================================================================
--- emit-rtl.c (revision 153570)
+++ emit-rtl.c (working copy)
@@ -3489,6 +3489,11 @@ try_split (rtx pat, rtx trial, int last)
p = &XEXP (*p, 1);
*p = CALL_INSN_FUNCTION_USAGE (trial);
SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
+
+ /* Update the debug information for virtual calls. */
+ if (flag_enable_icf_debug)
+ (*debug_hooks->copy_virtual_call_token) (INSN_UID (trial),
+ INSN_UID (insn));
}
}
More information about the Gcc-patches
mailing list