Hi all,
I would like to know if the attached patch resource-check.patch is a
good sanity check or not.
I have been working in reorg.c and running into trouble with the target
info cache in mark_target_live_regs, so I decided to write a patch that
checks consistency between cached values and recomputed values. Soon I
started running into issues that were unrelated to my changes in reorg.c.
As an example of the kind of situations the sanity check detects,
consider fixed-bit.c.212r.alignments. During pass_machine_reorg, the
following scenario happens:
1. a copy of insn 78 is imported into the delay slot of jump_insn 14.
(insn 106 13 49
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(sequence [
(jump_insn 14 13 78
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (pc)
(if_then_else (ne (reg:SI 2 $2 [200])
(const_int 0 [0x0]))
(label_ref:SI 105)
(pc))) 442 {*branch_equalitysi_micromips}
(expr_list:REG_DEAD (reg:SI 2 $2 [200])
(expr_list:REG_BR_PROB (const_int 6100 [0x17d4])
(nil)))
-> 105)
(insn/s 78 14 49 (set (reg:SI 3 $3 [orig:196 z+4 ] [196])
(const_int 0 [0x0])) 284 {*movsi_internal} (nil))
]) -1 (nil))
It's a copy since jump_insn 14 does not own the thread containing insn
78. The copy is marked with INSN_FROM_TARGET_P (insn/s) to indicate that
it was imported from the target of the jump.
2. we call mark_target_live_regs for insn 17. We scan all insn from the
start of the function to insn 17. We ignore however the copy of insn 78,
since it's marked with INSN_FROM_TARGET_P, so we conclude that $3 is not
live at insn 17. This info is stored in the target info cache.
3. redundant_insn finds that the original insn 78 is redundant (since
the copy of insn 78 occurs on all paths towards insn 78) and decides to
remove the original. The INSN_FROM_TARGET_P of the copy is cleared, to
indicate that the $3 is now live on the fall-through path of jump_insn
14 as well.
4. we call mark_target_live_regs for insn 17 again. We get the value
from the cache and conclude that $3 is not live at insn 17. Then my
patch recomputes the live info, which now takes the copy of insn 78 into
account since INSN_FROM_TARGET_P has been cleared, and concludes that $3
is live. And we assert.
The following fix makes sure that the cached live info is invalidated:
...
@@ -1865,6 +1880,7 @@ redundant_insn (rtx insn, rtx target, rt
{
/* Show that this insn will be used in the sequel. */
INSN_FROM_TARGET_P (candidate) = 0;
+ incr_ticks_for_insn (candidate);
return candidate;
}
...
and the assert is not triggered anymore.
So my questions are:
- is the consistency check correct? Does it make sense to fix all the
cases where it triggers?
- Is my analysis of the example and the fix correct?
Thanks,
- Tom
Index: gcc/resource.c
===================================================================
--- gcc/resource.c (revision 310935)
+++ gcc/resource.c (working copy)
@@ -878,6 +878,12 @@ mark_target_live_regs (rtx insns, rtx ta
rtx jump_insn = 0;
rtx jump_target;
HARD_REG_SET scratch;
+#if defined ENABLE_RUNTIME_CHECKING
+ HARD_REG_SET cached;
+ bool cached_valid = false;
+ int fb = -1;
+#endif
+
struct resources set, needed;
/* Handle end of function. */
@@ -918,6 +924,13 @@ mark_target_live_regs (rtx insns, rtx ta
if (b == -1)
b = find_basic_block (target, MAX_DELAY_SLOT_LIVE_SEARCH);
+#if defined ENABLE_RUNTIME_CHECKING
+ else
+ {
+ fb = find_basic_block (target, MAX_DELAY_SLOT_LIVE_SEARCH);
+ gcc_assert (fb == -1 || fb == b);
+ }
+#endif
if (target_hash_table != NULL)
{
@@ -927,8 +940,13 @@ mark_target_live_regs (rtx insns, rtx ta
update it below. */
if (b == tinfo->block && b != -1 && tinfo->bb_tick == bb_ticks[b])
{
+#if defined ENABLE_RUNTIME_CHECKING
+ cached_valid = true;
+ COPY_HARD_REG_SET (cached, tinfo->live_regs);
+#else
COPY_HARD_REG_SET (res->regs, tinfo->live_regs);
return;
+#endif
}
}
else
@@ -1126,6 +1144,10 @@ mark_target_live_regs (rtx insns, rtx ta
{
COPY_HARD_REG_SET (tinfo->live_regs, res->regs);
}
+#if defined ENABLE_RUNTIME_CHECKING
+ if (cached_valid)
+ gcc_assert (hard_reg_set_equal_p (cached, tinfo->live_regs));
+#endif
}
/* Initialize the resources required by mark_target_live_regs ().
;; Function __ussubudq3 (__ussubudq3)
(note 1 0 6 NOTE_INSN_DELETED)
(note 6 1 80 2 [bb 2] NOTE_INSN_BASIC_BLOCK)
(note 80 6 4 2 NOTE_INSN_PROLOGUE_END)
(note 4 80 9 2 NOTE_INSN_FUNCTION_BEG)
(debug_insn 9 4 11 2
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:180
(var_location:DI x (concatn:DI [
(reg:SI 4 $4 [orig:209 x.0 ] [209])
(reg:SI 5 $5 [orig:210 x.0+4 ] [210])
])) -1 (nil))
(debug_insn 11 9 12 2
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:181
(var_location:DI y (concatn:DI [
(reg:SI 6 $6 [orig:211 y.1 ] [211])
(reg:SI 7 $7 [orig:212 y.1+4 ] [212])
])) -1 (nil))
(debug_insn 12 11 13 2
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(var_location:DI z (minus:DI (concatn:DI [
(reg:SI 4 $4 [orig:209 x.0 ] [209])
(reg:SI 5 $5 [orig:210 x.0+4 ] [210])
])
(concatn:DI [
(reg:SI 6 $6 [orig:211 y.1 ] [211])
(reg:SI 7 $7 [orig:212 y.1+4 ] [212])
]))) -1 (nil))
(insn 13 12 14 2
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (reg:SI 2 $2 [200])
(gtu:SI (reg:SI 6 $6 [orig:211 y.1 ] [211])
(reg:SI 4 $4 [orig:209 x.0 ] [209]))) 479 {*sgtu_sisi} (nil))
(jump_insn 14 13 49 2
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (pc)
(if_then_else (ne (reg:SI 2 $2 [200])
(const_int 0 [0x0]))
(label_ref:SI 48)
(pc))) 442 {*branch_equalitysi_micromips} (expr_list:REG_DEAD
(reg:SI 2 $2 [200])
(expr_list:REG_BR_PROB (const_int 6100 [0x17d4])
(nil)))
-> 48)
(note 49 14 16 3 [bb 3] NOTE_INSN_BASIC_BLOCK)
(jump_insn 16 49 50 3
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (pc)
(if_then_else (ne (reg:SI 6 $6 [orig:211 y.1 ] [211])
(reg:SI 4 $4 [orig:209 x.0 ] [209]))
(label_ref:SI 55)
(pc))) 442 {*branch_equalitysi_micromips} (expr_list:REG_BR_PROB
(const_int 3900 [0xf3c])
(nil))
-> 55)
(note 50 16 17 4 [bb 4] NOTE_INSN_BASIC_BLOCK)
(insn 17 50 18 4
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (reg:SI 2 $2 [202])
(gtu:SI (reg:SI 7 $7 [orig:212 y.1+4 ] [212])
(reg:SI 5 $5 [orig:210 x.0+4 ] [210]))) 479 {*sgtu_sisi} (nil))
(jump_insn 18 17 55 4
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:183
(set (pc)
(if_then_else (ne (reg:SI 2 $2 [202])
(const_int 0 [0x0]))
(label_ref:SI 48)
(pc))) 442 {*branch_equalitysi_micromips} (expr_list:REG_DEAD
(reg:SI 2 $2 [202])
(expr_list:REG_BR_PROB (const_int 6100 [0x17d4])
(nil)))
-> 48)
(code_label 55 18 24 5 5 "" [1 uses])
(note 24 55 29 5 [bb 5] NOTE_INSN_BASIC_BLOCK)
(note 29 24 26 5 NOTE_INSN_DELETED)
(insn 26 29 27 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 7 $7 [orig:214+4 ] [214])
(minus:SI (reg:SI 5 $5 [orig:210 x.0+4 ] [210])
(reg:SI 7 $7 [orig:212 y.1+4 ] [212]))) 23 {subsi3} (nil))
(insn 27 26 28 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 5 $5 [206])
(gtu:SI (reg:SI 7 $7 [orig:214+4 ] [214])
(reg:SI 5 $5 [orig:210 x.0+4 ] [210]))) 479 {*sgtu_sisi} (nil))
(insn 28 27 62 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 6 $6 [213])
(minus:SI (reg:SI 4 $4 [orig:209 x.0 ] [209])
(reg:SI 6 $6 [orig:211 y.1 ] [211]))) 23 {subsi3}
(expr_list:REG_DEAD (reg:SI 4 $4 [orig:209 x.0 ] [209])
(nil)))
(insn 62 28 74 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 9 $9 [orig:220 z ] [220])
(minus:SI (reg:SI 6 $6 [213])
(reg:SI 5 $5 [206]))) 23 {subsi3} (expr_list:REG_DEAD (reg:SI 6 $6
[213])
(expr_list:REG_DEAD (reg:SI 5 $5 [206])
(nil))))
(insn 74 62 75 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 2 $2 [ z ])
(reg:SI 9 $9 [orig:220 z ] [220])) 284 {*movsi_internal}
(expr_list:REG_DEAD (reg:SI 9 $9 [orig:220 z ] [220])
(nil)))
(insn 75 74 81 5
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:182
(set (reg:SI 3 $3 [orig:222 z+4 ] [222])
(reg:SI 7 $7 [orig:221 z+4 ] [221])) 284 {*movsi_internal}
(expr_list:REG_DEAD (reg:SI 7 $7 [orig:221 z+4 ] [221])
(nil)))
(jump_insn 81 75 67 5 (return) 564 {*return} (nil)
-> return)
(barrier 67 81 48)
(code_label 48 67 47 6 4 "" [2 uses])
(note 47 48 78 6 [bb 6] NOTE_INSN_BASIC_BLOCK)
(insn 78 47 79 6
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:184
(set (reg:SI 3 $3 [orig:196 z+4 ] [196])
(const_int 0 [0x0])) 284 {*movsi_internal} (nil))
(insn 79 78 34 6
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:184
(set (reg:SI 2 $2 [ z ])
(const_int 0 [0x0])) 284 {*movsi_internal} (nil))
(debug_insn 34 79 35 6 (var_location:DI z (reg/v:DI 2 $2 [orig:196 z ] [196]))
-1 (nil))
(debug_insn 35 34 43 6
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:189
(var_location:UDQ c (subreg:UDQ (reg/v:DI 2 $2 [orig:196 z ] [196]) 0)) -1
(nil))
(insn 43 35 83 6
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:191
(use (reg/i:UDQ 2 $2)) -1 (nil))
(jump_insn 83 43 82 6
/scratch/vries/henry7/mips/src/gcc-trunk-4.5/libgcc/../gcc/config/fixed-bit.c:191
(return) 564 {*return} (nil)
-> return)
(barrier 82 83 77)
(note 77 82 0 NOTE_INSN_DELETED)