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]

Proposed fix for 3.1 branch


RTH and I were discussing the bug in compiling ada/make.adb for ia64 and
came up with this as the best solution for 3.1.  There is another solution
proposed for 3.2 which I don't fully understand.

Although this is not a regression, we both feel it's safe enough for the
branch and is important since it fixes a code generation problem (the restore
of GP after a call may be scheduled after insns that use it).

Is this OK for the branch?

Tue May 28 08:04:58 2002  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* sched-deps.c (sched_analyze_insn): Move post-barrier handling
	before reg_pending_barrier handling and set reg_pending_barrier if
	call was in previous basic block.
	(sched_analyze): If insn before this basic block is a CALL_INSN,
	set in_post_call_group_p and (new) cal_in_previous_bb_p.
	(init_deps): Initialize call_in_previous_bb_p.
	* sched-int.h (struct deps): New field call_in_previous_bb_p.

*** sched-deps.c	19 Feb 2002 02:53:10 -0000	1.34
--- sched-deps.c	27 May 2002 15:59:20 -0000
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1038,1041 ****
--- 1038,1093 ----
      reg_pending_barrier = true;
  
+   /* If a post-call group is still open, see if it should remain so.
+      This insn must be a simple move of a hard reg to a pseudo or
+      vice-versa.
+ 
+      We must avoid moving these insns for correctness on
+      SMALL_REGISTER_CLASS machines, and for special registers like
+      PIC_OFFSET_TABLE_REGNUM.  For simplicity, extend this to all
+      hard regs for all targets.  */
+ 
+   if (deps->in_post_call_group_p)
+     {
+       rtx tmp, set = single_set (insn);
+       int src_regno, dest_regno;
+ 
+       if (set == NULL)
+ 	goto end_call_group;
+ 
+       tmp = SET_DEST (set);
+       if (GET_CODE (tmp) == SUBREG)
+ 	tmp = SUBREG_REG (tmp);
+       if (GET_CODE (tmp) == REG)
+ 	dest_regno = REGNO (tmp);
+       else
+ 	goto end_call_group;
+ 
+       tmp = SET_SRC (set);
+       if (GET_CODE (tmp) == SUBREG)
+ 	tmp = SUBREG_REG (tmp);
+       if (GET_CODE (tmp) == REG)
+ 	src_regno = REGNO (tmp);
+       else
+ 	goto end_call_group;
+ 
+       if (src_regno < FIRST_PSEUDO_REGISTER
+ 	  || dest_regno < FIRST_PSEUDO_REGISTER)
+ 	{
+ 	  if (! deps->call_in_previous_bb_p)
+ 	    {
+ 	      set_sched_group_p (insn);
+ 	      CANT_MOVE (insn) = 1;
+ 	    }
+ 	  else
+ 	    reg_pending_barrier = true;
+ 	}
+       else
+ 	{
+ 	end_call_group:
+ 	  deps->in_post_call_group_p = false;
+ 	  deps->call_in_previous_bb_p = false;
+ 	}
+     }
+ 
    /* Add dependencies if a scheduling barrier was found.  */
    if (reg_pending_barrier)
*************** sched_analyze_insn (deps, x, insn, loop_
*** 1163,1212 ****
    CLEAR_REG_SET (reg_pending_clobbers);
    CLEAR_REG_SET (reg_pending_sets);
- 
-   /* If a post-call group is still open, see if it should remain so.
-      This insn must be a simple move of a hard reg to a pseudo or
-      vice-versa.
- 
-      We must avoid moving these insns for correctness on
-      SMALL_REGISTER_CLASS machines, and for special registers like
-      PIC_OFFSET_TABLE_REGNUM.  For simplicity, extend this to all
-      hard regs for all targets.  */
- 
-   if (deps->in_post_call_group_p)
-     {
-       rtx tmp, set = single_set (insn);
-       int src_regno, dest_regno;
- 
-       if (set == NULL)
- 	goto end_call_group;
- 
-       tmp = SET_DEST (set);
-       if (GET_CODE (tmp) == SUBREG)
- 	tmp = SUBREG_REG (tmp);
-       if (GET_CODE (tmp) == REG)
- 	dest_regno = REGNO (tmp);
-       else
- 	goto end_call_group;
- 
-       tmp = SET_SRC (set);
-       if (GET_CODE (tmp) == SUBREG)
- 	tmp = SUBREG_REG (tmp);
-       if (GET_CODE (tmp) == REG)
- 	src_regno = REGNO (tmp);
-       else
- 	goto end_call_group;
- 
-       if (src_regno < FIRST_PSEUDO_REGISTER
- 	  || dest_regno < FIRST_PSEUDO_REGISTER)
- 	{
- 	  set_sched_group_p (insn);
- 	  CANT_MOVE (insn) = 1;
- 	}
-       else
- 	{
- 	end_call_group:
- 	  deps->in_post_call_group_p = false;
- 	}
-     }
  }
  
--- 1215,1218 ----
*************** sched_analyze (deps, head, tail)
*** 1225,1228 ****
--- 1231,1243 ----
      cselib_init ();
  
+   /* If the last real insn is a CALL_INSN, say we are in the post-call
+      group.  */
+   if (prev_real_insn (head) != 0
+       && GET_CODE (prev_real_insn (head)) == CALL_INSN)
+     {
+       deps->in_post_call_group_p = true;
+       deps->call_in_previous_bb_p = true;
+     }
+ 
    for (insn = head;; insn = NEXT_INSN (insn))
      {
*************** init_deps (deps)
*** 1450,1453 ****
--- 1465,1469 ----
    deps->sched_before_next_call = 0;
    deps->in_post_call_group_p = false;
+   deps->call_in_previous_bb_p = false;
  }
  
*** sched-int.h	28 Feb 2002 18:29:07 -0000	1.18.2.1
--- sched-int.h	27 May 2002 15:59:20 -0000
*************** struct deps
*** 83,86 ****
--- 83,87 ----
       the call.  */
    bool in_post_call_group_p;
+   bool call_in_previous_bb_p;
  
    /* The maximum register number for the following arrays.  Before reload
  


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