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]

reorg versus machine dependednt reorg


On the SH, we very carefully make sure that conditional branches
(which have only a short displacement) can reach their targets; we
replace others with combinations of conditional branches and jump
instructions.  This all happens in machine dependent reorg.

Then, along comes reorg to fill delay slots and while it's doing that
it redirects some of our oh-so-carefully positioned branches to point
to other places, and if these new branches happen to be out of range
we're SNAFUd.

reorg needs to be told that sometimes it can't move a branch, however
much it might want to.

This patch adds a new target macro that is passed two branch insns.
It returns true if it's possible to redirect branch insn 1 to the
target of branch insn 2.

Andrew.

2001-07-13  Andrew Haley  <aph@cambridge.redhat.com>

        * doc/tm.texi (MD_CAN_REDIRECT_BRANCH): New macro.
        * config/sh/sh.h (MD_CAN_REDIRECT_BRANCH): New macro.
        * config/sh/sh.c (sh_can_redirect_branch): New function.
        * reorg.c (steal_delay_list_from_target): Use
        MD_CAN_REDIRECT_BRANCH to see if redirection is possible.

Index: doc/tm.texi
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/doc/tm.texi,v
retrieving revision 1.4
diff -p -2 -c -r1.4 tm.texi
*** tm.texi	2001/07/05 22:55:18	1.4
--- tm.texi	2001/07/18 14:58:54
*************** is to be ignored.
*** 8727,8729 ****
--- 8727,8740 ----
  This macro should return the result of the call to the built-in function.
  
+ @findex MD_CAN_REDIRECT_BRANCH
+ @item MD_CAN_REDIRECT_BRANCH(@var{branch1}, @var{branch2})
+ 
+ Take a branch insn in @var{branch1} and a another in @var{branch2}.
+ Return true if redirecting @var{branch1} to the destination of
+ @var{branch2} is possible.
+ 
+ On some targets, branches may have a limited range.  Optimizing the
+ filling of delay slots can result in branches being redirected, and this
+ may in turn cause a branch offset to overflow.
+ 
  @end table
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/sh/sh.h,v
retrieving revision 1.274
diff -p -2 -c -r1.274 sh.h
*** sh.h	2001/07/02 13:37:29	1.274
--- sh.h	2001/07/18 14:58:57
*************** do {									\
*** 3852,3855 ****
--- 3853,3859 ----
  #define EMIT_MODE_SET(ENTITY, MODE, HARD_REGS_LIVE) \
    fpscr_set_from_mem ((MODE), (HARD_REGS_LIVE))
+ 
+ #define MD_CAN_REDIRECT_BRANCH(INSN, SEQ) \
+   sh_can_redirect_branch ((INSN), (SEQ))
  
  #define DWARF_LINE_MIN_INSTR_LENGTH 2
Index: config/sh/sh.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/config/sh/sh.c,v
retrieving revision 1.239
diff -p -2 -c -r1.239 sh.c
*** sh.c	2001/07/02 13:37:29	1.239
--- sh.c	2001/07/18 14:59:03
*************** static rtx mark_constant_pool_use (x)
*** 6759,6760 ****
--- 6766,6804 ----
    return lab;
  }
+ 
+ /* Return true if it's possible to redirect BRANCH1 to the destination
+    of an unconditional jump BRANCH2.  We only want to do this if the
+    resulting branch will have a short displacement.  */
+ int 
+ sh_can_redirect_branch (branch1, branch2)
+      rtx branch1;
+      rtx branch2;
+ {
+   if (flag_expensive_optimizations && simplejump_p (branch2))
+     {
+       rtx dest = XEXP (SET_SRC (single_set (branch2)), 0);
+       rtx insn;
+       int distance;
+       
+       for (distance = 0, insn = NEXT_INSN (branch1); 
+ 	   insn && distance < 256; 
+ 	   insn = PREV_INSN (insn))
+ 	{
+ 	  if (insn == dest)    
+ 	    return 1;
+ 	  else
+ 	    distance += get_attr_length (insn);
+ 	}
+       for (distance = 0, insn = NEXT_INSN (branch1); 
+ 	   insn && distance < 256; 
+ 	   insn = NEXT_INSN (insn))
+ 	{
+ 	  if (insn == dest)    
+ 	    return 1;
+ 	  else
+ 	    distance += get_attr_length (insn);
+ 	}
+     }
+   return 0;
+ }
+ 
Index: reorg.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/reorg.c,v
retrieving revision 1.127
diff -p -2 -c -r1.127 reorg.c
*** reorg.c	2001/04/30 22:37:16	1.127
--- reorg.c	2001/07/18 15:00:07
*************** steal_delay_list_from_target (insn, cond
*** 1273,1276 ****
--- 1273,1284 ----
      return delay_list;
  
+ #ifdef MD_CAN_REDIRECT_BRANCH
+   /* On some targets, branches with delay slots can have a limited
+      displacement.  Give the back end a chance to tell us we can't do
+      this.  */
+   if (! MD_CAN_REDIRECT_BRANCH (insn, XVECEXP (seq, 0, 0)))
+     return delay_list;
+ #endif
+ 
    for (i = 1; i < XVECLEN (seq, 0); i++)
      {


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