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]

RFA: fix post-call group scheduling to make sh-elf build again


The current mailine fails to build libstdc++-v3 for sh-elf.  We get
a reload failure compiling locale-inst.cc for -m4-single-only .
The first scheduling pass moves the instruction that moves the call
value from a hard to a pseudo register away from the call, which extends
the lifetime of r0 across an instruction with indexed addressing.
The problem is that the call is in a different scheduling region, as
exception handling causes it to end a basic block.
Thus, sched_analyze doesn't see the CALL_INSN during the current region
scheduling, in_post_call_group_p does not get set, and thus the return
value copy instruction doesn't get the SCHED_GROUP_P bit set.

The appended patch fixes this problem by making sched_analyze initialize
in_post_call_group_p appropriately.  It uses a different value than for
ordinary in-region post-call groups because we must not add a dependency
to an instruction in a previous scheduling region.

2004-05-14  J"orn Rennecke <joern.rennecke@superh.com>

	* sched-int.h (in_post_call_group_p): Change type to enum.
	* sched-deps.c (sched_analyze_insn):
	(sched_analyze): When in_post_call_group_p is post_call_initial,
	don't add a dependency, but still set SCHED_GROUP_P and CANT_MOVE,
	and also reset in_post_call_group_p to post_call.
	(sched_analyze): When the previous basic block ended in a CALL_INSN,
	initialize in_post_call_group_p as post_call_initial.
	(init_deps): initialize in_post_call_group_p to not_post_call.
	
Index: sched-deps.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-deps.c,v
retrieving revision 1.72
diff -p -r1.72 sched-deps.c
*** sched-deps.c	25 Mar 2004 00:58:57 -0000	1.72
--- sched-deps.c	14 May 2004 15:10:57 -0000
*************** sched_analyze_insn (struct deps *deps, r
*** 1145,1157 ****
        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;
  	}
      }
  }
--- 1145,1165 ----
        if (src_regno < FIRST_PSEUDO_REGISTER
  	  || dest_regno < FIRST_PSEUDO_REGISTER)
  	{
! 	  /* If we are inside a post-call group right at the start of the
! 	     scheduling region, we must not add a dependency.  */
! 	  if (deps->in_post_call_group_p == post_call_initial)
! 	    {
! 	      SCHED_GROUP_P (insn) = 1;
! 	      deps->in_post_call_group_p = post_call;
! 	    }
! 	  else
! 	    set_sched_group_p (insn);
  	  CANT_MOVE (insn) = 1;
  	}
        else
  	{
  	end_call_group:
! 	  deps->in_post_call_group_p = not_post_call;
  	}
      }
  }
*************** sched_analyze (struct deps *deps, rtx he
*** 1168,1173 ****
--- 1176,1190 ----
    if (current_sched_info->use_cselib)
      cselib_init (true);
  
+   /* Before reload, if the previous block ended in a call, show that
+      we are inside a post-call group, so as to keep the lifetimes of
+      hard registers correct.  */
+   if (! reload_completed && GET_CODE (head) != CODE_LABEL)
+     {
+       insn = prev_nonnote_insn (head);
+       if (insn && GET_CODE (insn) == CALL_INSN)
+ 	deps->in_post_call_group_p = post_call_initial;
+     }
    for (insn = head;; insn = NEXT_INSN (insn))
      {
        rtx link, end_seq, r0, set;
*************** sched_analyze (struct deps *deps, rtx he
*** 1259,1265 ****
  	  /* Before reload, begin a post-call group, so as to keep the
  	     lifetimes of hard registers correct.  */
  	  if (! reload_completed)
! 	    deps->in_post_call_group_p = true;
  	}
  
        /* See comments on reemit_notes as to why we do this.
--- 1276,1282 ----
  	  /* Before reload, begin a post-call group, so as to keep the
  	     lifetimes of hard registers correct.  */
  	  if (! reload_completed)
! 	    deps->in_post_call_group_p = post_call;
  	}
  
        /* See comments on reemit_notes as to why we do this.
*************** init_deps (struct deps *deps)
*** 1420,1426 ****
    deps->last_pending_memory_flush = 0;
    deps->last_function_call = 0;
    deps->sched_before_next_call = 0;
!   deps->in_post_call_group_p = false;
    deps->libcall_block_tail_insn = 0;
  }
  
--- 1437,1443 ----
    deps->last_pending_memory_flush = 0;
    deps->last_function_call = 0;
    deps->sched_before_next_call = 0;
!   deps->in_post_call_group_p = not_post_call;
    deps->libcall_block_tail_insn = 0;
  }
  
Index: sched-int.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/sched-int.h,v
retrieving revision 1.32
diff -p -r1.32 sched-int.h
*** sched-int.h	23 Feb 2004 17:02:50 -0000	1.32
--- sched-int.h	14 May 2004 15:10:57 -0000
*************** struct deps
*** 84,90 ****
  
    /* Used to keep post-call pseudo/hard reg movements together with
       the call.  */
!   bool in_post_call_group_p;
  
    /* Set to the tail insn of the outermost libcall block.
  
--- 84,90 ----
  
    /* Used to keep post-call pseudo/hard reg movements together with
       the call.  */
!   enum { not_post_call, post_call, post_call_initial } in_post_call_group_p;
  
    /* Set to the tail insn of the outermost libcall block.
  


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