Commit f8526c84 authored by Matthias Braun's avatar Matthias Braun
Browse files

irloop: remove get_loop_son, get_loop_node

The interface was really inefficient and shouldn't be used like that.
So simply don't provide functions that make inefficient code convenient.
parent 6ce434e9
...@@ -72,20 +72,6 @@ FIRM_API ir_loop *get_loop_outer_loop(const ir_loop *loop); ...@@ -72,20 +72,6 @@ FIRM_API ir_loop *get_loop_outer_loop(const ir_loop *loop);
/** Returns nesting depth of this loop */ /** Returns nesting depth of this loop */
FIRM_API unsigned get_loop_depth(const ir_loop *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. */ /** Returns the number of elements contained in loop. */
FIRM_API size_t get_loop_n_elements(const ir_loop *loop); FIRM_API size_t get_loop_n_elements(const ir_loop *loop);
...@@ -93,12 +79,6 @@ FIRM_API size_t get_loop_n_elements(const ir_loop *loop); ...@@ -93,12 +79,6 @@ FIRM_API size_t get_loop_n_elements(const ir_loop *loop);
kind pointer, an ir_node* or an ir_loop*. */ kind pointer, an ir_node* or an ir_loop*. */
FIRM_API loop_element get_loop_element(const ir_loop *loop, size_t pos); 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 /** 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 readable. If libfirm_debug is not set it returns the loop cast to
int. */ int. */
......
...@@ -40,7 +40,6 @@ void add_loop_son(ir_loop *loop, ir_loop *son) ...@@ -40,7 +40,6 @@ void add_loop_son(ir_loop *loop, ir_loop *son)
assert(get_kind(son) == k_ir_loop); assert(get_kind(son) == k_ir_loop);
lson.son = son; lson.son = son;
ARR_APP1(loop_element, loop->children, lson); ARR_APP1(loop_element, loop->children, lson);
++loop->n_sons;
loop->flags |= loop_outer_loop; loop->flags |= loop_outer_loop;
} }
...@@ -50,7 +49,6 @@ void add_loop_node(ir_loop *loop, ir_node *n) ...@@ -50,7 +49,6 @@ void add_loop_node(ir_loop *loop, ir_node *n)
ln.node = n; ln.node = n;
assert(loop && loop->kind == k_ir_loop); assert(loop && loop->kind == k_ir_loop);
ARR_APP1(loop_element, loop->children, ln); ARR_APP1(loop_element, loop->children, ln);
loop->n_nodes++;
} }
void add_loop_irg(ir_loop *loop, ir_graph *irg) void add_loop_irg(ir_loop *loop, ir_graph *irg)
...@@ -59,7 +57,6 @@ void add_loop_irg(ir_loop *loop, ir_graph *irg) ...@@ -59,7 +57,6 @@ void add_loop_irg(ir_loop *loop, ir_graph *irg)
ln.irg = irg; ln.irg = irg;
assert(loop && loop->kind == k_ir_loop); assert(loop && loop->kind == k_ir_loop);
ARR_APP1(loop_element, loop->children, ln); ARR_APP1(loop_element, loop->children, ln);
loop->n_nodes++;
} }
/** /**
...@@ -70,20 +67,18 @@ void add_loop_irg(ir_loop *loop, ir_graph *irg) ...@@ -70,20 +67,18 @@ void add_loop_irg(ir_loop *loop, ir_graph *irg)
*/ */
void mature_loops(ir_loop *loop, struct obstack *obst) void mature_loops(ir_loop *loop, struct obstack *obst)
{ {
size_t i;
loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children); loop_element *new_children = DUP_ARR_D(loop_element, obst, loop->children);
DEL_ARR_F(loop->children); DEL_ARR_F(loop->children);
loop->children = new_children; loop->children = new_children;
if (loop->n_sons > 0) { /* mature child loops */
/* we have child loops, mature them */ for (i = ARR_LEN(new_children); i > 0;) {
size_t i; loop_element child = new_children[--i];
for (i = ARR_LEN(new_children); i > 0;) { if (*child.kind == k_ir_loop) {
loop_element child = new_children[--i]; mature_loops(child.son, obst);
if (*child.kind == k_ir_loop) {
mature_loops(child.son, obst);
}
} }
} }
} }
...@@ -100,60 +95,6 @@ unsigned (get_loop_depth)(const ir_loop *loop) ...@@ -100,60 +95,6 @@ unsigned (get_loop_depth)(const ir_loop *loop)
return _get_loop_depth(loop); 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. */ /* Returns the number of elements contained in loop. */
size_t get_loop_n_elements(const ir_loop *loop) size_t get_loop_n_elements(const ir_loop *loop)
{ {
...@@ -167,20 +108,6 @@ loop_element get_loop_element(const ir_loop *loop, size_t pos) ...@@ -167,20 +108,6 @@ loop_element get_loop_element(const ir_loop *loop, size_t pos)
return(loop -> children[pos]); 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. * Sets the loop for a node.
*/ */
...@@ -244,8 +171,6 @@ ir_loop *alloc_loop(ir_loop *father, struct obstack *obst) ...@@ -244,8 +171,6 @@ ir_loop *alloc_loop(ir_loop *father, struct obstack *obst)
son = OALLOCZ(obst, ir_loop); son = OALLOCZ(obst, ir_loop);
son->kind = k_ir_loop; son->kind = k_ir_loop;
son->children = NEW_ARR_F(loop_element, 0); son->children = NEW_ARR_F(loop_element, 0);
son->n_nodes = 0;
son->n_sons = 0;
son->link = NULL; son->link = NULL;
if (father) { if (father) {
son->outer_loop = father; son->outer_loop = father;
......
...@@ -63,8 +63,6 @@ typedef enum loop_flags { ...@@ -63,8 +63,6 @@ typedef enum loop_flags {
struct ir_loop { struct ir_loop {
firm_kind kind; /**< A type tag, set to k_ir_loop. */ firm_kind kind; /**< A type tag, set to k_ir_loop. */
unsigned depth; /**< Nesting depth */ 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 */ unsigned flags; /**< a set of loop_flags_t */
struct ir_loop *outer_loop; /**< The outer loop */ struct ir_loop *outer_loop; /**< The outer loop */
loop_element *children; /**< Mixed flexible array: Contains sons and loop_nodes */ loop_element *children; /**< Mixed flexible array: Contains sons and loop_nodes */
...@@ -135,12 +133,6 @@ static inline unsigned _get_loop_depth(const ir_loop *loop) ...@@ -135,12 +133,6 @@ static inline unsigned _get_loop_depth(const ir_loop *loop)
return loop->depth; 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 */ /* Uses temporary information to get the loop */
static inline ir_loop *_get_irn_loop(const ir_node *n) static inline ir_loop *_get_irn_loop(const ir_node *n)
{ {
...@@ -152,7 +144,6 @@ static inline ir_loop *_get_irn_loop(const ir_node *n) ...@@ -152,7 +144,6 @@ static inline ir_loop *_get_irn_loop(const ir_node *n)
#define get_irg_loop(irg) _get_irg_loop(irg) #define get_irg_loop(irg) _get_irg_loop(irg)
#define get_loop_outer_loop(loop) _get_loop_outer_loop(loop) #define get_loop_outer_loop(loop) _get_loop_outer_loop(loop)
#define get_loop_depth(loop) _get_loop_depth(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) #define get_irn_loop(n) _get_irn_loop(n)
#endif #endif
...@@ -1891,14 +1891,12 @@ static void dump_out_edge(ir_node *n, void *env) ...@@ -1891,14 +1891,12 @@ static void dump_out_edge(ir_node *n, void *env)
} }
} }
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", fprintf(F, "loop %u", get_loop_depth(loop));
get_loop_depth(loop), (unsigned long) get_loop_n_sons(loop),
(unsigned long) get_loop_n_nodes(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, " info1: \"");
fprintf(F, " loop nr: %ld", get_loop_loop_nr(loop)); fprintf(F, " loop nr: %ld", get_loop_loop_nr(loop));
...@@ -1908,7 +1906,7 @@ static void dump_loop_info(FILE *F, ir_loop *loop) ...@@ -1908,7 +1906,7 @@ static void dump_loop_info(FILE *F, ir_loop *loop)
fprintf(F, "\""); 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: \""); fprintf(F, "node: {title: \"");
PRINT_LOOPID(loop); PRINT_LOOPID(loop);
...@@ -1919,44 +1917,52 @@ static void dump_loop_node(FILE *F, ir_loop *loop) ...@@ -1919,44 +1917,52 @@ static void dump_loop_node(FILE *F, ir_loop *loop)
fprintf(F, "}\n"); 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); assert(loop);
fprintf(F, "edge: {sourcename: \""); fprintf(F, "edge: {sourcename: \"");
PRINT_LOOPID(loop); PRINT_LOOPID(loop);
fprintf(F, "\" targetname: \""); fprintf(F, "\" targetname: \"");
PRINT_NODEID(get_loop_node(loop, i)); PRINT_NODEID(get_loop_element(loop, i).node);
fprintf(F, "\" color: green"); fprintf(F, "\" color: green");
fprintf(F, "}\n"); 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); assert(loop);
fprintf(F, "edge: {sourcename: \""); fprintf(F, "edge: {sourcename: \"");
PRINT_LOOPID(loop); PRINT_LOOPID(loop);
fprintf(F, "\" targetname: \""); fprintf(F, "\" targetname: \"");
PRINT_LOOPID(get_loop_son(loop, i)); PRINT_LOOPID(get_loop_element(loop, i).son);
ir_fprintf(F, "\" color: darkgreen label: \"%zu\"}\n", ir_fprintf(F, "\" color: darkgreen label: \"%zu\"}\n", i);
get_loop_element_pos(loop, get_loop_son(loop, 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 i;
size_t n_elements = get_loop_n_elements(loop);
/* dump this loop node */ /* dump this loop node */
dump_loop_node(F, loop); dump_loop_node(F, loop);
/* dump edges to nodes in loop -- only if it is a real loop */ /* dump edges to nodes in loop -- only if it is a real loop */
if (get_loop_depth(loop) != 0) { 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; --i;
element = get_loop_element(loop, i);
if (*element.kind != k_ir_node)
continue;
dump_loop_node_edge(F, loop, i); dump_loop_node_edge(F, loop, i);
} }
} }
for (i = get_loop_n_sons(loop); i > 0;) { for (i = n_elements; i > 0;) {
--i; loop_element element;
dump_loops(F, get_loop_son(loop, i)); --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); dump_loop_son_edge(F, loop, i);
} }
} }
......
...@@ -2596,8 +2596,8 @@ static void init_analyze(ir_graph *irg, ir_loop *loop) ...@@ -2596,8 +2596,8 @@ static void init_analyze(ir_graph *irg, ir_loop *loop)
/* Reset loop info */ /* Reset loop info */
memset(&loop_info, 0, sizeof(loop_info_t)); memset(&loop_info, 0, sizeof(loop_info_t));
DB((dbg, LEVEL_1, " >>>> current loop includes node %N <<<\n", DB((dbg, LEVEL_1, " >>>> current loop %ld <<<\n",
get_loop_node(loop, 0))); get_loop_loop_nr(loop)));
/* Collect loop informations: head, node counts. */ /* Collect loop informations: head, node counts. */
irg_walk_graph(irg, get_loop_info, NULL, NULL); irg_walk_graph(irg, get_loop_info, NULL, NULL);
...@@ -2629,24 +2629,28 @@ static void init_analyze(ir_graph *irg, ir_loop *loop) ...@@ -2629,24 +2629,28 @@ static void init_analyze(ir_graph *irg, ir_loop *loop)
default: default:
panic("Loop optimization not implemented."); panic("Loop optimization not implemented.");
} }
DB((dbg, LEVEL_1, " <<<< end of loop with node %N >>>>\n", DB((dbg, LEVEL_1, " <<<< end of loop with node %ld >>>>\n",
get_loop_node(loop, 0))); get_loop_loop_nr(loop)));
} }
/* Find innermost loops and add them to loops. */ /* Find innermost loops and add them to loops. */
static void find_innermost_loop(ir_loop *loop) static void find_innermost_loop(ir_loop *loop)
{ {
/* descend into sons */ bool had_sons = false;
size_t sons = get_loop_n_sons(loop); size_t n_elements = get_loop_n_elements(loop);
size_t e;
if (sons == 0) {
ARR_APP1(ir_loop *, loops, loop); for (e = 0; e < n_elements; ++e) {
} else { loop_element element = get_loop_element(loop, e);
size_t s; if (*element.kind == k_ir_loop) {
for (s = 0; s < sons; ++s) { find_innermost_loop(element.son);
find_innermost_loop(get_loop_son(loop, s)); had_sons = true;
} }
} }
if (!had_sons) {
ARR_APP1(ir_loop*, loops, loop);
}
} }
static void set_loop_params(void) static void set_loop_params(void)
...@@ -2672,8 +2676,8 @@ static void set_loop_params(void) ...@@ -2672,8 +2676,8 @@ static void set_loop_params(void)
void loop_optimization(ir_graph *irg) void loop_optimization(ir_graph *irg)
{ {
ir_loop *loop; ir_loop *loop;
size_t sons, nr; size_t i;
size_t i; size_t n_elements;
set_loop_params(); set_loop_params();
...@@ -2687,12 +2691,15 @@ void loop_optimization(ir_graph *irg) ...@@ -2687,12 +2691,15 @@ void loop_optimization(ir_graph *irg)
collect_phiprojs(irg); collect_phiprojs(irg);
loop = get_irg_loop(irg); loop = get_irg_loop(irg);
sons = get_loop_n_sons(loop);
loops = NEW_ARR_F(ir_loop *, 0); loops = NEW_ARR_F(ir_loop *, 0);
/* List all inner loops */ /* List all inner loops */
for (nr = 0; nr < sons; ++nr) { n_elements = get_loop_n_elements(loop);
find_innermost_loop(get_loop_son(loop, nr)); 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 */ /* Set all links to NULL */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment