#include "irgraph_t.h"
#include "irprog_t.h"
#include "irgwalk.h"
+#include "irtools.h"
#ifdef DEBUG_libfirm
/* Note: ir_node.out_valid and ir_graph.n_outs are only present when DEBUG_libfirm is defined */
#ifdef DEBUG_libfirm
/* assert (node->out_valid); */
#endif /* defined DEBUG_libfirm */
- return (int)(node->out[0]);
+ return PTR_TO_INT(node->out[0]);
}
/* Access successor n */
node->out[pos+1] = out;
}
-
+/* Return the number of control flow successors, ignore keep-alives. */
int get_Block_n_cfg_outs(ir_node *bl) {
int i, n_cfg_outs = 0;
assert(bl && is_Block(bl));
#ifdef DEBUG_libfirm
assert (bl->out_valid);
#endif /* defined DEBUG_libfirm */
- for (i = 1; i <= (int)bl->out[0]; i++)
+ for (i = 1; i <= PTR_TO_INT(bl->out[0]); i++)
if ((get_irn_mode(bl->out[i]) == mode_X) &&
(get_irn_op(bl->out[i]) != op_End))
n_cfg_outs++;
return n_cfg_outs;
}
+/* Return the number of control flow successors, honor keep-alives. */
+int get_Block_n_cfg_outs_ka(ir_node *bl) {
+ int i, n_cfg_outs = 0;
+ assert(bl && is_Block(bl));
+#ifdef DEBUG_libfirm
+ assert (bl->out_valid);
+#endif /* defined DEBUG_libfirm */
+ for (i = 1; i <= PTR_TO_INT(bl->out[0]); i++)
+ if (get_irn_mode(bl->out[i]) == mode_X) {
+ /* ignore End if we are in the Endblock */
+ if (get_irn_op(bl->out[i]) == op_End &&
+ get_irn_n(bl->out[i], -1) == bl)
+ continue;
+ else
+ n_cfg_outs++;
+ }
+ return n_cfg_outs;
+}
+/* Access predecessor n, ignore keep-alives. */
ir_node *get_Block_cfg_out(ir_node *bl, int pos) {
int i, out_pos = 0;
- assert(bl && (get_irn_op(bl) == op_Block));
+ assert(bl && is_Block(bl));
#ifdef DEBUG_libfirm
assert (bl->out_valid);
#endif /* defined DEBUG_libfirm */
- for (i = 1; i <= (int)bl->out[0]; i++)
+ for (i = 1; i <= PTR_TO_INT(bl->out[0]); i++)
if ((get_irn_mode(bl->out[i]) == mode_X) &&
(get_irn_op(bl->out[i]) != op_End)) {
if (out_pos == pos) {
return NULL;
}
+/* Access predecessor n, honor keep-alives. */
+ir_node *get_Block_cfg_out_ka(ir_node *bl, int pos) {
+ int i, out_pos = 0;
+ assert(bl && is_Block(bl));
+#ifdef DEBUG_libfirm
+ assert (bl->out_valid);
+#endif /* defined DEBUG_libfirm */
+ for (i = 1; i <= PTR_TO_INT(bl->out[0]); i++)
+ if (get_irn_mode(bl->out[i]) == mode_X) {
+ /* ignore End if we are in the Endblock */
+ if (get_irn_op(bl->out[i]) == op_End &&
+ get_irn_n(bl->out[i], -1) == bl)
+ continue;
+ if (out_pos == pos) {
+ ir_node *cfop = bl->out[i];
+ /* handle keep-alive here */
+ if (get_irn_op(cfop) == op_End)
+ return get_irn_n(cfop, -1);
+ return cfop->out[1];
+ } else
+ out_pos++;
+ }
+ return NULL;
+}
+
static void irg_out_walk_2(ir_node *node, irg_walk_func *pre,
irg_walk_func *post, void *env) {
- int i;
+ int i, n;
ir_node *succ;
assert(node);
if (pre) pre(node, env);
- for (i = 0; i < get_irn_n_outs(node); i++) {
+ for (i = 0, n = get_irn_n_outs(node); i < n; i++) {
succ = get_irn_out(node, i);
if (get_irn_visited(succ) < get_irg_visited(current_ir_graph))
irg_out_walk_2(succ, pre, post, env);
static void irg_out_block_walk2(ir_node *bl,
irg_walk_func *pre, irg_walk_func *post,
void *env) {
- int i;
+ int i, n;
- if(get_Block_block_visited(bl) < get_irg_block_visited(current_ir_graph)) {
- set_Block_block_visited(bl, get_irg_block_visited(current_ir_graph));
+ if (Block_not_block_visited(bl)) {
+ mark_Block_block_visited(bl);
- if(pre)
+ if (pre)
pre(bl, env);
- for(i = 0; i < get_Block_n_cfg_outs(bl); i++) {
+ for (i = 0, n = get_Block_n_cfg_outs(bl); i < n; i++) {
/* find the corresponding predecessor block. */
ir_node *pred = get_Block_cfg_out(bl, i);
/* recursion */
irg_out_block_walk2(pred, pre, post, env);
}
- if(post)
+ if (post)
post(bl, env);
}
- return;
}
/* Walks only over Block nodes in the graph. Has it's own visited
irg_walk_func *pre, irg_walk_func *post,
void *env) {
- assert((get_irn_op(node) == op_Block) || (get_irn_mode(node) == mode_X));
+ assert(is_Block(node) || (get_irn_mode(node) == mode_X));
inc_irg_block_visited(current_ir_graph);
- if (get_irn_mode(node) == mode_X) node = node->out[1];
+ if (get_irn_mode(node) == mode_X)
+ node = node->out[1];
irg_out_block_walk2(node, pre, post, env);
-
- return;
-
}
/*--------------------------------------------------------------------*/
res += _count_outs(pred);
/* Count my outs */
- pred->out = (ir_node **)( (int)pred->out + 1);
+ pred->out = (ir_node **)INT_TO_PTR(PTR_TO_INT(pred->out) + 1);
}
return res;
}
/** Returns the amount of out edges for not yet visited successors.
- * This version handles some special nodes like irg_frame etc.
+ * This version handles some special nodes like irg_frame, irg_args etc.
*/
static int count_outs(ir_graph *irg) {
ir_node *n;
++res;
}
+ n = get_irg_args(irg);
+ if (irn_not_visited(n)) {
+ n->out = (ir_node **)1;
+ ++res;
+ }
+
return res;
}
set_irn_visited(n, get_irg_visited(current_ir_graph));
/* Allocate my array */
- n_outs = (int) n->out;
+ n_outs = PTR_TO_INT(n->out);
n->out = free;
#ifdef DEBUG_libfirm
n->out_valid = 1;
free = _set_out_edges(pred, free);
/* Remember our back edge */
pred->out[get_irn_n_outs(pred)+1] = n;
- pred->out[0] = (ir_node *) (get_irn_n_outs(pred) + 1);
+ pred->out[0] = INT_TO_PTR(get_irn_n_outs(pred) + 1);
}
return free;
}
* @return The next free address
*/
static ir_node **set_out_edges(ir_graph *irg, ir_node **free) {
- ir_node *n;
- int n_outs;
+ ir_node *n, *special[2];
+ int i, n_outs;
inc_irg_visited(irg);
free = _set_out_edges(get_irg_end(irg), free);
- n = get_irg_frame(irg);
- if (get_irn_visited(n) < get_irg_visited(current_ir_graph)) {
- n_outs = (int)n->out;
- n->out = free;
+ /* handle special nodes */
+ special[0] = get_irg_frame(irg);
+ special[1] = get_irg_args(irg);
+
+ for (i = 1; i >= 0; --i) {
+ n = special[i];
+
+ if (get_irn_visited(n) < get_irg_visited(current_ir_graph)) {
+ n_outs = PTR_TO_INT(n->out);
+ n->out = free;
#ifdef DEBUG_libfirm
- n->out_valid = 1;
+ n->out_valid = 1;
#endif /* defined DEBUG_libfirm */
- free += n_outs;
+ free += n_outs;
+ }
}
return free;
int i;
if (get_Block_n_cfg_outs(startbl)) {
- for (i = 0; i < get_irn_n_outs(startbl); i++)
+ for (i = get_irn_n_outs(startbl) - 1; i >= 0; --i)
if (get_irn_mode(get_irn_out(startbl, i)) == mode_X) {
proj = get_irn_out(startbl, i);
break;
if (current_ir_graph->outs_state != outs_none)
free_irg_outs(current_ir_graph);
- current_ir_graph->outs_state = outs_consistent;
/* This first iteration counts the overall number of out edges and the
number of out edges for each node. */
the out block walker. */
fix_start_proj(irg);
+ current_ir_graph->outs_state = outs_consistent;
current_ir_graph = rem;
}
+void assure_irg_outs(ir_graph *irg) {
+ if (get_irg_outs_state(irg) != outs_consistent)
+ compute_irg_outs(irg);
+}
+
void compute_irp_outs(void) {
int i, n_irgs = get_irp_n_irgs();
for (i = 0; i < n_irgs; ++i)
for(i = start; i < arity; i++) {
succ = get_irn_n(node, i);
- succ->out = (ir_node **)((int)succ->out + 1);
+ succ->out = (ir_node **)INT_TO_PTR(PTR_TO_INT(succ->out) + 1);
}
}
ir_node ***free = (ir_node ***) env;
/* Allocate my array */
- n_outs = (int) node -> out; /* We wrote the count here in count_ip_outs */
+ n_outs = PTR_TO_INT(node->out); /* We wrote the count here in count_ip_outs */
dummy_count += n_outs;
assert(dummy_count <= global_count && "More outedges than initially counted!");
node -> out = *free;
ir_node *succ;
int start = (!is_Block(node)) ? -1 : 0;
- for(i = start; i < arity; i++) {
+ for (i = start; i < arity; i++) {
succ = get_irn_n(node, i);
succ->out[get_irn_n_outs(succ)+1] = node;
- succ->out[0] = (ir_node *) (get_irn_n_outs(succ) + 1);
+ succ->out[0] = INT_TO_PTR(get_irn_n_outs(succ) + 1);
}
}