aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleg Endo <olegendo@gcc.gnu.org>2014-12-17 22:52:21 +0000
committerOleg Endo <olegendo@gcc.gnu.org>2014-12-17 22:52:21 +0000
commitff49a9ba7b528078691a9f4e811bcdd4e9f99cdd (patch)
tree0933652a8f697fda312a9852cba33b84ad34e166
parent64e6d5c44231696ec9212101d099427e9214203a (diff)
downloadgcc-ff49a9ba7b528078691a9f4e811bcdd4e9f99cdd.zip
gcc-ff49a9ba7b528078691a9f4e811bcdd4e9f99cdd.tar.gz
gcc-ff49a9ba7b528078691a9f4e811bcdd4e9f99cdd.tar.bz2
re PR target/51244 ([SH] Inefficient conditional branch and code around T bit)
gcc/ PR target/51244 * config/sh/sh_treg_combine.cc (sh_treg_combine::try_optimize_cbranch): Combine ccreg inversion and cbranch into inverted cbranch. From-SVN: r218847
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/sh/sh_treg_combine.cc23
2 files changed, 28 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 87940a2..00b3728 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-17 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh_treg_combine.cc (sh_treg_combine::try_optimize_cbranch):
+ Combine ccreg inversion and cbranch into inverted cbranch.
+
2014-12-17 Vladimir Makarov <vmakarov@redhat.com>
* lra-constraints.c (process_alt_operands): Remove non
diff --git a/gcc/config/sh/sh_treg_combine.cc b/gcc/config/sh/sh_treg_combine.cc
index 68c7fc1..62392d8 100644
--- a/gcc/config/sh/sh_treg_combine.cc
+++ b/gcc/config/sh/sh_treg_combine.cc
@@ -1339,9 +1339,17 @@ sh_treg_combine::try_optimize_cbranch (rtx_insn *insn)
// for now we limit the search to the current basic block.
trace.setcc = find_set_of_reg_bb (m_ccreg, prev_nonnote_insn_bb (insn));
- if (!is_cmp_eq_zero (trace.setcc.set_src ()))
+ if (trace.setcc.set_src () == NULL_RTX)
log_return_void ("could not find set of ccreg in current BB\n");
+ if (!is_cmp_eq_zero (trace.setcc.set_src ())
+ && !is_inverted_ccreg (trace.setcc.set_src ()))
+ {
+ log_msg ("unsupported set of ccreg in current BB: ");
+ log_rtx (trace.setcc.set_src ());
+ log_return_void ("\n");
+ }
+
rtx trace_reg = XEXP (trace.setcc.set_src (), 0);
log_msg ("set of ccreg:\n");
@@ -1358,6 +1366,19 @@ sh_treg_combine::try_optimize_cbranch (rtx_insn *insn)
log_return_void ("\nbecause it's volatile\n");
}
+ // If the ccreg is inverted before cbranch try inverting the branch
+ // condition.
+ if (is_inverted_ccreg (trace.setcc.set_src ()))
+ {
+ if (!trace.can_invert_condition ())
+ log_return_void ("branch condition can't be inverted - aborting\n");
+
+ if (try_invert_branch_condition (trace))
+ delete_insn (trace.setcc.insn);
+
+ return;
+ }
+
// Now that we have an insn which tests some reg and sets the condition
// reg before the conditional branch, try to figure out how that tested
// reg was formed, i.e. find all the insns that set the tested reg in