This is the mail archive of the gcc-patches@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]
Other format: [Raw text]

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);
+ }


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