This is the mail archive of the gcc@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]

A question about df_get_live_in


Hi,

I hope DF/middle-end experts will comment about this.

PR target/40710
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40710

is a wrong code problem on SH.  A delayed slot of a conditional
branch insn is wrongly filled with an insn changing stack pointer
in the failing case.  I've tried to see what is going on.

Before the dbr optimization, the code looks like as

(note 6 1 5 [bb 2] NOTE_INSN_BASIC_BLOCK)
...
(jump_insn 13 12 31 fs/ext3/balloc.c:57 (set (pc)
        (if_then_else (eq (reg:SI 147 t)
                (const_int 0 [0x0]))
            (label_ref:SI 129)
            (pc))) 208 {branch_false} (expr_list:REG_DEAD (reg:SI 147 t)
        (expr_list:REG_BR_PROB (const_int 184 [0xb8])
            (nil))))

(note 31 13 46 [bb 3] NOTE_INSN_BASIC_BLOCK)

(note 46 31 32 NOTE_INSN_DELETED)

(insn 32 46 35 fs/ext3/balloc.c:66 (parallel [
            (asm_operands/v ("") ("") 0 []
                 [] 2935777)
            (clobber (mem:BLK (scratch) [0 A8]))
        ]) -1 (nil))
...
...
(barrier 126 125 129)

(code_label 129 126 14 9 "" [1 uses])

(note 14 129 109 [bb 8] NOTE_INSN_BASIC_BLOCK)

(insn 109 14 15 fs/ext3/balloc.c:58 (set (reg/f:SI 1 r1 [176])
        (mem/u/c:SI (label_ref 146) [0 S4 A32])) 172 {movsi_ie} (expr_list:REG_EQUIV (symbol_ref:SI ("ext3_error") [flags 0x41] <function_decl 0xb7a28d80 ext3_error>)
        (nil)))

(insn 15 109 24 fs/ext3/balloc.c:58 (set (reg/f:SI 15 r15)
        (plus:SI (reg/f:SI 15 r15)
            (const_int -4 [0xfffffffffffffffc]))) 35 {*addsi3_compact} (nil))

reorg.c:fill_slots_from_thread fills that delay slot of insn 13
with insn 15 from bb 8.  Since r15 is the stack pointer register
for SH, this fill makes it wrong when the conditional jmp isn't
taken.  fill_slots_from_thread computes the resource set for
the follow-through block of that jmp insn with

  mark_target_live_regs (get_insns (), opposite_thread, &opposite_needed);

and mark_target_live_regs uses df_get_live_in to get live regs
for the basic block including the opposite_thread insn which is
insn 32.  gdb shows the resulting opposite_needed is

$1 = {memory = 0x1, unch_memory = 0x0, volatil = 0x0, cc = 0x0,
      regs = {0xf6,  0x0, 0x0, 0x0, 0x40000}}

i.e. it seems that df_get_live_in doesn't count r15 as an live
register and fill_slots_from_thread picks insn 15 up as
an eligible insn to fill that delayed slot.
Is this the expected behavior of df_get_live_in?  If so, is
there something problematic in the target?

I thought that the stack pointer register should be live here.
The first part of DF dump in .compgotos which is the last dump
before dbr pass is:

;; Start of basic block ( 0) -> 2
;; bb 2 artificial_defs: { }
;; bb 2 artificial_uses: { u-1(15){ }}
;; lr  in        4 [r4] 5 [r5] 6 [r6] 15 [r15] 146 [pr] 151 []
;; lr  use       4 [r4] 5 [r5] 15 [r15] 146 [pr]
;; lr  def       1 [r1] 2 [r2] 3 [r3] 15 [r15] 147 [t]
;; live  in      4 [r4] 5 [r5] 6 [r6] 146 [pr]
;; live  gen     1 [r1] 2 [r2] 3 [r3] 15 [r15] 147 [t]
;; live  kill   
...
;; End of basic block 2 -> ( 8 3)
;; lr  out       1 [r1] 2 [r2] 3 [r3] 4 [r4] 5 [r5] 6 [r6] 15 [r15] 151 []
;; live  out     1 [r1] 2 [r2] 3 [r3] 4 [r4] 5 [r5] 6 [r6] 15 [r15]
...
;; Start of basic block ( 2) -> 3
;; bb 3 artificial_defs: { }
;; bb 3 artificial_uses: { u-1(15){ }}
;; lr  in        1 [r1] 2 [r2] 4 [r4] 5 [r5] 6 [r6] 15 [r15] 151 []
;; lr  use       1 [r1] 2 [r2] 5 [r5] 15 [r15]
;; lr  def       0 [r0] 1 [r1] 2 [r2] 3 [r3] 7 [r7] 147 [t]
;; live  in      1 [r1] 2 [r2] 4 [r4] 5 [r5] 6 [r6] 15 [r15]
;; live  gen     0 [r0] 1 [r1] 2 [r2] 3 [r3] 7 [r7] 147 [t]
;; live  kill   
...
;; End of basic block 3 -> ( 9 4)
;; lr  out       1 [r1] 2 [r2] 4 [r4] 5 [r5] 6 [r6] 7 [r7] 15 [r15] 151 []
;; live  out     1 [r1] 2 [r2] 4 [r4] 5 [r5] 6 [r6] 7 [r7] 15 [r15]

Regards,
	kaz


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