aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-im.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-loop-im.c')
-rw-r--r--gcc/tree-ssa-loop-im.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 8034cf6..1c865b2 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -2169,6 +2169,7 @@ execute_sm (class loop *loop, im_mem_ref *ref,
enum sm_kind { sm_ord, sm_unord, sm_other };
struct seq_entry
{
+ seq_entry () {}
seq_entry (unsigned f, sm_kind k, tree fr = NULL)
: first (f), second (k), from (fr) {}
unsigned first;
@@ -2352,6 +2353,8 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
unsigned min_len = MIN(first_edge_seq.length (),
edge_seq.length ());
/* Incrementally merge seqs into first_edge_seq. */
+ int first_uneq = -1;
+ auto_vec<seq_entry, 2> extra_refs;
for (unsigned int i = 0; i < min_len; ++i)
{
/* ??? We can more intelligently merge when we face different
@@ -2367,6 +2370,11 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
bitmap_set_bit (refs_not_supported, edge_seq[i].first);
first_edge_seq[i].second = sm_other;
first_edge_seq[i].from = NULL_TREE;
+ /* Record the dropped refs for later processing. */
+ if (first_uneq == -1)
+ first_uneq = i;
+ extra_refs.safe_push (seq_entry (edge_seq[i].first,
+ sm_other, NULL_TREE));
}
/* sm_other prevails. */
else if (first_edge_seq[i].second != edge_seq[i].second)
@@ -2399,10 +2407,36 @@ sm_seq_valid_bb (class loop *loop, basic_block bb, tree vdef,
}
else if (edge_seq.length () > first_edge_seq.length ())
{
+ if (first_uneq == -1)
+ first_uneq = first_edge_seq.length ();
for (unsigned i = first_edge_seq.length ();
i < edge_seq.length (); ++i)
- if (edge_seq[i].second == sm_ord)
- bitmap_set_bit (refs_not_supported, edge_seq[i].first);
+ {
+ if (edge_seq[i].second == sm_ord)
+ bitmap_set_bit (refs_not_supported, edge_seq[i].first);
+ extra_refs.safe_push (seq_entry (edge_seq[i].first,
+ sm_other, NULL_TREE));
+ }
+ }
+ /* Put unmerged refs at first_uneq to force dependence checking
+ on them. */
+ if (first_uneq != -1)
+ {
+ /* Missing ordered_splice_at. */
+ if ((unsigned)first_uneq == first_edge_seq.length ())
+ first_edge_seq.safe_splice (extra_refs);
+ else
+ {
+ unsigned fes_length = first_edge_seq.length ();
+ first_edge_seq.safe_grow (fes_length
+ + extra_refs.length ());
+ memmove (&first_edge_seq[first_uneq + extra_refs.length ()],
+ &first_edge_seq[first_uneq],
+ (fes_length - first_uneq) * sizeof (seq_entry));
+ memcpy (&first_edge_seq[first_uneq],
+ extra_refs.address (),
+ extra_refs.length () * sizeof (seq_entry));
+ }
}
}
/* Use the sequence from the first edge and push SMs down. */