This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
flow.c and nested subregs
- To: gcc at gcc dot gnu dot org
- Subject: flow.c and nested subregs
- From: Stephen Clarke <Stephen dot Clarke at st dot com>
- Date: Tue, 24 Jul 2001 14:55:31 -0700
- Organization: STMicroelectronics
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.