This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Blackfin: Fix dataflow breakage
- From: Bernd Schmidt <bernds_cb1 at t-online dot de>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 13 Jun 2007 16:22:56 +0200
- Subject: Re: Blackfin: Fix dataflow breakage
- References: <466EAFD9.1050100@t-online.de>
Bernd Schmidt wrote:
> Someone had already done half a conversion on the Blackfin port, but
> clearly not compile tested it.
>
> Rather than try and teach the df framework about SEQUENCE insns which we
> previously used to represent a bundle of three parallel instructions,
> I've decided to just leave them in the insn stream as is and rely on the
> fact that nothing runs after machine_reorg that could reorder them. I
> needed to add a new function to remove var tracking notes from in
> between these insns, since the assembler chokes if it finds labels in
> the middle of an insn.
Here's a followup patch, committed as 125677. With parallel insns no
longer represented as a SEQUENCE, the anomaly workaround code needs to
be taught to look at three consecutive insns as a unit in these cases.
Also, a bit of warning cleanup.
Bernd
--
This footer brought to you by insane German lawmakers.
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: ChangeLog
===================================================================
--- ChangeLog (revision 125676)
+++ ChangeLog (working copy)
@@ -1,3 +1,10 @@
+2007-06-13 Bernd Schmidt <bernd.schmidt@analog.com>
+
+ * config/bfin/bfin.c (gen_one_bundle): Delete unused local variables.
+ (find_next_insn_start, find_load): New functions.
+ (bfin_reorg): Use them to deal with the fact that parallel insns are
+ no longer represented as a SEQUENCE.
+
2007-06-13 Eric Botcazou <ebotcazou@libertysurf.fr>
* config/sparc/sparc.c (sparc_override_options): Initialize
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c (revision 125648)
+++ config/bfin/bfin.c (working copy)
@@ -4089,8 +4089,6 @@ bfin_reorg_loops (FILE *dump_file)
static bool
gen_one_bundle (rtx slot[3])
{
- rtx bundle, insn;
-
gcc_assert (slot[1] != NULL_RTX);
/* Verify that we really can do the multi-issue. */
@@ -4309,6 +4307,39 @@ trapping_loads_p (rtx insn)
return may_trap_p (SET_SRC (single_set (insn)));
}
+/* This function acts like NEXT_INSN, but is aware of three-insn bundles and
+ skips all subsequent parallel instructions if INSN is the start of such
+ a group. */
+static rtx
+find_next_insn_start (rtx insn)
+{
+ if (GET_MODE (insn) == SImode)
+ {
+ while (GET_MODE (insn) != QImode)
+ insn = NEXT_INSN (insn);
+ }
+ return NEXT_INSN (insn);
+}
+
+/* Return INSN if it is of TYPE_MCLD. Alternatively, if INSN is the start of
+ a three-insn bundle, see if one of them is a load and return that if so.
+ Return NULL_RTX if the insn does not contain loads. */
+static rtx
+find_load (rtx insn)
+{
+ if (get_attr_type (insn) == TYPE_MCLD)
+ return insn;
+ if (GET_MODE (insn) != SImode)
+ return NULL_RTX;
+ do {
+ insn = NEXT_INSN (insn);
+ if ((GET_MODE (insn) == SImode || GET_MODE (insn) == QImode)
+ && get_attr_type (insn) == TYPE_MCLD)
+ return insn;
+ } while (GET_MODE (insn) != QImode);
+ return NULL_RTX;
+}
+
/* We use the machine specific reorg pass for emitting CSYNC instructions
after conditional branches as needed.
@@ -4332,7 +4363,8 @@ trapping_loads_p (rtx insn)
static void
bfin_reorg (void)
{
- rtx insn, last_condjump = NULL_RTX;
+ rtx insn, next;
+ rtx last_condjump = NULL_RTX;
int cycles_since_jump = INT_MAX;
/* We are freeing block_for_insn in the toplev to keep compatibility
@@ -4365,10 +4397,12 @@ bfin_reorg (void)
/* First pass: find predicted-false branches; if something after them
needs nops, insert them or change the branch to predict true. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+ for (insn = get_insns (); insn; insn = next)
{
rtx pat;
+ next = find_next_insn_start (insn);
+
if (NOTE_P (insn) || BARRIER_P (insn) || LABEL_P (insn))
continue;
@@ -4391,14 +4425,15 @@ bfin_reorg (void)
}
else if (INSN_P (insn))
{
+ rtx load_insn = find_load (insn);
enum attr_type type = type_for_anomaly (insn);
int delay_needed = 0;
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
- if (type == TYPE_MCLD && TARGET_SPECLD_ANOMALY)
+ if (load_insn && TARGET_SPECLD_ANOMALY)
{
- if (trapping_loads_p (insn))
+ if (trapping_loads_p (load_insn))
delay_needed = 3;
}
else if (type == TYPE_SYNC && TARGET_CSYNC_ANOMALY)