}
}
+/* Returns true when DEF is an SSA_NAME defined in LOOP and used after
+ the LOOP. */
+
+static bool
+ssa_name_has_uses_outside_loop_p (tree def, loop_p loop)
+{
+ imm_use_iterator imm_iter;
+ use_operand_p use_p;
+
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, def)
+ if (loop != loop_containing_stmt (USE_STMT (use_p)))
+ return true;
+
+ return false;
+}
+
+/* Returns true when STMT defines a scalar variable used after the
+ loop. */
+
+static bool
+stmt_has_scalar_dependences_outside_loop (gimple stmt)
+{
+ tree name;
+
+ switch (gimple_code (stmt))
+ {
+ case GIMPLE_ASSIGN:
+ name = gimple_assign_lhs (stmt);
+ break;
+
+ case GIMPLE_PHI:
+ name = gimple_phi_result (stmt);
+ break;
+
+ default:
+ return false;
+ }
+
+ return TREE_CODE (name) == SSA_NAME
+ && ssa_name_has_uses_outside_loop_p (name, loop_containing_stmt (stmt));
+}
+
+/* Returns true when STMT will be code generated in a partition of RDG
+ different than PART and that will not be code generated as a
+ builtin. */
+
+static bool
+stmt_generated_in_another_partition (struct graph *rdg, gimple stmt, int part,
+ VEC (bitmap, heap) *partitions)
+{
+ int p;
+ bitmap pp;
+ unsigned i;
+ bitmap_iterator bi;
+
+ FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
+ if (p != part
+ && !can_generate_builtin (rdg, pp))
+ EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
+ if (stmt == RDG_STMT (rdg, i))
+ return true;
+
+ return false;
+}
+
+/* For each partition in PARTITIONS that will be code generated using
+ a builtin, add its scalar computations used after the loop to
+ PARTITION. */
+
+static void
+add_scalar_computations_to_partition (struct graph *rdg,
+ VEC (bitmap, heap) *partitions,
+ bitmap partition)
+{
+ int p;
+ bitmap pp;
+ unsigned i;
+ bitmap_iterator bi;
+ bitmap l = BITMAP_ALLOC (NULL);
+ bitmap pr = BITMAP_ALLOC (NULL);
+ bool f = false;
+
+ FOR_EACH_VEC_ELT (bitmap, partitions, p, pp)
+ if (can_generate_builtin (rdg, pp))
+ EXECUTE_IF_SET_IN_BITMAP (pp, 0, i, bi)
+ if (stmt_has_scalar_dependences_outside_loop (RDG_STMT (rdg, i))
+ && !stmt_generated_in_another_partition (rdg, RDG_STMT (rdg, i), p,
+ partitions))
+ rdg_flag_vertex_and_dependent (rdg, i, partition, l, pr, &f);
+
+ rdg_flag_loop_exits (rdg, l, partition, pr, &f);
+
+ BITMAP_FREE (pr);
+ BITMAP_FREE (l);
+}
+
/* Aggregate several components into a useful partition that is
registered in the PARTITIONS vector. Partitions will be
distributed in different loops. */
free_rdg_components (comps);
}
+ add_scalar_computations_to_partition (rdg, *partitions, partition);
+
/* If there is something left in the last partition, save it. */
if (bitmap_count_bits (partition) > 0)
VEC_safe_push (bitmap, heap, *partitions, partition);