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]

post-reload life vs scheduling



I've installed this patch which should fix many of the bad interactions between
the post-reload life analysis pass and instruction scheduling.  It should
fix our sparc problems (including the complex failures) as well as another
handful of sh build failures.



        * final.c (cleanup_subreg_operands): New function.
        (final_scan_insn): Use it.
        (alter_subreg): Clear the "used" field when we turn a SUBREG into
        a REG.
        * reload1.c (reload): Delete CLOBBER insns and also cleanup SUBREG
        operands when reload has finished.
        * reload.h (cleanup_subreg_operands): Declare..
        * flow.c (life_analysis_1): No longer delete CLOBBER insns after
        reload.  Handled in reload itself.

Index: final.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/final.c,v
retrieving revision 1.159
diff -c -3 -p -r1.159 final.c
*** final.c	1998/10/09 23:02:32	1.159
--- final.c	1998/10/28 07:15:27
*************** final_scan_insn (insn, file, optimize, p
*** 2933,2955 ****
  
  	insn_code_number = recog_memoized (insn);
  	insn_extract (insn);
! 	for (i = 0; i < insn_n_operands[insn_code_number]; i++)
! 	  {
! 	    if (GET_CODE (recog_operand[i]) == SUBREG)
! 	      recog_operand[i] = alter_subreg (recog_operand[i]);
! 	    else if (GET_CODE (recog_operand[i]) == PLUS
! 		     || GET_CODE (recog_operand[i]) == MULT)
! 	      recog_operand[i] = walk_alter_subreg (recog_operand[i]);
! 	  }
! 
! 	for (i = 0; i < insn_n_dups[insn_code_number]; i++)
! 	  {
! 	    if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
! 	      *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
! 	    else if (GET_CODE (*recog_dup_loc[i]) == PLUS
! 		     || GET_CODE (*recog_dup_loc[i]) == MULT)
! 	      *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
! 	  }
  
  #ifdef REGISTER_CONSTRAINTS
  	if (! constrain_operands (insn_code_number, 1))
--- 2933,2939 ----
  
  	insn_code_number = recog_memoized (insn);
  	insn_extract (insn);
! 	cleanup_subreg_operands (insn);
  
  #ifdef REGISTER_CONSTRAINTS
  	if (! constrain_operands (insn_code_number, 1))
*************** output_source_line (file, insn)
*** 3128,3133 ****
--- 3112,3160 ----
      }
  }
  
+ 
+ /* For each operand in INSN, simplify (subreg (reg)) so that it refers
+    directly to the desired hard register.  */
+ void
+ cleanup_subreg_operands (insn)
+      rtx insn;
+ {
+   int insn_code_number, i;
+ 
+   /* Ignore things we can not handle.  */
+   if (GET_RTX_CLASS (GET_CODE (insn)) != 'i'
+       || GET_CODE (PATTERN (insn)) == USE
+       || GET_CODE (PATTERN (insn)) == ADDR_VEC
+       || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
+       || asm_noperands (PATTERN (insn)) >= 0)
+     return;
+ 
+   /* Try to recognize the instruction.
+      If successful, verify that the operands satisfy the
+      constraints for the instruction.  Crash if they don't,
+      since `reload' should have changed them so that they do.  */
+ 
+   insn_code_number = recog_memoized (insn);
+   insn_extract (insn);
+   for (i = 0; i < insn_n_operands[insn_code_number]; i++)
+     {
+       if (GET_CODE (recog_operand[i]) == SUBREG)
+         recog_operand[i] = alter_subreg (recog_operand[i]);
+       else if (GET_CODE (recog_operand[i]) == PLUS
+                || GET_CODE (recog_operand[i]) == MULT)
+        recog_operand[i] = walk_alter_subreg (recog_operand[i]);
+     }
+ 
+   for (i = 0; i < insn_n_dups[insn_code_number]; i++)
+     {
+       if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
+         *recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
+       else if (GET_CODE (*recog_dup_loc[i]) == PLUS
+                || GET_CODE (*recog_dup_loc[i]) == MULT)
+         *recog_dup_loc[i] = walk_alter_subreg (*recog_dup_loc[i]);
+     }
+ }
+ 
  /* If X is a SUBREG, replace it with a REG or a MEM,
     based on the thing it is a subreg of.  */
  
