This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[vta] regstack fixes for var-tracking-assignments
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 05 Nov 2007 05:41:31 -0200
- Subject: [vta] regstack fixes for var-tracking-assignments
Most of the changes I'd made to regstack.c to avoid code changes with
debug insns were obsoleted by other changes elsewhere. However,
references to floating point stack registers in debug insns weren't
being updated at all. This patch fixes this.
It also fixes a codegen change caused by debug insns in the beginning
of a BB. reg-stack uses the reg-stack requirements of the first insn
in the BB that has reg-stack requirements to determine how the
reg-stack should look like at the entry point of the BB. If there was
a debug insns that referenced stack registers before, its requirements
(none) would be taken into account *instead of* those of the first
active insn. Oops.
This patch processes the initial debug insns after determining the
entry point stack layout. I guess I could try to come up with some
clever means to link the debug insns such that I wouldn't have to
count them and potentially iterate over the entire sequence, but I
don't think it's worth it.
I'm going to check this in the vta branch soon.
for gcc/ChangeLog.vta
from Alexandre Oliva <aoliva@redhat.com>
* reg-stack.c (subst_stack_regs_in_debug_insn): New.
(subst_stack_regs_pat): Revert.
(convert_regs_1): Replace regs in debug insns. Deal with
debug insns before first active insn.
Index: gcc/reg-stack.c
===================================================================
--- gcc/reg-stack.c.orig 2007-11-05 05:06:18.000000000 -0200
+++ gcc/reg-stack.c 2007-11-05 05:31:55.000000000 -0200
@@ -310,7 +310,7 @@ stack_regs_mentioned (const_rtx insn)
unsigned int uid, max;
int test;
- if (! INSN_P (insn) /* || DEBUG_INSN_P (insn) */ || !stack_regs_mentioned_data)
+ if (! INSN_P (insn) || !stack_regs_mentioned_data)
return 0;
uid = INSN_UID (insn);
@@ -1328,6 +1328,30 @@ compare_for_stack_reg (rtx insn, stack r
}
}
+/* Substitute new registers in LOC, which is part of a debug insn.
+ REGSTACK is the current register layout. */
+
+static int
+subst_stack_regs_in_debug_insn (rtx *loc, void *data)
+{
+ rtx *tloc = get_true_reg (loc);
+ stack regstack = (stack)data;
+ int hard_regno;
+
+ if (!STACK_REG_P (*tloc))
+ return 0;
+
+ if (tloc != loc)
+ return 0;
+
+ hard_regno = get_hard_regnum (regstack, *loc);
+ gcc_assert (hard_regno >= FIRST_STACK_REG);
+
+ replace_reg (loc, hard_regno);
+
+ return -1;
+}
+
/* Substitute new registers in PAT, which is part of INSN. REGSTACK
is the current register layout. Return whether a control flow insn
was deleted in the process. */
@@ -1362,14 +1386,7 @@ subst_stack_regs_pat (rtx insn, stack re
break;
case VAR_LOCATION:
- for (dest = ®_NOTES (insn); *dest; dest = &XEXP (*dest, 1))
- if (REG_NOTE_KIND (*dest) == REG_DEAD
- && STACK_REG_P (*(src = &XEXP (*dest, 0)))
- && TEST_HARD_REG_BIT (regstack->reg_set, REGNO (*src)))
- /* ??? This is not right. We want to *avoid* emitting the
- pop and the corresponding push. */
- emit_pop_insn (insn, regstack, *src, EMIT_AFTER);
- break;
+ gcc_unreachable ();
case CLOBBER:
{
@@ -2865,6 +2882,7 @@ convert_regs_1 (basic_block block)
int reg;
rtx insn, next;
bool control_flow_insn_deleted = false;
+ int debug_insns_with_starting_stack = 0;
any_malformed_asm = false;
@@ -2917,8 +2935,25 @@ convert_regs_1 (basic_block block)
/* Don't bother processing unless there is a stack reg
mentioned or if it's a CALL_INSN. */
- if (stack_regs_mentioned (insn)
- || CALL_P (insn))
+ if (DEBUG_INSN_P (insn))
+ {
+ if (starting_stack_p)
+ debug_insns_with_starting_stack++;
+ else
+ {
+ for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn,
+ ®stack);
+
+ /* Nothing must ever die at a debug insn. If something
+ is referenced in it that becomes dead, it should have
+ died before and the reference in the debug insn
+ should have been removed so as to avoid changing code
+ generation. */
+ gcc_assert (!REG_NOTES (insn));
+ }
+ }
+ else if (stack_regs_mentioned (insn)
+ || CALL_P (insn))
{
if (dump_file)
{
@@ -2932,6 +2967,24 @@ convert_regs_1 (basic_block block)
}
while (next);
+ if (debug_insns_with_starting_stack)
+ {
+ /* Since it's the first non-debug instruction that determines
+ the stack requirements of the current basic block, we refrain
+ from updating debug insns before it in the loop above, and
+ fix them up here. */
+ for (insn = BB_HEAD (block); debug_insns_with_starting_stack;
+ insn = NEXT_INSN (insn))
+ {
+ if (!DEBUG_INSN_P (insn))
+ continue;
+
+ debug_insns_with_starting_stack--;
+ for_each_rtx (&PATTERN (insn), subst_stack_regs_in_debug_insn,
+ &bi->stack_in);
+ }
+ }
+
if (dump_file)
{
fprintf (dump_file, "Expected live registers [");
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}