95 lines
2.9 KiB
Diff
95 lines
2.9 KiB
Diff
2014-08-14 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR target/62025
|
|
* sched-deps.c (find_inc): Limit the test for inc_insn defs
|
|
vs. mem_insn uses to !backwards case only. Give up also if
|
|
any mem_insn def is used by inc_insn or if non-clobber
|
|
mem_insn def in backwards case is clobbered by inc_insn.
|
|
|
|
--- gcc/sched-deps.c.jj 2014-08-12 17:06:26.000000000 +0200
|
|
+++ gcc/sched-deps.c 2014-08-14 00:09:38.000000000 +0200
|
|
@@ -4746,23 +4746,70 @@ find_inc (struct mem_inc_info *mii, bool
|
|
"inc conflicts with store failure.\n");
|
|
goto next;
|
|
}
|
|
+ else
|
|
+ {
|
|
+ df_ref *use_rec, *def2_rec;
|
|
+ for (use_rec = DF_INSN_USES (mii->inc_insn);
|
|
+ *use_rec; use_rec++)
|
|
+ {
|
|
+ df_ref use = *use_rec;
|
|
+ if (reg_overlap_mentioned_p (DF_REF_REG (def),
|
|
+ DF_REF_REG (use)))
|
|
+ {
|
|
+ if (sched_verbose >= 5)
|
|
+ fprintf (sched_dump,
|
|
+ "mem def conflict with inc use "
|
|
+ "failure.\n");
|
|
+ goto next;
|
|
+ }
|
|
+ }
|
|
+ /* If both inc_insn and mem_insn clobber the same register,
|
|
+ it is fine, but avoid the case where mem_insn e.g.
|
|
+ sets CC and originally earlier inc_insn clobbers it. */
|
|
+ if ((DF_REF_FLAGS (def) & DF_REF_MUST_CLOBBER) == 0
|
|
+ && backwards)
|
|
+ for (def2_rec = DF_INSN_DEFS (mii->inc_insn);
|
|
+ *def2_rec; def2_rec++)
|
|
+ {
|
|
+ df_ref def2 = *def2_rec;
|
|
+ if (reg_overlap_mentioned_p (DF_REF_REG (def),
|
|
+ DF_REF_REG (def2)))
|
|
+ {
|
|
+ if (sched_verbose >= 5)
|
|
+ fprintf (sched_dump,
|
|
+ "mem def conflict with inc def "
|
|
+ "failure.\n");
|
|
+ goto next;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
/* The inc instruction could have clobbers, make sure those
|
|
- registers are not used in mem insn. */
|
|
- for (def_rec = DF_INSN_DEFS (mii->inc_insn); *def_rec; def_rec++)
|
|
- if (!reg_overlap_mentioned_p (DF_REF_REG (*def_rec), mii->mem_reg0))
|
|
+ registers are not used in mem insn, if mem_insn is originally
|
|
+ earlier than inc_insn. */
|
|
+ if (!backwards)
|
|
+ for (def_rec = DF_INSN_DEFS (mii->inc_insn); *def_rec; def_rec++)
|
|
{
|
|
- df_ref *use_rec;
|
|
- for (use_rec = DF_INSN_USES (mii->mem_insn); *use_rec; use_rec++)
|
|
- if (reg_overlap_mentioned_p (DF_REF_REG (*def_rec),
|
|
- DF_REF_REG (*use_rec)))
|
|
- {
|
|
- if (sched_verbose >= 5)
|
|
- fprintf (sched_dump,
|
|
- "inc clobber used in store failure.\n");
|
|
- goto next;
|
|
- }
|
|
+ df_ref def = *def_rec;
|
|
+ if (!reg_overlap_mentioned_p (DF_REF_REG (def), mii->mem_reg0))
|
|
+ {
|
|
+ df_ref *use_rec;
|
|
+ for (use_rec = DF_INSN_USES (mii->mem_insn);
|
|
+ *use_rec; use_rec++)
|
|
+ {
|
|
+ df_ref use = *use_rec;
|
|
+ if (reg_overlap_mentioned_p (DF_REF_REG (def),
|
|
+ DF_REF_REG (use)))
|
|
+ {
|
|
+ if (sched_verbose >= 5)
|
|
+ fprintf (sched_dump,
|
|
+ "inc def conflict with mem use "
|
|
+ "failure.\n");
|
|
+ goto next;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
newaddr = mii->inc_input;
|