pset_insert_ptr(copies, phi);
pset_insert_ptr(copy_blocks, y);
- /* Insert the phi node into the schedule */
- sched_add_before(sched_first(y), phi);
+ /*
+ * Insert the phi node into the schedule if it
+ * can occur there (PhiM's are not to put into a schedule.
+ */
+ if(to_appear_in_schedule(phi))
+ sched_add_before(sched_first(y), phi);
/* Insert the phi node in the phi blocks set. */
pset_insert_ptr(phi_blocks, y);
free(outs);
}
+struct phi_collect_info {
+ const ir_node *orig;
+ pset *copies;
+ pset *copy_blocks;
+};
+
+static void add_all_phis_walker(ir_node *irn, void *data)
+{
+ if(is_Phi(irn)) {
+ int i, n;
+ struct phi_collect_info *info = data;
+
+ /*
+ * Look at all operands of the phi. If one of them is the original
+ * node, insert the phi into the copies and copy_blocks set.
+ */
+ for(i = 0, n = get_irn_arity(irn); i < n; ++i) {
+ if(get_irn_n(irn, i) == info->orig) {
+ pset_insert_ptr(info->copies, irn);
+ pset_insert_ptr(info->copy_blocks, get_nodes_block(irn));
+ break;
+ }
+ }
+
+
+ }
+}
+
+/**
+ * Add all phis using a node to a set.
+ * @param orig The node the phis shall use.
+ * @param copies The set where the phis shall be put into.
+ * @param copy_blocks The set the blocks of the phis shall be put into.
+ */
+static void add_all_phis_using(const ir_node *orig, pset *copies, pset *copy_blocks)
+{
+ struct phi_collect_info info;
+
+ info.copies = copies;
+ info.copy_blocks = copy_blocks;
+ info.orig = orig;
+ irg_walk_graph(get_irn_irg(orig), add_all_phis_walker, NULL, &info);
+}
+
void be_introduce_copies(dom_front_info_t *info, ir_node *orig, int n, ir_node *copy_nodes[])
{
pset *copies = pset_new_ptr(2 * n);
pset_insert_ptr(copies, orig);
pset_insert_ptr(copy_blocks, get_nodes_block(orig));
+ /*
+ * All phis using the original value are also copies of it
+ * and must be present in the copies set.
+ */
+ add_all_phis_using(orig, copies, copy_blocks);
+
for(i = 0; i < n; ++i) {
DBG((dbg, LEVEL_1,
" %+F in block %+F\n", copy_nodes[i], get_nodes_block(copy_nodes[i])));