}
/**
- * collect nodes
+ * Post-walker: collect nodes and put them on the right list
*/
static void collect_nodes(ir_node *node, void *env)
{
if (is_Block(node)) {
/* it's a block, put it into the block list */
- pdeq_putr(ctx->blk_list, node);
+ pdeq_putl(ctx->blk_list, node);
return;
}
block = get_nodes_block(node);
entry = block_find_entry(block, ctx);
- if (get_irn_mode(node) == mode_X)
- pdeq_putl(entry->list, node);
- else
+ if (get_irn_mode(node) == mode_X) {
+ /*
+ * put all mode_X nodes to the start, later we can
+ * move them to the end.
+ */
pdeq_putr(entry->list, node);
+ }
+ else
+ pdeq_putl(entry->list, node);
+}
+
+/**
+ * move mode_X nodes to the end of the schedule
+ */
+static void move_X_nodes_to_end(pdeq *list)
+{
+ int j;
+
+ /* move mode_X nodes to the end */
+ for (j = pdeq_len(list); j > 0; --j) {
+ ir_node *node = pdeq_getr(list);
+
+ if (get_irn_mode(node) == mode_X) {
+ pdeq_putl(list, node);
+ }
+ else {
+ pdeq_putr(list, node);
+ break;
+ }
+ }
}
/**
ir_node *block = pdeq_getl(blks->blk_list);
block_entry_t *entry = block_find_entry(block, blks);
+ /* move mode_X nodes to the end */
+ move_X_nodes_to_end(entry->list);
+
for (j = pdeq_len(entry->list); j > 0; --j) {
ir_node *node = pdeq_getl(entry->list);
pre(node, env);
block_entry_t *entry = block_find_entry(block, blks);
post(block, env);
+
+ /* move mode_X nodes to the end */
+ move_X_nodes_to_end(entry->list);
+
for (j = pdeq_len(entry->list); j > 0; --j) {
ir_node *node = pdeq_getr(entry->list);
post(node, env);
pdeq_putr(blks->blk_list, block);
+ /* move mode_X nodes to the end */
+ move_X_nodes_to_end(entry->list);
+
for (j = pdeq_len(entry->list); j > 0; --j) {
ir_node *node = pdeq_getl(entry->list);
}
/* second step */
- traverse_post(blks, post, env);
+ for (i = pdeq_len(blks->blk_list); i > 0; --i) {
+ ir_node *block = pdeq_getr(blks->blk_list);
+ block_entry_t *entry = block_find_entry(block, blks);
+
+ post(block, env);
+
+ for (j = pdeq_len(entry->list); j > 0; --j) {
+ ir_node *node = pdeq_getr(entry->list);
+ post(node, env);
+ }
+ }
}
if (node->visited < current_ir_graph->visited) {
/* first step: traverse the graph and fill the lists */
- irg_walk(node, collect_nodes, NULL, &blks);
+ irg_walk(node, NULL, collect_nodes, &blks);
/* second step: traverse the list */
traverse(&blks, pre, post, env);