This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
REG_N_SETS and scheduling
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: 08 Dec 2002 11:50:46 +0000
- Subject: REG_N_SETS and scheduling
The test case below fails for -mips4 when scheduling is enabled.
We have a sequence like this before split_all_insns:
...
t1 = buf
t2 = 0x13560
t1[t2] = 42.0
t3 = 0x10000
t4 = t1 + t3
t5 = t4[0x3560]
...
There's only one assignment to t2, so REG_N_SETS (t2) == 1.
split_all_insns splits it as follows:
t2 = 0x10000
t2 = t2 | 0x3560
but REG_N_SETS isn't updated until after scheduling.
init_alias_analysis sees t2 = 0x10000, notices that REG_N_SETS (t2)
is 1, and sets reg_known_equiv[t2] to 0x10000. Thus t2[t1] is
canonicalised as buf[0x10000] and doesn't alias the later load.
I don't understand the handling of REG_N_SETS too well (when is it
supposed to be valid, when isn't it?) so the patch below is only
tentative. It feels too much like the easy way out.
Anyway, tested on mips64-elf ({,-mips4,-msoft-float}{,-EL}).
No regressions.
Richard
* toplev.c (rest_of_compilation): Recompute register usage after
split_all_insns.
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.689
diff -c -d -p -F^[(a-zA-Z0-9_^#] -r1.689 toplev.c
*** toplev.c 23 Nov 2002 02:07:13 -0000 1.689
--- toplev.c 8 Dec 2002 11:08:32 -0000
*************** rest_of_compilation (decl)
*** 2383,2389 ****
int tem;
int failure = 0;
int rebuild_label_notes_after_reload;
- int register_life_up_to_date;
timevar_push (TV_REST_OF_COMPILATION);
--- 2383,2388 ----
*************** #endif
*** 3175,3184 ****
description to add extra information not needed previously. */
split_all_insns (1);
- /* Any of the several passes since flow1 will have munged register
- lifetime data a bit. */
- register_life_up_to_date = 0;
-
#ifdef OPTIMIZE_MODE_SWITCHING
timevar_push (TV_MODE_SWITCH);
--- 3174,3179 ----
*************** #ifdef OPTIMIZE_MODE_SWITCHING
*** 3189,3194 ****
--- 3184,3194 ----
timevar_pop (TV_MODE_SWITCH);
#endif
+ /* Any of the several passes since flow1 will have munged register
+ lifetime data a bit. We need it to be up to date for scheduling
+ (see handling of reg_known_equiv in init_alias_analysis). */
+ recompute_reg_usage (insns, !optimize_size);
+
timevar_push (TV_SCHED);
#ifdef INSN_SCHEDULING
*************** #ifdef INSN_SCHEDULING
*** 3205,3214 ****
schedule_insns (rtl_dump_file);
close_dump_file (DFI_sched, print_rtl_with_bb, insns);
-
- /* Register lifetime information was updated as part of verifying
- the schedule. */
- register_life_up_to_date = 1;
}
#endif
timevar_pop (TV_SCHED);
--- 3205,3210 ----
*************** #endif
*** 3227,3235 ****
RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
jump optimizer after register allocation and reloading are finished. */
-
- if (! register_life_up_to_date)
- recompute_reg_usage (insns, ! optimize_size);
if (flag_new_regalloc)
{
--- 3223,3228 ----
*** /dev/null Tue Nov 14 21:44:43 2000
--- testsuite/gcc.c-torture/execute/20021207-1.c Fri Dec 6 17:41:20 2002
***************
*** 0 ****
--- 1,11 ----
+ double x[100][100];
+ int main ()
+ {
+ int i;
+
+ i = 99;
+ x[i][0] = 42;
+ if (x[99][0] != 42)
+ abort ();
+ exit (0);
+ }