@@ -81,6 +81,7 @@
#include "ppc-auxv.h"
#include "rs6000-internal.h"
#include "opts.h"
+#include "rtl-iter.h"
/* This file should be included last. */
#include "target-def.h"
@@ -5570,7 +5571,11 @@ rs6000_cost_data::finish_cost (const vector_costs *scalar_costs)
static unsigned
rs6000_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
{
- if (unroll_only_small_loops)
+ basic_block *bbs;
+ rtx_insn *insn;
+ unsigned i;
+ unsigned mem_count = 0;
+ if (unroll_only_small_loops)
{
/* TODO: These are hardcoded values right now. We probably should use
a PARAM here. */
@@ -5582,6 +5587,28 @@ rs6000_loop_unroll_adjust (unsigned nunroll, struct loop *loop)
return 0;
}
+ /* Count the number of memory references within the loop body. */
+ subrtx_iterator::array_type array;
+ bbs = get_loop_body (loop);
+ for (i = 0; i < loop->num_nodes; i++)
+ FOR_BB_INSNS (bbs[i], insn)
+ if (NONDEBUG_INSN_P (insn))
+ FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
+ if (const_rtx x = *iter)
+ if (MEM_P (x))
+ {
+ machine_mode mode = GET_MODE (x);
+ unsigned int n_words = GET_MODE_SIZE (mode) / UNITS_PER_WORD;
+ if (n_words > 4)
+ mem_count += 2;
+ else
+ mem_count += 1;
+ }
+ free (bbs);
+
+ if (mem_count && mem_count <=32)
+ return MIN (nunroll, 32 / mem_count);
+
return nunroll;
}