The interface was really inefficient and shouldn't be used like that.
So simply don't provide functions that make inefficient code convenient.
/** Returns nesting depth of this loop */
FIRM_API unsigned get_loop_depth(const ir_loop *loop);
-/** Returns the number of inner loops */
-FIRM_API size_t get_loop_n_sons(const ir_loop *loop);
-
-/** Returns the pos`th son loop (inner loop) of a loop.
-Returns NULL if there is not a pos`th loop_node. */
-FIRM_API ir_loop *get_loop_son(ir_loop *loop, size_t pos);
-
-/** Returns the number of nodes contained in loop. */
-FIRM_API size_t get_loop_n_nodes(const ir_loop *loop);
-
-/** Returns the pos`th ir_node of a loop.
-Returns NULL if there is not a pos`th ir_node. */
-FIRM_API ir_node *get_loop_node(const ir_loop *loop, size_t pos);
-
/** Returns the number of elements contained in loop. */
FIRM_API size_t get_loop_n_elements(const ir_loop *loop);
kind pointer, an ir_node* or an ir_loop*. */
FIRM_API loop_element get_loop_element(const ir_loop *loop, size_t pos);
-#define INVALID_LOOP_POS ((size_t)-1)
-
-/** Returns the element number of the loop son in loop.
-* Returns INVALID_LOOP_POS if not found. O(|elements|). */
-FIRM_API size_t get_loop_element_pos(const ir_loop *loop, void *le);
-
/** Returns a unique node number for the loop node to make output
readable. If libfirm_debug is not set it returns the loop cast to
int. */
assert(get_kind(son) == k_ir_loop);
lson.son = son;
ARR_APP1(loop_element, loop->children, lson);
- ++loop->n_sons;
loop->flags |= loop_outer_loop;
}
ln.node = n;
assert(loop && loop->kind == k_ir_loop);
ARR_APP1(loop_element, loop->children, ln);
- loop->n_nodes++;
}
void add_loop_irg(ir_loop *loop, ir_graph *irg)
ln.irg = irg;
assert(loop && loop->kind == k_ir_loop);
ARR_APP1(loop_element, loop->children, ln);
- loop->n_nodes++;
}
/**
*/
void mature_loops(ir_loop *loop, struct obstack *obst)
{
+ size_t i;
+
loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
DEL_ARR_F(loop->children);
loop->children = new_children;
- if (loop->n_sons > 0) {
- /* we have child loops, mature them */
- size_t i;
+ /* mature child loops */
+ for (i = ARR_LEN(new_children); i > 0;) {
+ loop_element child = new_children[--i];
- for (i = ARR_LEN(new_children); i > 0;) {
- loop_element child = new_children[--i];
-
- if (*child.kind == k_ir_loop) {
- mature_loops(child.son, obst);
- }
+ if (*child.kind == k_ir_loop) {
+ mature_loops(child.son, obst);
}
}
}
return _get_loop_depth(loop);
}
-/* Returns the number of inner loops */
-size_t (get_loop_n_sons)(const ir_loop *loop)
-{
- return _get_loop_n_sons(loop);
-}
-
-/* Returns the pos`th loop_node-child *
- * TODO: This method isn`t very efficient ! *
- * Returns NULL if there isn`t a pos`th loop_node */
-ir_loop *get_loop_son(ir_loop *loop, size_t pos)
-{
- size_t child_nr = 0;
- size_t loop_nr = 0;
-
- assert(loop && loop->kind == k_ir_loop);
- for (child_nr = 0; child_nr < ARR_LEN(loop->children); ++child_nr) {
- if (*(loop->children[child_nr].kind) != k_ir_loop)
- continue;
- if (loop_nr == pos)
- return loop->children[child_nr].son;
- loop_nr++;
- }
- return NULL;
-}
-
-/* Returns the number of nodes in the loop */
-size_t get_loop_n_nodes(const ir_loop *loop)
-{
- assert(loop);
- assert(loop->kind == k_ir_loop);
- return loop->n_nodes;
-}
-
-/* Returns the pos'th ir_node-child *
- * TODO: This method isn't very efficient ! *
- * Returns NULL if there isn't a pos'th ir_node */
-ir_node *get_loop_node(const ir_loop *loop, size_t pos)
-{
- size_t node_nr = 0;
- size_t child_nr;
-
- assert(loop && loop->kind == k_ir_loop);
- assert(pos < get_loop_n_nodes(loop));
-
- for (child_nr = 0; child_nr < ARR_LEN(loop->children); ++child_nr) {
- if (*(loop->children[child_nr].kind) != k_ir_node)
- continue;
- if (node_nr == pos)
- return loop -> children[child_nr].node;
- node_nr++;
- }
- panic("no child at pos found");
-}
-
/* Returns the number of elements contained in loop. */
size_t get_loop_n_elements(const ir_loop *loop)
{
return(loop -> children[pos]);
}
-size_t get_loop_element_pos(const ir_loop *loop, void *le)
-{
- size_t n;
- size_t i;
- assert(loop && loop->kind == k_ir_loop);
-
- n = get_loop_n_elements(loop);
- for (i = 0; i < n; i++)
- if (get_loop_element(loop, i).node == le)
- return i;
- return INVALID_LOOP_POS;
-}
-
-
/**
* Sets the loop for a node.
*/
son = OALLOCZ(obst, ir_loop);
son->kind = k_ir_loop;
son->children = NEW_ARR_F(loop_element, 0);
- son->n_nodes = 0;
- son->n_sons = 0;
son->link = NULL;
if (father) {
son->outer_loop = father;
struct ir_loop {
firm_kind kind; /**< A type tag, set to k_ir_loop. */
unsigned depth; /**< Nesting depth */
- size_t n_sons; /**< Number of ir_nodes in array "children" */
- size_t n_nodes; /**< Number of loop_nodes in array "children" */
unsigned flags; /**< a set of loop_flags_t */
struct ir_loop *outer_loop; /**< The outer loop */
loop_element *children; /**< Mixed flexible array: Contains sons and loop_nodes */
return loop->depth;
}
-static inline size_t _get_loop_n_sons(const ir_loop *loop)
-{
- assert(_is_ir_loop(loop));
- return loop->n_sons;
-}
-
/* Uses temporary information to get the loop */
static inline ir_loop *_get_irn_loop(const ir_node *n)
{
#define get_irg_loop(irg) _get_irg_loop(irg)
#define get_loop_outer_loop(loop) _get_loop_outer_loop(loop)
#define get_loop_depth(loop) _get_loop_depth(loop)
-#define get_loop_n_sons(loop) _get_loop_n_sons(loop)
#define get_irn_loop(n) _get_irn_loop(n)
#endif
}
}
-static void dump_loop_label(FILE *F, ir_loop *loop)
+static void dump_loop_label(FILE *F, const ir_loop *loop)
{
- fprintf(F, "loop %u, %lu sons, %lu nodes",
- get_loop_depth(loop), (unsigned long) get_loop_n_sons(loop),
- (unsigned long) get_loop_n_nodes(loop));
+ fprintf(F, "loop %u", get_loop_depth(loop));
}
-static void dump_loop_info(FILE *F, ir_loop *loop)
+static void dump_loop_info(FILE *F, const ir_loop *loop)
{
fprintf(F, " info1: \"");
fprintf(F, " loop nr: %ld", get_loop_loop_nr(loop));
fprintf(F, "\"");
}
-static void dump_loop_node(FILE *F, ir_loop *loop)
+static void dump_loop_node(FILE *F, const ir_loop *loop)
{
fprintf(F, "node: {title: \"");
PRINT_LOOPID(loop);
fprintf(F, "}\n");
}
-static void dump_loop_node_edge(FILE *F, ir_loop *loop, size_t i)
+static void dump_loop_node_edge(FILE *F, const ir_loop *loop, size_t i)
{
assert(loop);
fprintf(F, "edge: {sourcename: \"");
PRINT_LOOPID(loop);
fprintf(F, "\" targetname: \"");
- PRINT_NODEID(get_loop_node(loop, i));
+ PRINT_NODEID(get_loop_element(loop, i).node);
fprintf(F, "\" color: green");
fprintf(F, "}\n");
}
-static void dump_loop_son_edge(FILE *F, ir_loop *loop, size_t i)
+static void dump_loop_son_edge(FILE *F, const ir_loop *loop, size_t i)
{
assert(loop);
fprintf(F, "edge: {sourcename: \"");
PRINT_LOOPID(loop);
fprintf(F, "\" targetname: \"");
- PRINT_LOOPID(get_loop_son(loop, i));
- ir_fprintf(F, "\" color: darkgreen label: \"%zu\"}\n",
- get_loop_element_pos(loop, get_loop_son(loop, i)));
+ PRINT_LOOPID(get_loop_element(loop, i).son);
+ ir_fprintf(F, "\" color: darkgreen label: \"%zu\"}\n", i);
}
-static void dump_loops(FILE *F, ir_loop *loop)
+static void dump_loops(FILE *F, const ir_loop *loop)
{
size_t i;
+ size_t n_elements = get_loop_n_elements(loop);
/* dump this loop node */
dump_loop_node(F, loop);
/* dump edges to nodes in loop -- only if it is a real loop */
if (get_loop_depth(loop) != 0) {
- for (i = get_loop_n_nodes(loop); i > 0;) {
+ for (i = n_elements; i > 0;) {
+ loop_element element;
--i;
+ element = get_loop_element(loop, i);
+ if (*element.kind != k_ir_node)
+ continue;
dump_loop_node_edge(F, loop, i);
}
}
- for (i = get_loop_n_sons(loop); i > 0;) {
- --i;
- dump_loops(F, get_loop_son(loop, i));
+ for (i = n_elements; i > 0;) {
+ loop_element element;
+ --i;
+ element = get_loop_element(loop, i);
+ if (*element.kind != k_ir_loop)
+ continue;
+ dump_loops(F, element.son);
dump_loop_son_edge(F, loop, i);
}
}
/* Reset loop info */
memset(&loop_info, 0, sizeof(loop_info_t));
- DB((dbg, LEVEL_1, " >>>> current loop includes node %N <<<\n",
- get_loop_node(loop, 0)));
+ DB((dbg, LEVEL_1, " >>>> current loop %ld <<<\n",
+ get_loop_loop_nr(loop)));
/* Collect loop informations: head, node counts. */
irg_walk_graph(irg, get_loop_info, NULL, NULL);
default:
panic("Loop optimization not implemented.");
}
- DB((dbg, LEVEL_1, " <<<< end of loop with node %N >>>>\n",
- get_loop_node(loop, 0)));
+ DB((dbg, LEVEL_1, " <<<< end of loop with node %ld >>>>\n",
+ get_loop_loop_nr(loop)));
}
/* Find innermost loops and add them to loops. */
static void find_innermost_loop(ir_loop *loop)
{
- /* descend into sons */
- size_t sons = get_loop_n_sons(loop);
-
- if (sons == 0) {
- ARR_APP1(ir_loop *, loops, loop);
- } else {
- size_t s;
- for (s = 0; s < sons; ++s) {
- find_innermost_loop(get_loop_son(loop, s));
+ bool had_sons = false;
+ size_t n_elements = get_loop_n_elements(loop);
+ size_t e;
+
+ for (e = 0; e < n_elements; ++e) {
+ loop_element element = get_loop_element(loop, e);
+ if (*element.kind == k_ir_loop) {
+ find_innermost_loop(element.son);
+ had_sons = true;
}
}
+
+ if (!had_sons) {
+ ARR_APP1(ir_loop*, loops, loop);
+ }
}
static void set_loop_params(void)
void loop_optimization(ir_graph *irg)
{
ir_loop *loop;
- size_t sons, nr;
- size_t i;
+ size_t i;
+ size_t n_elements;
set_loop_params();
collect_phiprojs(irg);
loop = get_irg_loop(irg);
- sons = get_loop_n_sons(loop);
loops = NEW_ARR_F(ir_loop *, 0);
/* List all inner loops */
- for (nr = 0; nr < sons; ++nr) {
- find_innermost_loop(get_loop_son(loop, nr));
+ n_elements = get_loop_n_elements(loop);
+ for (i = 0; i < n_elements; ++i) {
+ loop_element element = get_loop_element(loop, i);
+ if (*element.kind != k_ir_loop)
+ continue;
+ find_innermost_loop(element.son);
}
/* Set all links to NULL */