*************** alter_subreg (x)
*** 3161,3166 ****
--- 3188,3196 ----
  #else
        REGNO (x) = REGNO (y) + SUBREG_WORD (x);
  #endif
+       /* This field has a different meaning for REGs and SUBREGs.  Make sure
+ 	 to clear it!  */
+       x->used = 0;
      }
    else if (GET_CODE (y) == MEM)
      {
Index: reload1.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload1.c,v
retrieving revision 1.196
diff -c -3 -p -r1.196 reload1.c
*** reload1.c	1998/10/23 05:53:04	1.196
--- reload1.c	1998/10/28 07:15:40
*************** reload (first, global, dumpfile)
*** 1233,1248 ****
      }
  
    /* Make a pass over all the insns and delete all USEs which we inserted
!      only to tag a REG_EQUAL note on them.  Also remove all REG_DEAD and
!      REG_UNUSED notes.  */
  
    for (insn = first; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
        {
  	rtx *pnote;
  
! 	if (GET_CODE (PATTERN (insn)) == USE
! 	    && find_reg_note (insn, REG_EQUAL, NULL_RTX))
  	  {
  	    PUT_CODE (insn, NOTE);
  	    NOTE_SOURCE_FILE (insn) = 0;
--- 1233,1249 ----
      }
  
    /* Make a pass over all the insns and delete all USEs which we inserted
!      only to tag a REG_EQUAL note on them.  Remove all REG_DEAD and REG_UNUSED
!      notes.  Delete all CLOBBER insns and simplify (subreg (reg)) operands.  */
  
    for (insn = first; insn; insn = NEXT_INSN (insn))
      if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
        {
  	rtx *pnote;
  
! 	if ((GET_CODE (PATTERN (insn)) == USE
! 	     && find_reg_note (insn, REG_EQUAL, NULL_RTX))
! 	    || GET_CODE (PATTERN (insn)) == CLOBBER)
  	  {
  	    PUT_CODE (insn, NOTE);
  	    NOTE_SOURCE_FILE (insn) = 0;
*************** reload (first, global, dumpfile)
*** 1259,1264 ****
--- 1260,1268 ----
  	    else
  	      pnote = &XEXP (*pnote, 1);
  	  }
+ 
+ 	/* And simplify (subreg (reg)) if it appears as an operand.  */
+ 	cleanup_subreg_operands (insn);
        }
  
    /* If we are doing stack checking, give a warning if this function's
Index: reload.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reload.h,v
retrieving revision 1.39
diff -c -3 -p -r1.39 reload.h
*** reload.h	1998/10/17 08:31:26	1.39
--- reload.h	1998/10/28 07:15:41
*************** extern void setup_save_areas PROTO((void
*** 338,340 ****
--- 338,343 ----
  
  /* Find the places where hard regs are live across calls and save them.  */
  extern void save_call_clobbered_regs PROTO((void));
+ 
+ /* Replace (subreg (reg)) with the appropriate (reg) for any operands.  */
+ extern void cleanup_subreg_operands PROTO ((rtx));
Index: flow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/flow.c,v
retrieving revision 1.145
diff -c -3 -p -r1.145 flow.c
*** flow.c	1998/10/24 03:33:42	1.145
--- flow.c	1998/10/28 07:15:47
*************** life_analysis_1 (f, nregs)
*** 1340,1362 ****
    if (reload_completed)
      bcopy (regs_ever_live, save_regs_ever_live, (sizeof (regs_ever_live)));
  
-   /* Also remove all CLOBBER insns after reload.  They can cause us to think
-      a value is dead when it really is not dead.  */
-   if (reload_completed)
-     {
-       rtx insn;
- 
-       for (insn = f; insn; insn = NEXT_INSN (insn))
- 	{
- 	  if (GET_CODE (insn) == INSN
- 	      && GET_CODE (PATTERN (insn)) == CLOBBER)
- 	    {
-               PUT_CODE (insn, NOTE);
-               NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
-               NOTE_SOURCE_FILE (insn) = 0;
- 	    }
- 	}
-     }
    bzero (regs_ever_live, sizeof regs_ever_live);
  
    /* Allocate and zero out many data structures
--- 1340,1345 ----


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