[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[Bug target/23451] [3.4/4.0/4.1/4.2 regression] Redundant reloading from stack frame




------- Comment #4 from steven at gcc dot gnu dot org  2006-01-10 20:57 -------
On the trunk, we have the following situation in the .csa RTL dump (on AMD64
-m32 -march=i686):

;; Start of basic block 5, registers live:
 4 [si] 5 [di] 6 [bp] 7 [sp] 20 [frame]
(code_label:HI 38 37 39 5 2 "" [1 uses])

(note:HI 39 38 41 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(insn:HI 41 39 42 5 (set (reg:CCZ 17 flags)
        (compare:CCZ (mem/f/c:SI (plus:SI (reg/f:SI 6 bp)
                    (const_int -20 [0xffffffffffffffec])) [7 val+0 S4 A8])
            (const_int 0 [0x0]))) 3 {*cmpsi_ccno_1} (nil)
    (nil))

(jump_insn:HI 42 41 44 5 (set (pc)
        (if_then_else (ne (reg:CCZ 17 flags)
                (const_int 0 [0x0]))
            (label_ref 63)
            (pc))) 511 {*jcc_1} (insn_list:REG_DEP_TRUE 41 (nil))
    (expr_list:REG_DEAD (reg:CCZ 17 flags)
        (expr_list:REG_BR_PROB (const_int 8100 [0x1fa4])
            (nil))))
;; End of basic block 5, registers live:
 4 [si] 5 [di] 6 [bp] 7 [sp] 20 [frame]

(...)

;; Start of basic block 7, registers live: 4 [si] 5 [di] 6 [bp] 7 [sp] 20
[frame]
(code_label:HI 63 119 64 7 5 "" [1 uses])

(note:HI 64 63 125 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

(insn 125 64 66 7 (set (reg:SI 0 ax)
        (mem/f/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -20 [0xffffffffffffffec])) [7 val+0 S4 A8])) 40
{*movsi_1} (nil)
    (nil))

(insn:HI 66 125 67 7 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32])
        (reg:SI 0 ax)) 40 {*movsi_1} (nil)
    (expr_list:REG_DEAD (reg:SI 0 ax)
        (nil)))

(call_insn/u:HI 67 66 68 7 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("strlen") [flags 0x41]
                       <function_decl 0x2aaaaae6fb00 strlen>) [0 S1 A8])
            (const_int 4 [0x4]))) 731 {*call_value_0} (nil)
    (expr_list:REG_EH_REGION (const_int 0 [0x0])
        (nil))
    (expr_list:REG_DEP_TRUE (use (mem:BLK (scratch) [0 A8]))
        (nil)))
(...)


Then we peephole2 the MEM for the compare to a set, see the .peephole2 dump:

;; Start of basic block 5, registers live:
  4 [si] 5 [di] 6 [bp] 7 [sp] 20 [frame]
(code_label:HI 38 37 39 5 2 "" [1 uses])

(note:HI 39 38 142 5 [bb 5] NOTE_INSN_BASIC_BLOCK)

(insn 142 39 143 5 (set (reg:SI 0 ax)
        (mem/f/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -20 [0xffffffffffffffec])) [7 val+0 S4 A8])) -1
(nil)
    (nil))

(insn 143 142 42 5 (set (reg:CCZ 17 flags)
        (compare:CCZ (reg:SI 0 ax)
            (const_int 0 [0x0]))) -1 (nil)
    (expr_list:REG_DEAD (reg:SI 0 ax)
        (nil)))

(jump_insn:HI 42 143 44 5 (set (pc)
        (if_then_else (ne (reg:CCZ 17 flags)
                (const_int 0 [0x0]))
            (label_ref 63)
            (pc))) 511 {*jcc_1} (insn_list:REG_DEP_TRUE 41 (nil))
    (expr_list:REG_DEAD (reg:CCZ 17 flags)
        (expr_list:REG_BR_PROB (const_int 8100 [0x1fa4])
            (nil))))
;; End of basic block 5, registers live:
 4 [si] 5 [di] 6 [bp] 7 [sp] 20 [frame]

(...)

;; Start of basic block 7, registers live: 4 [si] 5 [di] 6 [bp] 7 [sp] 20
[frame]
(code_label:HI 63 119 64 7 5 "" [1 uses])

(note:HI 64 63 125 7 [bb 7] NOTE_INSN_BASIC_BLOCK)

(insn 125 64 66 7 (set (reg:SI 0 ax)
        (mem/f/c:SI (plus:SI (reg/f:SI 6 bp)
                (const_int -20 [0xffffffffffffffec])) [7 val+0 S4 A8])) 40
{*movsi_1} (nil)
    (nil))

(insn:HI 66 125 67 7 (set (mem:SI (reg/f:SI 7 sp) [0 S4 A32])
        (reg:SI 0 ax)) 40 {*movsi_1} (nil)
    (expr_list:REG_DEAD (reg:SI 0 ax)
        (nil)))

(call_insn/u:HI 67 66 68 7 (set (reg:SI 0 ax)
        (call (mem:QI (symbol_ref:SI ("strlen") [flags 0x41]
                       <function_decl 0x2aaaaae6fb00 strlen>) [0 S1 A8])
            (const_int 4 [0x4]))) 731 {*call_value_0} (nil)
    (expr_list:REG_EH_REGION (const_int 0 [0x0])
        (nil))
    (expr_list:REG_DEP_TRUE (use (mem:BLK (scratch) [0 A8]))
        (nil)))


Essentially the same thing happens in GCC 3.3: Up to peephole2, the first MEM
is burried in the compare, and split out by some peephole. 

I don't think this is related to register allocation, really.  Someone should
try to see what the flow2 dump looks like for GCC 3.2, which is apparently the
last release that did not have this problem.  In any case, it will be difficult
to find out when this problem was introduced.  But it doesn't look like a
really severe problem to me anyway, really...


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23451

------- You are receiving this mail because: -------
You reported the bug, or are watching the reporter.



Reply to: