diff options
author | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-07-23 16:00:06 +0000 |
---|---|---|
committer | aph <aph@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-07-23 16:00:06 +0000 |
commit | e95ebfe01248c88832e21726accb01321f20a61e (patch) | |
tree | ef220d1f1710bdd39aaddf1da18b1709fc794695 | |
parent | 40be2320a3646ff02c2caa7459eaccdce2b5c2f4 (diff) | |
download | gcc-e95ebfe01248c88832e21726accb01321f20a61e.tar.gz |
2001-07-13 Andrew Haley <aph@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.
* config/sh/sh-protos.h (sh_can_redirect_branch): Declare.
* reorg.c (steal_delay_list_from_target): Use
MD_CAN_REDIRECT_BRANCH to see if redirection is possible.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44269 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/sh/sh-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/sh/sh.c | 37 | ||||
-rw-r--r-- | gcc/config/sh/sh.h | 3 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 11 | ||||
-rw-r--r-- | gcc/reorg.c | 8 |
6 files changed, 69 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 642408d7876..b49083981f8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2001-07-13 Andrew Haley <aph@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. + * config/sh/sh-protos.h (sh_can_redirect_branch): Declare. + * reorg.c (steal_delay_list_from_target): Use + MD_CAN_REDIRECT_BRANCH to see if redirection is possible. + Mon Jul 23 17:20:18 CEST 2001 Jan Hubicka <jh@suse.cz> * flow.c (try_simplify_condjump): Unlink insn chain on diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h index 1200ba2f41a..f11f2e2f74b 100644 --- a/gcc/config/sh/sh-protos.h +++ b/gcc/config/sh/sh-protos.h @@ -98,6 +98,7 @@ extern void expand_df_unop PARAMS ((rtx (*)(rtx, rtx, rtx), rtx *)); extern void expand_df_binop PARAMS ((rtx (*)(rtx, rtx, rtx, rtx), rtx *)); extern void expand_fp_branch PARAMS ((rtx (*)(void), rtx (*)(void))); extern int sh_insn_length_adjustment PARAMS ((rtx)); +extern int sh_can_redirect_branch PARAMS ((rtx, rtx)); #ifdef TREE_CODE extern void sh_va_start PARAMS ((int, tree, rtx)); extern rtx sh_va_arg PARAMS ((tree, tree)); diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 18e6379fd60..ec09d08b666 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -5515,3 +5515,40 @@ static rtx mark_constant_pool_use (x) 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; +} + diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h index f72c07c9fbe..cc17258353f 100644 --- a/gcc/config/sh/sh.h +++ b/gcc/config/sh/sh.h @@ -2421,6 +2421,9 @@ do { \ #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 /* SH constant pool breaks the devices in crtstuff.c to control section diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index b5d8ba92d4d..81a55828c2e 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -8681,4 +8681,15 @@ ignored. This function should return the result of the call to the built-in function. @end deftypefn +@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 diff --git a/gcc/reorg.c b/gcc/reorg.c index 1f26e7e3751..3177e7117dd 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -1272,6 +1272,14 @@ steal_delay_list_from_target (insn, condition, seq, delay_list, || ! single_set (XVECEXP (seq, 0, 0))) 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++) { rtx trial = XVECEXP (seq, 0, i); |