diff options
author | Bin Cheng <bin.cheng@arm.com> | 2013-09-18 02:01:07 +0000 |
---|---|---|
committer | Bin Cheng <amker@gcc.gnu.org> | 2013-09-18 02:01:07 +0000 |
commit | 3b3cc26bcc127eceeb6d257313555fc2149cf6d4 (patch) | |
tree | 9370908234dca1d39c9210241fe1b059ef0b395f /gcc | |
parent | b5ba3a9b55ea2462b54b5fcd14476182e3f93fe4 (diff) | |
download | gcc-3b3cc26bcc127eceeb6d257313555fc2149cf6d4.zip gcc-3b3cc26bcc127eceeb6d257313555fc2149cf6d4.tar.gz gcc-3b3cc26bcc127eceeb6d257313555fc2149cf6d4.tar.bz2 |
arm.c (thumb1_reorg): Search for flag setting insn before branch in same basic block.
* config/arm/arm.c (thumb1_reorg): Search for flag setting insn
before branch in same basic block. Check both src and dest of
the move insn.
From-SVN: r202678
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 38 |
2 files changed, 32 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d2c79a1..3524ca8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-09-18 Bin Cheng <bin.cheng@arm.com> + + * config/arm/arm.c (thumb1_reorg): Search for flag setting insn + before branch in same basic block. Check both src and dest of + the move insn. + 2013-09-17 Nick Clifton <nickc@redhat.com> * config/rl78/rl78-real.md (bf): New pattern. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f9027dd..176f719 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -14265,9 +14265,10 @@ thumb1_reorg (void) FOR_EACH_BB (bb) { - rtx set, dest, src; - rtx pat, op0; + rtx dest, src; + rtx pat, op0, set = NULL; rtx prev, insn = BB_END (bb); + bool insn_clobbered = false; while (insn != BB_HEAD (bb) && DEBUG_INSN_P (insn)) insn = PREV_INSN (insn); @@ -14276,13 +14277,29 @@ thumb1_reorg (void) if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn) continue; - /* Find the first non-note insn before INSN in basic block BB. */ + /* Get the register with which we are comparing. */ + pat = PATTERN (insn); + op0 = XEXP (XEXP (SET_SRC (pat), 0), 0); + + /* Find the first flag setting insn before INSN in basic block BB. */ gcc_assert (insn != BB_HEAD (bb)); - prev = PREV_INSN (insn); - while (prev != BB_HEAD (bb) && (NOTE_P (prev) || DEBUG_INSN_P (prev))) - prev = PREV_INSN (prev); + for (prev = PREV_INSN (insn); + (!insn_clobbered + && prev != BB_HEAD (bb) + && (NOTE_P (prev) + || DEBUG_INSN_P (prev) + || ((set = single_set (prev)) != NULL + && get_attr_conds (prev) == CONDS_NOCOND))); + prev = PREV_INSN (prev)) + { + if (reg_set_p (op0, prev)) + insn_clobbered = true; + } + + /* Skip if op0 is clobbered by insn other than prev. */ + if (insn_clobbered) + continue; - set = single_set (prev); if (!set) continue; @@ -14292,12 +14309,9 @@ thumb1_reorg (void) || !low_register_operand (src, SImode)) continue; - pat = PATTERN (insn); - op0 = XEXP (XEXP (SET_SRC (pat), 0), 0); /* Rewrite move into subtract of 0 if its operand is compared with ZERO - in INSN. Don't need to check dest since cprop_hardreg pass propagates - src into INSN. */ - if (REGNO (op0) == REGNO (src)) + in INSN. Both src and dest of the move insn are checked. */ + if (REGNO (op0) == REGNO (src) || REGNO (op0) == REGNO (dest)) { dest = copy_rtx (dest); src = copy_rtx (src); |