Commit 599f2d24 authored by Matthias Braun's avatar Matthias Braun
Browse files

toposort callgraph when inlining

[r22177]
parent 6df2132c
......@@ -126,7 +126,8 @@ typedef void callgraph_walk_func(ir_graph *g, void *env);
* @param post - walker function, executed after the predecessor of a node are visited
* @param env - environment, passed to pre and post
*/
void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *env);
void callgraph_walk(ir_entity **roots, unsigned n_roots,
callgraph_walk_func *pre, callgraph_walk_func *post, void *env);
/**
* Compute the backedges that represent recursions and a looptree.
......
......@@ -52,10 +52,10 @@
#include "irgwalk.h"
static int master_cg_visited = 0;
static INLINE int cg_irg_visited (ir_graph *n);
static unsigned long master_cg_visited = 0;
static INLINE int cg_irg_visited (ir_graph *n);
static INLINE void mark_cg_irg_visited(ir_graph *n);
static INLINE void set_cg_irg_visited (ir_graph *n, int i);
static INLINE void set_cg_irg_visited (ir_graph *n, unsigned long i);
/** Returns the callgraph state of the program representation. */
irp_callgraph_state get_irp_callgraph_state(void) {
......@@ -386,11 +386,21 @@ static void do_walk(ir_graph *irg, callgraph_walk_func *pre, callgraph_walk_func
post(irg, env);
}
void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
int i, n_irgs = get_irp_n_irgs();
void callgraph_walk(ir_entity **roots, unsigned n_roots,
callgraph_walk_func *pre, callgraph_walk_func *post, void *env) {
//int i, n_irgs = get_irp_n_irgs();
unsigned r;
++master_cg_visited;
do_walk(get_irp_main_irg(), pre, post, env);
for (r = 0; r < n_roots; ++r) {
ir_graph *irg = get_entity_irg(roots[r]);
if (irg == NULL)
continue;
do_walk(irg, pre, post, env);
}
#if 0
for (i = 0; i < n_irgs; i++) {
ir_graph *irg = get_irp_irg(i);
if (!cg_irg_visited(irg) && get_irg_n_callers(irg) == 0)
......@@ -401,6 +411,7 @@ void callgraph_walk(callgraph_walk_func *pre, callgraph_walk_func *post, void *e
if (!cg_irg_visited(irg))
do_walk(irg, pre, post, env);
}
#endif
}
/* ----------------------------------------------------------------------------------- */
......@@ -441,36 +452,28 @@ static INLINE scc_info *new_scc_info(struct obstack *obst) {
* Returns non-zero if a graph was already visited.
*/
static INLINE int cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
assert(info && "missing call to init_scc()");
return info->visited >= master_cg_visited;
return irg->self_visited >= master_cg_visited;
}
/**
* Marks a graph as visited.
*/
static INLINE void mark_cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
assert(info && "missing call to init_scc()");
info->visited = master_cg_visited;
irg->self_visited = master_cg_visited;
}
/**
* Set a graphs visited flag to i.
*/
static INLINE void set_cg_irg_visited(ir_graph *irg, int i) {
scc_info *info = get_irg_link(irg);
assert(info && "missing call to init_scc()");
info->visited = i;
static INLINE void set_cg_irg_visited(ir_graph *irg, unsigned long i) {
irg->self_visited = i;
}
/**
* Returns the visited flag of a graph.
*/
static INLINE int get_cg_irg_visited(ir_graph *irg) {
scc_info *info = get_irg_link(irg);
assert(info && "missing call to init_scc()");
return info->visited;
static INLINE unsigned long get_cg_irg_visited(ir_graph *irg) {
return irg->self_visited;
}
static INLINE void mark_irg_in_stack(ir_graph *irg) {
......@@ -1015,7 +1018,7 @@ static void reset_isbe(void) {
static void compute_loop_depth(ir_graph *irg, void *env) {
int current_nesting = *(int *) env;
int old_nesting = irg->callgraph_loop_depth;
int old_visited = get_cg_irg_visited(irg);
unsigned long old_visited = get_cg_irg_visited(irg);
int i, n_callees;
//return ;
......
......@@ -496,6 +496,8 @@ struct ir_graph {
the graph */
unsigned long block_visited; /**< same as visited, for a complete block */
unsigned long self_visited; /**< visited flag of the irg */
unsigned estimated_node_count; /**< estimated number of nodes in this graph,
updated after every walk */
irg_edges_info_t edge_info; /**< edge info for automatic outs */
......
......@@ -2007,6 +2007,35 @@ static int calc_inline_benefice(ir_node *call, ir_graph *callee, unsigned *local
return weight;
}
static ir_graph **irgs;
static int last_irg;
static void callgraph_walker(ir_graph *irg, void *data)
{
(void) data;
irgs[last_irg++] = irg;
}
static ir_graph **create_irg_list(void)
{
ir_entity **roots;
int arr_len;
int n_irgs = get_irp_n_irgs();
cgana(&arr_len, &roots);
compute_callgraph();
last_irg = 0;
irgs = xmalloc(n_irgs * sizeof(*irgs));
memset(irgs, 0, sizeof(n_irgs * sizeof(*irgs)));
callgraph_walk(roots, arr_len, NULL, callgraph_walker, NULL);
xfree(roots);
assert(n_irgs == last_irg);
return irgs;
}
/**
* Heuristic inliner. Calculates a benefice value for every call and inlines
* those calls with a value higher than the threshold.
......@@ -2021,23 +2050,26 @@ void inline_functions(int maxsize, int inline_threshold) {
const call_entry *centry;
pmap *copied_graphs;
pmap_entry *pm_entry;
ir_graph **irgs;
rem = current_ir_graph;
obstack_init(&temp_obst);
irgs = create_irg_list();
/* a map for the copied graphs, used to inline recursive calls */
copied_graphs = pmap_create();
/* extend all irgs by a temporary data structure for inlining. */
n_irgs = get_irp_n_irgs();
for (i = 0; i < n_irgs; ++i)
set_irg_link(get_irp_irg(i), alloc_inline_irg_env());
set_irg_link(irgs[i], alloc_inline_irg_env());
/* Precompute information in temporary data structure. */
wenv.ignore_runtime = 0;
wenv.ignore_callers = 0;
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
ir_graph *irg = irgs[i];
assert(get_irg_phase_state(irg) != phase_building);
free_callee_info(irg);
......@@ -2052,7 +2084,7 @@ void inline_functions(int maxsize, int inline_threshold) {
for (i = 0; i < n_irgs; ++i) {
int phiproj_computed = 0;
ir_node *call;
ir_graph *irg = get_irp_irg(i);
ir_graph *irg = irgs[i];
current_ir_graph = irg;
env = get_irg_link(irg);
......@@ -2169,7 +2201,7 @@ void inline_functions(int maxsize, int inline_threshold) {
}
for (i = 0; i < n_irgs; ++i) {
ir_graph *irg = get_irp_irg(i);
ir_graph *irg = irgs[i];
env = get_irg_link(irg);
if (env->got_inline) {
......@@ -2203,6 +2235,8 @@ void inline_functions(int maxsize, int inline_threshold) {
}
pmap_destroy(copied_graphs);
xfree(irgs);
obstack_free(&temp_obst, NULL);
current_ir_graph = rem;
}
......
Markdown is supported
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