static inline void pop_scc_to_loop(ir_node *n)
{
ir_node *m;
- int i = 0;
do {
m = pop();
set_irn_dfn(m, loop_node_cnt);
add_loop_node(current_loop, m);
set_irn_loop(m, current_loop);
- ++i;
} while (m != n);
-
- /* i might be bigger than 1 for dead (and that's why bad) loops */
- /* if (i > 1)
- printf("Mehr als eine Iteration!!!!!!!!!!!!!!!!!!!!!!!!!!!!11111\n");
- */
}
/* GL ??? my last son is my grandson??? Removes loops with no
finish_stack();
}
-#ifdef INTERPROCEDURAL_VIEW
-static inline void init_ip_scc(struct obstack *obst)
-{
- init_scc_common();
- cg_walk(init_node, NULL, obst);
-
-#if EXPERIMENTAL_LOOP_TREE
- cg_walk(link_to_reg_end, NULL, NULL);
-#endif
-}
-#endif
-
/**
* Check weather a given node represents the outer most Start
* block. In intra-procedural view this is the start block of the
#if BLOCK_BEFORE_NODE
/* This version assures, that all nodes are ordered absolutely. This allows
- to undef all nodes in the heap analysis if the block is false, which means
- not reachable.
- I.e., with this code, the order on the loop tree is correct. But a (single)
- test showed the loop tree is deeper. */
- if (get_irn_op(n) == op_Phi ||
- is_Block(n) ||
- (is_Filter(n) && get_interprocedural_view()) || (
- get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
- get_irn_pinned(n) == op_pin_state_floats
- ))
+ to undef all nodes in the heap analysis if the block is false, which
+ means not reachable.
+ I.e., with this code, the order on the loop tree is correct. But a
+ (single) test showed the loop tree is deeper. */
+ if (get_irn_op(n) == op_Phi ||
+ is_Block(n) ||
+ (get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
+ get_irn_pinned(n) == op_pin_state_floats))
// Here we could test for backedge at -1 which is illegal
return 0;
else
/**
* Return non-zero if the given node is a legal loop header:
- * Block, Phi, Filter.
+ * Block, Phi
*
* @param n the node to check
*/
{
ir_op *op = get_irn_op(n);
return ((op == op_Block) ||
- (op == op_Phi) ||
- ((op == op_Filter) && get_interprocedural_view()));
+ (op == op_Phi));
}
/**
- * Returns non-zero if n is a loop header, i.e., it is a Block, Phi
- * or Filter node and has predecessors within the loop and out
- * of the loop.
+ * Returns non-zero if n is a loop header, i.e., it is a Block or Phi
+ * node and has predecessors within the loop and out of the loop.
*
* @param n the node to check
* @param root only needed for assertion.
/**
* Returns non-zero if n is possible loop head of an endless loop.
- * I.e., it is a Block, Phi or Filter node and has only predecessors
+ * I.e., it is a Block or Phi node and has only predecessors
* within the loop.
*
* @param n the node to check
return is_outermost_Start(n) ? NULL : get_irn_n(m, res_index);
}
-
-#if EXPERIMENTAL_LOOP_TREE
-
-/* ----------------------------------------------------------------
- AS: This is experimental code to build loop trees suitable for
- the heap analysis. Does not work correctly right now... :-(
-
-
- Search in stack for the corresponding first Call-End-ProjX that
- corresponds to one of the control flow predecessors of the given
- block, that is the possible callers.
- returns: the control predecessor to chose\
- or -1 if no corresponding Call-End-Node could be found
- on the stack.
- - -------------------------------------------------------------- */
-
-int search_endproj_in_stack(ir_node *start_block)
-{
- int i, j;
- assert(is_Block(start_block));
- for (i = tos - 1; i >= 0; --i)
- {
- if (get_irn_op(stack[i]) == op_Proj && get_irn_mode(stack[i]) == mode_X &&
- get_irn_op(get_irn_n(stack[i], 0)) == op_EndReg)
- {
- printf("FOUND PROJ!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
- ir_node *end_projx = stack[i];
-
- int arity = get_irn_arity(start_block);
- for (j = 0; j < arity; j++)
- {
- ir_node *begin_projx = get_Block_cfgpred(get_irg_start_block(get_irn_irg(end_projx)),
- get_Proj_proj(end_projx));
- if (get_irn_n(start_block, j) == begin_projx)
- {
- printf("FOUND IT!!!!!!!!!!!!!!!!!!\n");
- return(j);
- }
- }
- }
- }
- return(-1);
-}
-
-
-static pmap *projx_link = NULL;
-
-void link_to_reg_end (ir_node *n, void *env)
-{
- if (get_irn_op(n) == op_Proj &&
- get_irn_mode(n) == mode_X &&
- get_irn_op(get_irn_n(n, 0)) == op_EndReg) {
- /* Reg End Projx -> Find the CallBegin Projx and hash it */
- ir_node *end_projx = n;
- ir_node *begin_projx = get_Block_cfgpred(get_irg_start_block(get_irn_irg(end_projx)),
- get_Proj_proj(end_projx));
- set_projx_link(begin_projx, end_projx);
- }
-}
-
-void set_projx_link(ir_node *cb_projx, ir_node *end_projx)
-{
- if (projx_link == NULL)
- projx_link = pmap_create();
- pmap_insert(projx_link, (void *)cb_projx, (void *)end_projx);
-}
-
-ir_node *get_projx_link(ir_node *cb_projx)
-{
- return((ir_node *) pmap_get(projx_link, (void *)cb_projx));
-}
-
-#endif
-
static inline int is_outermost_loop(ir_loop *l)
{
return l == get_loop_outer_loop(l);
}
-
/*-----------------------------------------------------------*
* The core algorithm. *
*-----------------------------------------------------------*/
}
}
-#ifdef INTERPROCEDURAL_VIEW
-static void my_scc(ir_node *n)
-{
- int i;
- if (irn_visited_else_mark(n))
- return;
-
- /* Initialize the node */
- set_irn_dfn(n, current_dfn); /* Depth first number for this node */
- set_irn_uplink(n, current_dfn); /* ... is default uplink. */
- set_irn_loop(n, NULL);
- current_dfn ++;
- push(n);
-
- /* AS: get_start_index might return -1 for Control Flow Nodes, and thus a negative
- array index would be passed to is_backedge(). But CFG Nodes dont't have a backedge array,
- so is_backedge does not access array[-1] but correctly returns false! */
-
- if (!is_outermost_Start(n)) {
- int arity = get_irn_arity(n);
-
- for (i = get_start_index(n); i < arity; i++) {
- ir_node *m;
- if (is_backedge(n, i)) continue;
- m = get_irn_n(n, i); /* get_irn_ip_pred(n, i); */
- /* if (!m || is_Unknown(m)) continue; */
- my_scc(m);
- if (irn_is_in_stack(m)) {
- /* Uplink of m is smaller if n->m is a backedge.
- Propagate the uplink to mark the loop. */
- if (get_irn_uplink(m) < get_irn_uplink(n))
- set_irn_uplink(n, get_irn_uplink(m));
- }
- }
- }
-
- if (get_irn_dfn(n) == get_irn_uplink(n)) {
- /* This condition holds for
- 1) the node with the incoming backedge.
- That is: We found a loop!
- 2) Straight line code, because no uplink has been propagated, so the
- uplink still is the same as the dfn.
-
- But n might not be a proper loop head for the analysis. Proper loop
- heads are Block and Phi nodes. find_tail searches the stack for
- Block's and Phi's and takes those nodes as loop heads for the current
- loop instead and marks the incoming edge as backedge. */
-
- ir_node *tail = find_tail(n);
- if (tail) {
- /* We have a loop, that is no straight line code,
- because we found a loop head!
- Next actions: Open a new loop on the loop tree and
- try to find inner loops */
-
-#if NO_LOOPS_WITHOUT_HEAD
- /* This is an adaption of the algorithm from fiasco / optscc to
- * avoid loops without Block or Phi as first node. This should
- * severely reduce the number of evaluations of nodes to detect
- * a fixpoint in the heap analysis.
- * Further it avoids loops without firm nodes that cause errors
- * in the heap analyses. */
-
- ir_loop *l;
- int close;
- if ((get_loop_n_elements(current_loop) > 0) || (is_outermost_loop(current_loop))) {
- l = new_loop();
- close = 1;
- } else {
- l = current_loop;
- close = 0;
- }
-#else
- ir_loop *l = new_loop();
-#endif
-
- /* Remove the loop from the stack ... */
- pop_scc_unmark_visit(n);
-
- /* The current backedge has been marked, that is temporarily eliminated,
- by find tail. Start the scc algorithm
- anew on the subgraph that is left (the current loop without the backedge)
- in order to find more inner loops. */
- my_scc(tail);
-
- assert(irn_visited(n));
-#if NO_LOOPS_WITHOUT_HEAD
- if (close)
-#endif
- close_loop(l);
- } else {
- /* No loop head was found, that is we have straightline code.
- Pop all nodes from the stack to the current loop. */
- pop_scc_to_loop(n);
- }
- }
-}
-#endif /* INTERPROCEDURAL_VIEW */
-
/* Constructs backedge information for irg. In interprocedural view constructs
backedges for all methods called by irg, too. */
int construct_backedges(ir_graph *irg)
ir_loop *head_rem;
struct obstack temp;
- assert(!get_interprocedural_view() &&
- "not implemented, use construct_ip_backedges()");
-
max_loop_depth = 0;
current_ir_graph = irg;
outermost_ir_graph = irg;
return max_loop_depth;
}
-
-#ifdef INTERPROCEDURAL_VIEW
-int construct_ip_backedges(void)
-{
- ir_graph *rem = current_ir_graph;
- int rem_ipv = get_interprocedural_view();
- int i;
- strcut obstack temp;
-
- max_loop_depth = 0;
- assert(get_irp_ip_view_state() == ip_view_valid);
-
- outermost_ir_graph = get_irp_main_irg();
-
- obstack_init(&temp);
- init_ip_scc(&temp);
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /** We have to start the walk at the same nodes as cg_walk. **/
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb))
- continue;
-
- scc(get_irg_end(current_ir_graph));
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph)) scc(sb);
- }
-
- /* Walk all endless loops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
-
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++)
- scc(get_End_keepalive(e, j));
- }
- }
-
- set_irg_loop(outermost_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
- assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
-
- obstack_free(&temp, NULL);
- current_ir_graph = rem;
- set_interprocedural_view(rem_ipv);
- return max_loop_depth;
-}
-
-void my_construct_ip_backedges(void)
-{
- ir_graph *rem = current_ir_graph;
- int rem_ipv = get_interprocedural_view();
- int i;
-
- assert(get_irp_ip_view_state() == ip_view_valid);
-
- outermost_ir_graph = get_irp_main_irg();
-
- init_ip_scc();
-
- current_loop = NULL;
- new_loop(); /* sets current_loop */
- set_interprocedural_view(1);
-
- inc_max_irg_visited();
- for (i = 0; i < get_irp_n_irgs(); i++)
- set_irg_visited(get_irp_irg(i), get_max_irg_visited());
-
- /** We have to start the walk at the same nodes as cg_walk. **/
- /* Walk starting at unreachable procedures. Only these
- * have End blocks visible in interprocedural view. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- sb = get_irg_start_block(current_ir_graph);
-
- if ((get_Block_n_cfgpreds(sb) > 1) ||
- (get_nodes_block(get_Block_cfgpred(sb, 0)) != sb)) continue;
-
- my_scc(get_irg_end(current_ir_graph));
- }
-
- /* Check whether we walked all procedures: there could be procedures
- with cyclic calls but no call from the outside. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *sb;
- current_ir_graph = get_irp_irg(i);
-
- /* Test start block: if inner procedure end and end block are not
- * visible and therefore not marked. */
- sb = get_irg_start_block(current_ir_graph);
- if (get_irn_visited(sb) < get_irg_visited(current_ir_graph))
- scc(sb);
- }
-
- /* Walk all endless loops in inner procedures.
- * We recognize an inner procedure if the End node is not visited. */
- for (i = 0; i < get_irp_n_irgs(); i++) {
- ir_node *e;
- current_ir_graph = get_irp_irg(i);
-
- e = get_irg_end(current_ir_graph);
- if (get_irn_visited(e) < get_irg_visited(current_ir_graph)) {
- int j;
- /* Don't visit the End node. */
- for (j = 0; j < get_End_n_keepalives(e); j++) scc(get_End_keepalive(e, j));
- }
- }
-
- set_irg_loop(outermost_ir_graph, current_loop);
- set_irg_loopinfo_state(current_ir_graph, loopinfo_ip_consistent);
- assert(get_irg_loop(outermost_ir_graph)->kind == k_ir_loop);
-
- current_ir_graph = rem;
- set_interprocedural_view(rem_ipv);
-}
-#endif
-
static void reset_backedges(ir_node *n)
{
if (is_possible_loop_head(n)) {
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
-
- set_interprocedural_view(1);
- clear_backedges(n);
- set_interprocedural_view(1);
- clear_backedges(n);
- set_interprocedural_view(rem);
-#else
clear_backedges(n);
-#endif
}
}
-
/*
static void loop_reset_backedges(ir_loop *l)
{
reset_backedges(n);
}
-
/** Removes all loop information.
Resets all backedges */
void free_loop_information(ir_graph *irg)
/* We cannot free the loop nodes, they are on the obstack. */
}
-
void free_all_loop_information(void)
{
int i;
-#ifdef INTERPROCEDURAL_VIEW
- int rem = get_interprocedural_view();
- set_interprocedural_view(1); /* To visit all filter nodes */
-#endif
for (i = 0; i < get_irp_n_irgs(); i++) {
free_loop_information(get_irp_irg(i));
}
-#ifdef INTERPROCEDURAL_VIEW
- set_interprocedural_view(rem);
-#endif
}
/* ------------------------------------------------------------------- */