This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
reorg versus machine dependednt reorg
- To: gcc-patches at gcc dot gnu dot org
- Subject: reorg versus machine dependednt reorg
- From: Andrew Haley <aph at cambridge dot redhat dot com>
- Date: Wed, 18 Jul 2001 16:21:06 +0100 (BST)
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++)
{