*/
#include "config.h"
-#ifdef HAVE_STRING_H
-# include <string.h>
-#endif
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
+#include <string.h>
+#include <stdlib.h>
#include "irloop_t.h"
/**
* Allocates a new SCC info on the given obstack.
*/
-static inline scc_info *new_scc_info(struct obstack *obst) {
- scc_info *info = obstack_alloc(obst, sizeof(*info));
- memset(info, 0, sizeof(*info));
- return info;
+static inline scc_info *new_scc_info(struct obstack *obst)
+{
+ return OALLOCZ(obst, scc_info);
}
/**
* Mark node n being on the SCC stack.
*/
-static inline void mark_irn_in_stack(ir_node *n) {
+static inline void mark_irn_in_stack(ir_node *n)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
scc->in_stack = 1;
/**
* Mark node n NOT being on the SCC stack.
*/
-static inline void mark_irn_not_in_stack(ir_node *n) {
+static inline void mark_irn_not_in_stack(ir_node *n)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
scc->in_stack = 0;
/**
* Checks if a node is on the SCC stack.
*/
-static inline int irn_is_in_stack(ir_node *n) {
+static inline int irn_is_in_stack(ir_node *n)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
return scc->in_stack;
/**
* Sets the uplink number for a node.
*/
-static inline void set_irn_uplink(ir_node *n, int uplink) {
+static inline void set_irn_uplink(ir_node *n, int uplink)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
scc->uplink = uplink;
/**
* Returns the uplink number for a node.
*/
-static int get_irn_uplink(ir_node *n) {
+static int get_irn_uplink(ir_node *n)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
return scc->uplink;
/**
* Sets the depth-first-search number for a node.
*/
-static inline void set_irn_dfn(ir_node *n, int dfn) {
+static inline void set_irn_dfn(ir_node *n, int dfn)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
scc->dfn = dfn;
/**
* Returns the depth-first-search number of a node.
*/
-static int get_irn_dfn(ir_node *n) {
+static int get_irn_dfn(ir_node *n)
+{
scc_info *scc = get_irn_link(n);
assert(scc);
return scc->dfn;
}
#if 0
-static ir_loop *find_nodes_loop(ir_node *n, ir_loop *l) {
+static ir_loop *find_nodes_loop(ir_node *n, ir_loop *l)
+{
int i;
ir_loop *res = NULL;
}
/* @@@ temporary implementation, costly!!! */
-ir_loop * get_irn_loop(ir_node *n) {
+ir_loop * get_irn_loop(ir_node *n)
+{
ir_loop *l = get_irg_loop(current_ir_graph);
l = find_nodes_loop(n, l);
return l;
/**
* initializes the stack
*/
-static inline void init_stack(void) {
+static inline void init_stack(void)
+{
if (stack) {
ARR_RESIZE(ir_node *, stack, 1000);
} else {
/**
* Frees the stack.
*/
-static void finish_stack(void) {
+static void finish_stack(void)
+{
DEL_ARR_F(stack);
stack = NULL;
}
*
* @param n The node to push
*/
-static inline void push(ir_node *n) {
+static inline void push(ir_node *n)
+{
if (tos == ARR_LEN(stack)) {
int nlen = ARR_LEN(stack) * 2;
ARR_RESIZE(ir_node *, stack, nlen);
*
* @return The topmost node
*/
-static inline ir_node *pop(void) {
+static inline ir_node *pop(void)
+{
ir_node *n = stack[--tos];
mark_irn_not_in_stack(n);
return n;
* The nodes up to n belong to the current loop.
* Removes them from the stack and adds them to the current loop.
*/
-static inline void pop_scc_to_loop(ir_node *n) {
+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
ir_nodes in them. Such loops have only another loop as son. (Why
can't they have two loops as sons? Does it never get that far? ) */
-static void close_loop(ir_loop *l) {
+static void close_loop(ir_loop *l)
+{
int last = get_loop_n_elements(l) - 1;
loop_element lelement = get_loop_element(l, last);
ir_loop *last_son = lelement.son;
/* Removes and unmarks all nodes up to n from the stack.
The nodes must be visited once more to assign them to a scc. */
-static inline void pop_scc_unmark_visit(ir_node *n) {
+static inline void pop_scc_unmark_visit(ir_node *n)
+{
ir_node *m = NULL;
while (m != n) {
/* Allocates a new loop as son of current_loop. Sets current_loop
to the new loop and returns the father. */
-static ir_loop *new_loop(void) {
+static ir_loop *new_loop(void)
+{
ir_loop *father = current_loop;
ir_loop *son = alloc_loop(father, outermost_ir_graph->obst);
/* Initialization steps. **********************************************/
-static inline void init_node(ir_node *n, void *env) {
+static inline void init_node(ir_node *n, void *env)
+{
struct obstack *obst = env;
set_irn_link(n, new_scc_info(obst));
clear_backedges(n);
}
-static inline void init_scc_common(void) {
+static inline void init_scc_common(void)
+{
current_dfn = 1;
loop_node_cnt = 0;
init_stack();
}
-static inline void init_scc(ir_graph *irg, struct obstack *obst) {
+static inline void init_scc(ir_graph *irg, struct obstack *obst)
+{
init_scc_common();
irg_walk_graph(irg, init_node, NULL, obst);
/*
}
#ifdef INTERPROCEDURAL_VIEW
-static inline void init_ip_scc(struct obstack *obst) {
+static inline void init_ip_scc(struct obstack *obst)
+{
init_scc_common();
cg_walk(init_node, NULL, obst);
*
* This is the condition for breaking the scc recursion.
*/
-static int is_outermost_Start(ir_node *n) {
+static int is_outermost_Start(ir_node *n)
+{
/* Test whether this is the outermost Start node. */
if (is_Block(n) && get_Block_n_cfgpreds(n) == 1) {
ir_node *pred = skip_Proj(get_Block_cfgpred(n, 0));
return 0;
}
+static inline int is_ip_Filter(ir_node *n)
+{
+#ifdef INTERPROCEDURAL_VIEW
+ return is_Filter(n) && get_interprocedural_view();
+#else
+ (void) n;
+ return 0;
+#endif
+}
+
/* When to walk from nodes to blocks. Only for Control flow operations? */
-static inline int get_start_index(ir_node *n) {
+static inline int get_start_index(ir_node *n)
+{
#undef BLOCK_BEFORE_NODE
#define BLOCK_BEFORE_NODE 1
#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()) || (
+ 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_ip_Filter(n)) || (
get_irg_pinned(get_irn_irg(n)) == op_pin_state_floats &&
get_irn_pinned(n) == op_pin_state_floats
))
*
* @param n the node to check
*/
-static inline int is_possible_loop_head(ir_node *n) {
+static inline int is_possible_loop_head(ir_node *n)
+{
ir_op *op = get_irn_op(n);
return ((op == op_Block) ||
(op == op_Phi) ||
- ((op == op_Filter) && get_interprocedural_view()));
+ (is_ip_Filter(n)));
}
/**
* @param n the node to check
* @param root only needed for assertion.
*/
-static int is_head(ir_node *n, ir_node *root) {
+static int is_head(ir_node *n, ir_node *root)
+{
int i, arity;
int some_outof_loop = 0, some_in_loop = 0;
* @param n the node to check
* @param root only needed for assertion.
*/
-static int is_endless_head(ir_node *n, ir_node *root) {
+static int is_endless_head(ir_node *n, ir_node *root)
+{
int i, arity;
int none_outof_loop = 1, some_in_loop = 0;
/** Returns index of the predecessor with the smallest dfn number
greater-equal than limit. */
-static int smallest_dfn_pred(ir_node *n, int limit) {
+static int smallest_dfn_pred(ir_node *n, int limit)
+{
int i, index = -2, min = -1;
if (!is_outermost_Start(n)) {
/**
* Returns index of the predecessor with the largest dfn number.
*/
-static int largest_dfn_pred(ir_node *n) {
+static int largest_dfn_pred(ir_node *n)
+{
int i, index = -2, max = -1;
if (!is_outermost_Start(n)) {
*
* @param n A node where uplink == dfn.
*/
-static ir_node *find_tail(ir_node *n) {
+static ir_node *find_tail(ir_node *n)
+{
ir_node *m;
int i, res_index = -2;
on the stack.
- -------------------------------------------------------------- */
-int search_endproj_in_stack(ir_node *start_block) {
+int search_endproj_in_stack(ir_node *start_block)
+{
int i, j;
assert(is_Block(start_block));
- for(i = tos - 1; i >= 0; --i)
+ for (i = tos - 1; i >= 0; --i)
{
- if(get_irn_op(stack[i]) == op_Proj && get_irn_mode(stack[i]) == mode_X &&
+ 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++)
+ 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)
+ if (get_irn_n(start_block, j) == begin_projx)
{
printf("FOUND IT!!!!!!!!!!!!!!!!!!\n");
return(j);
static pmap *projx_link = NULL;
-void link_to_reg_end (ir_node *n, void *env) {
- if(get_irn_op(n) == op_Proj &&
+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 */
}
}
-void set_projx_link(ir_node *cb_projx, ir_node *end_projx) {
- if(projx_link == NULL)
+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) {
+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) {
+static inline int is_outermost_loop(ir_loop *l)
+{
return l == get_loop_outer_loop(l);
}
*
* @param n node to start
*/
-static void scc(ir_node *n) {
+static void scc(ir_node *n)
+{
if (irn_visited_else_mark(n))
return;
}
#ifdef INTERPROCEDURAL_VIEW
-static void my_scc(ir_node *n) {
+static void my_scc(ir_node *n)
+{
int i;
if (irn_visited_else_mark(n))
return;
/* Constructs backedge information for irg. In interprocedural view constructs
backedges for all methods called by irg, too. */
-int construct_backedges(ir_graph *irg) {
+int construct_backedges(ir_graph *irg)
+{
ir_graph *rem = current_ir_graph;
ir_loop *head_rem;
struct obstack temp;
+#ifdef INTERPROCEDURAL_VIEW
assert(!get_interprocedural_view() &&
"not implemented, use construct_ip_backedges()");
+#endif
max_loop_depth = 0;
current_ir_graph = irg;
#ifdef INTERPROCEDURAL_VIEW
-int construct_ip_backedges(void) {
+int construct_ip_backedges(void)
+{
ir_graph *rem = current_ir_graph;
int rem_ipv = get_interprocedural_view();
int i;
return max_loop_depth;
}
-void my_construct_ip_backedges(void) {
+void my_construct_ip_backedges(void)
+{
ir_graph *rem = current_ir_graph;
int rem_ipv = get_interprocedural_view();
int i;
}
#endif
-static void reset_backedges(ir_node *n) {
+static void reset_backedges(ir_node *n)
+{
if (is_possible_loop_head(n)) {
#ifdef INTERPROCEDURAL_VIEW
int rem = get_interprocedural_view();
/*
-static void loop_reset_backedges(ir_loop *l) {
+static void loop_reset_backedges(ir_loop *l)
+{
int i;
reset_backedges(get_loop_node(l, 0));
for (i = 0; i < get_loop_n_nodes(l); ++i)
}
*/
-static void loop_reset_node(ir_node *n, void *env) {
+static void loop_reset_node(ir_node *n, void *env)
+{
(void) env;
set_irn_loop(n, NULL);
reset_backedges(n);
/** Removes all loop information.
Resets all backedges */
-void free_loop_information(ir_graph *irg) {
+void free_loop_information(ir_graph *irg)
+{
/* We can not use this recursion, as the loop might contain
illegal nodes by now. Why else would we throw away the
representation?
}
-void free_all_loop_information(void) {
+void free_all_loop_information(void)
+{
int i;
#ifdef INTERPROCEDURAL_VIEW
int rem = get_interprocedural_view();
#endif
}
-
-
-
-
-/* Debug stuff *************************************************/
-
-static int test_loop_node(ir_loop *l) {
- int i, has_node = 0, found_problem = 0;
- loop_element le;
-
- assert(l && l->kind == k_ir_loop);
-
- if (get_loop_n_elements(l) == 0) {
- found_problem = 1;
- dump_loop(l, "-ha");
- }
-
- le = get_loop_element(l, 0);
- if (*(le.kind) != k_ir_node) {
- assert(le.kind && *(le.kind) == k_ir_loop);
-
- found_problem = 1;
- dump_loop(l, "-ha");
- }
-
- if ((*(le.kind) == k_ir_node) && !is_possible_loop_head(le.node)) {
- found_problem = 1;
- dump_loop(l, "-ha");
- }
-
- if ((get_loop_depth(l) != 0) &&
- (*(le.kind) == k_ir_node) && !has_backedges(le.node)) {
- found_problem = 1;
- dump_loop(l, "-ha");
- }
-
- /* Recur */
- has_node = 0;
- for (i = 0; i < get_loop_n_elements(l); ++i) {
- le = get_loop_element(l, i);
- if (*(le.kind) == k_ir_node)
- has_node++;
- else
- if (test_loop_node(le.son)) found_problem = 1;
- }
-
- if (has_node == 0) {
- found_problem = 1;
- dump_loop(l, "-ha");
- }
-
- return found_problem;
-}
-
-/** Prints all loop nodes that
- * - do not have any firm nodes, only loop sons
- * - the header is not a Phi, Block or Filter.
- */
-void find_strange_loop_nodes(ir_loop *l) {
- int found_problem = 0;
- found_problem = test_loop_node(l);
- printf("Finished Test\n\n");
- if (found_problem) exit(0);
-
-}
-
/* ------------------------------------------------------------------- */
/* Simple analyses based on the loop information */
/* ------------------------------------------------------------------- */
-int is_loop_variant(ir_loop *l, ir_loop *b) {
+static int is_loop_variant(ir_loop *l, ir_loop *b)
+{
int i, n_elems;
if (l == b) return 1;
*
* Returns non-zero, if the node n is not changed in the loop block
* belongs to or in inner loops of this blocks loop. */
-int is_loop_invariant(const ir_node *n, const ir_node *block) {
+int is_loop_invariant(const ir_node *n, const ir_node *block)
+{
ir_loop *l = get_irn_loop(block);
const ir_node *b = is_Block(n) ? n : get_nodes_block(n);
return !is_loop_variant(l, get_irn_loop(b));