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]

flow.c and nested subregs


I have the following rtl instruction:

(insn 32 30 33 (set (subreg:DF (reg/v:DI 191) 0)
        (const_double:DF (cc0) 0 [0x0] 0 [0x0] [0])) 128 {} (nil)
    (nil))

My target is 64 bits, so a DI occupies (the whole of) a single
register.  Similarly, a DF also occupies the whole of a single
register.

When lifetime analysis is run, mark_set_1() in flow.c correctly
recognizes that this instruction kills the whole of r191.

When the instruction scheduler is run, it calls split_all_insns(),
which rewrites the instruction as:

(insn 32 30 3637 (set (subreg:DI (subreg:DF (reg/v:DI 191) 0) 0)
        (const_int 0 [0x0])) -1 (nil)
    (nil))

But now the function mark_set_1() does not recognize this
instruction as killing the whole of r191.  (And so when the instruction
scheduler calls update_live_info() I get an abort because the
live_at_start set calculated after scheduling does not match the
live_at_start set from before scheduling.)

This appears to be because of the use of a nested subreg:
mark_set_1() looks down one level of subreg for a register but no
further.

So I have a couple of questions:

1. Is this kind of usage of subreg allowed (i.e. one subreg nested inside
   another)?

2. Should mark_set_1() recognize that this instruction kills the whole
   register? (I understand that the current behavior of mark_set_1()
   could be considered to be correct but pessimistic.)

Thanks for any help,
Steve.
-- 
Stephen Clarke, Micro Cores & Development Tools, STMicroelectronics
Phone:1-408-922-4062, Fax:1-408-895-3069, mailto:Stephen.Clarke@st.com
Mail:  STMicroelectronics, 1060 E. Brokaw Rd., San Jose, CA 95131.


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