summaryrefslogtreecommitdiff
path: root/gcc/sched-deps.c
diff options
context:
space:
mode:
authorwmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-03 18:35:24 +0000
committerwmi <wmi@138bc75d-0d04-0410-961f-82ee72b054a4>2013-12-03 18:35:24 +0000
commit55e7138cdaa04363ca119981c56e2f0d03055f64 (patch)
treec7fa75151c5a9cc592c2871ba91390f22dffed86 /gcc/sched-deps.c
parent80d4fcdca426fb9dea2207619c775110969ab97e (diff)
downloadgcc-55e7138cdaa04363ca119981c56e2f0d03055f64.tar.gz
2013-12-03 Wei Mi <wmi@google.com>
PR rtl-optimization/59020 * sched-deps.c (try_group_insn): Move it from haifa-sched.c to here. (sched_analyze_insn): Call try_group_insn. (sched_analyze): Cleanup SCHED_GROUP_P before start the analysis. * haifa-sched.c (try_group_insn): Moved to sched-deps.c. (group_insns_for_macro_fusion): Removed. (sched_init): Remove calling group_insns_for_macro_fusion. 2013-12-03 Wei Mi <wmi@google.com> PR rtl-optimization/59020 * testsuite/gcc.dg/pr59020.c: New. * testsuite/gcc.dg/macro-fusion-1.c: New. * testsuite/gcc.dg/macro-fusion-2.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@205644 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/sched-deps.c')
-rw-r--r--gcc/sched-deps.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 287b826cfc6..f818a83ea2e 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2820,6 +2820,37 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx insn)
sched_deps_info->finish_rhs ();
}
+/* Try to group comparison and the following conditional jump INSN if
+ they're already adjacent. This is to prevent scheduler from scheduling
+ them apart. */
+
+static void
+try_group_insn (rtx insn)
+{
+ unsigned int condreg1, condreg2;
+ rtx cc_reg_1;
+ rtx prev;
+
+ if (!any_condjump_p (insn))
+ return;
+
+ targetm.fixed_condition_code_regs (&condreg1, &condreg2);
+ cc_reg_1 = gen_rtx_REG (CCmode, condreg1);
+ prev = prev_nonnote_nondebug_insn (insn);
+ if (!reg_referenced_p (cc_reg_1, PATTERN (insn))
+ || !prev
+ || !modified_in_p (cc_reg_1, prev))
+ return;
+
+ /* Different microarchitectures support macro fusions for different
+ combinations of insn pairs. */
+ if (!targetm.sched.macro_fusion_pair_p
+ || !targetm.sched.macro_fusion_pair_p (prev, insn))
+ return;
+
+ SCHED_GROUP_P (insn) = 1;
+}
+
/* Analyze an INSN with pattern X to find all dependencies. */
static void
sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
@@ -2843,6 +2874,11 @@ sched_analyze_insn (struct deps_desc *deps, rtx x, rtx insn)
can_start_lhs_rhs_p = (NONJUMP_INSN_P (insn)
&& code == SET);
+ /* Group compare and branch insns for macro-fusion. */
+ if (targetm.sched.macro_fusion_p
+ && targetm.sched.macro_fusion_p ())
+ try_group_insn (insn);
+
if (may_trap_p (x))
/* Avoid moving trapping instructions across function calls that might
not always return. */
@@ -3733,6 +3769,10 @@ sched_analyze (struct deps_desc *deps, rtx head, rtx tail)
{
/* And initialize deps_lists. */
sd_init_insn (insn);
+ /* Clean up SCHED_GROUP_P which may be set by last
+ scheduler pass. */
+ if (SCHED_GROUP_P (insn))
+ SCHED_GROUP_P (insn) = 0;
}
deps_analyze_insn (deps, insn);