------- Comment #9 from danglin at gcc dot gnu dot org  2006-01-07 18:37 -------
I'm changing this to a target bug.  The bug is in the define for
SECONDARY_MEMORY_NEEDED_RTX(MODE):

#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
  gen_rtx_MEM (MODE, gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-16)))

There are a number of places where this memory location gets used during
final code generation.  I don't think we can add clobbers.

When we define SECONDARY_MEMORY_NEEDED_RTX as above, reload introduces
store-load insns into the RTL to copy a value from a general/floating
register to a floating/general register.  Subsequently, scheduling may
copy separate the load and store insns.  This then can introduce a conflict
with the use of this memory location during code generation.

I'm not sure about the validity of scheduling moving the "fldws
-16(%r30),%fr21L"
over a call.  The call_insn is marked as a const or pure call:

(call_insn/u 80 4722 4769 0 cxg1005.adb:88 (parallel [
            (set (reg:SC 28 %r28)
                (call (mem:SI (symbol_ref/v:SI
("@cxg1005__test_block__complex_p
ack__compose_from_cartesian__3___395") <function_decl 0x40100620
cxg1005__test_b
lock__complex_pack__compose_from_cartesian__3>) [0 S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 1 %r1))
            (clobber (reg:SI 2 %r2))
            (use (const_int 0 [0x0]))
        ]) 204 {call_val_symref} (insn_list:REG_DEP_TRUE 60
(insn_list:REG_DEP_O
UTPUT 63 (insn_list:REG_DEP_ANTI 66 (insn_list:REG_DEP_ANTI 65
(insn_list:REG_DE
P_OUTPUT 20 (insn_list:REG_DEP_ANTI 22 (insn_list:REG_DEP_OUTPUT 21
(insn_list:R
EG_DEP_TRUE 79 (insn_list:REG_DEP_ANTI 64 (nil))))))))))
    (expr_list:REG_DEAD (reg:SF 32 %fr4)
        (expr_list:REG_UNUSED (reg:SI 2 %r2)
            (expr_list:REG_UNUSED (reg:SI 1 %r1)
                (nil))))
    (expr_list:REG_DEP_TRUE (use (reg:SF 32 %fr4))
        (nil)))

The decision as to whether the function is pure is made before reload and
that doesn't change when the SECONDARY_MEMORY_NEEDED_RTX MEM is used (ie.,
we use a special location in the frame of the caller for the copy.  This
problem can be avoided if we always ensure that the function has a frame.
However, this adds instructions and still doesn't fix the issue that the
MEM might be used between the store and load in other situations.

Thus, I think the best fix is to remove the SECONDARY_MEMORY_NEEDED_RTX
define and do the register copy in the move patterns directly.  This keeps
the MEM from being exposed in the RTL.  We lose the performance benefit
of scheduling the store and load.  However, we don't need a frame to
do floating-general copies.

As an aside, the problem is introduced in the RTL in the sched2 pass:

call_insn/u 80 4722 5740 0 cxg1005.adb:88 (parallel [
            (set (reg:SC 28 %r28)
                (call (mem:SI (symbol_ref/v:SI
("@cxg1005__test_block__complex_p
ack__compose_from_cartesian__3___395") <function_decl 0x40100620
cxg1005__test_b
lock__complex_pack__compose_from_cartesian__3>) [0 S4 A32])
                    (const_int 16 [0x10])))
            (clobber (reg:SI 1 %r1))
            (clobber (reg:SI 2 %r2))
            (use (const_int 0 [0x0]))
        ]) 204 {call_val_symref} (insn_list:REG_DEP_OUTPUT 63
(insn_list:REG_DEP
_ANTI 4765 (insn_list:REG_DEP_ANTI 4763 (insn_list:REG_DEP_OUTPUT 12
(insn_list:
REG_DEP_OUTPUT 10 (insn_list:REG_DEP_OUTPUT 17 (insn_list:REG_DEP_ANTI 22
(insn_
list:REG_DEP_OUTPUT 15 (insn_list:REG_DEP_ANTI 4767 (insn_list:REG_DEP_ANTI
4768
 (insn_list:REG_DEP_OUTPUT 4677 (insn_list:REG_DEP_ANTI 5372
(insn_list:REG_DEP_
ANTI 5391 (insn_list:REG_DEP_ANTI 5392 (insn_list:REG_DEP_ANTI 5393
(insn_list:R
EG_DEP_ANTI 5394 (insn_list:REG_DEP_ANTI 5395 (insn_list:REG_DEP_ANTI 5396
(insn
_list:REG_DEP_ANTI 5397 (insn_list:REG_DEP_ANTI 5398 (insn_list:REG_DEP_ANTI
539
9 (insn_list:REG_DEP_ANTI 5400 (insn_list:REG_DEP_OUTPUT 5390
(insn_list:REG_DEP
_TRUE 79 (insn_list:REG_DEP_TRUE 5373 (insn_list:REG_DEP_ANTI 64
(nil)))))))))))
))))))))))))))))
    (expr_list:REG_DEAD (reg:SF 32 %fr4)
        (expr_list:REG_UNUSED (reg:SI 2 %r2)
            (expr_list:REG_UNUSED (reg:SI 1 %r1)
                (nil))))
    (expr_list:REG_DEP_TRUE (use (reg:SF 32 %fr4))
        (nil)))

(note 5740 80 4766 0 ("cxg1005.adb") 87)

(insn 4766 5740 5741 0 cxg1005.adb:87 (set (reg:SF 66 %fr21 [orig:778+4 ]
[778])
        (mem:SF (plus:SI (reg/f:SI 30 %r30)
                (const_int -16 [0xfffffff0])) [0 S4 A32])) 77 {*pa.md:4325}
(ins
n_list:REG_DEP_ANTI 5391 (insn_list:REG_DEP_TRUE 5373 (insn_list:REG_DEP_ANTI
64
 (insn_list:REG_DEP_TRUE 4763 (insn_list:REG_DEP_TRUE 4765 (nil))))))
    (nil))



-- 

danglin at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
          Component|ada                         |target


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


Reply via email to