X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_inline.c;h=7f0998b6d1a61e95b1e0a6e62f876ec6eb8e63c7;hb=f864dbddcf026827e85d49544abbb002841a5405;hp=5ee6def660d718fd10b30b4729f09d140eb58cdd;hpb=e621040cc93398aede0043e19d7852705b95382c;p=libfirm diff --git a/ir/opt/opt_inline.c b/ir/opt/opt_inline.c index 5ee6def66..7f0998b6d 100644 --- a/ir/opt/opt_inline.c +++ b/ir/opt/opt_inline.c @@ -41,13 +41,13 @@ #include "irgmod.h" #include "irgwalk.h" -#include "adt/array.h" -#include "adt/list.h" -#include "adt/pset.h" -#include "adt/pmap.h" -#include "adt/pdeq.h" -#include "adt/xmalloc.h" -#include "adt/pqueue.h" +#include "array_t.h" +#include "list.h" +#include "pset.h" +#include "pmap.h" +#include "pdeq.h" +#include "xmalloc.h" +#include "pqueue.h" #include "irouts.h" #include "irloop_t.h" @@ -784,7 +784,7 @@ static void find_addr(ir_node *node, void *env) { * using alloca is called in loop. In GCC present in SPEC2000 inlining * into schedule_block cause it to require 2GB of ram instead of 256MB. * - * Sorryly this is true with our implementation also. + * Sorrily this is true with our implementation also. * Moreover, we cannot differentiate between alloca() and VLA yet, so this * disables inlining of functions using VLA (with are completely save). * @@ -1233,28 +1233,28 @@ int inline_method(ir_node *call, ir_graph *called_graph) { } /********************************************************************/ -/* Apply inlineing to small methods. */ +/* Apply inlining to small methods. */ /********************************************************************/ static struct obstack temp_obst; /** Represents a possible inlinable call in a graph. */ typedef struct _call_entry { - ir_node *call; /**< the Call node */ - ir_graph *callee; /**< the callee IR-graph called here */ - list_head list; /**< for linking the next one */ - int loop_depth; /**< the loop depth of this call */ - int benefice; /**< calculated benefice of this call */ - unsigned local_adr:1; /**< Set if this calls get an address of a local variable. */ - unsigned all_const:1; /**< Set if this calls has only constant parameters. */ + ir_node *call; /**< The Call node. */ + ir_graph *callee; /**< The callee IR-graph. */ + list_head list; /**< List head for linking the next one. */ + int loop_depth; /**< The loop depth of this call. */ + int benefice; /**< The calculated benefice of this call. */ + unsigned local_adr:1; /**< Set if this call gets an address of a local variable. */ + unsigned all_const:1; /**< Set if this call has only constant parameters. */ } call_entry; /** * environment for inlining small irgs */ typedef struct _inline_env_t { - struct obstack obst; /**< an obstack where call_entries are allocated on. */ - list_head calls; /**< the call entry list */ + struct obstack obst; /**< An obstack where call_entries are allocated on. */ + list_head calls; /**< The call entry list. */ } inline_env_t; /** @@ -1318,10 +1318,10 @@ void inline_small_irgs(ir_graph *irg, int size) { free_callee_info(irg); /* Find Call nodes to inline. - (We can not inline during a walk of the graph, as inlineing the same + (We can not inline during a walk of the graph, as inlining the same method several times changes the visited flag of the walked graph: - after the first inlineing visited of the callee equals visited of - the caller. With the next inlineing both are increased.) */ + after the first inlining visited of the callee equals visited of + the caller. With the next inlining both are increased.) */ obstack_init(&env.obst); INIT_LIST_HEAD(&env.calls); irg_walk_graph(irg, NULL, collect_calls, &env); @@ -1448,6 +1448,9 @@ static void collect_calls2(ir_node *call, void *ctx) { entry->call = call; entry->callee = callee; entry->loop_depth = get_irn_loop(get_nodes_block(call))->depth; + entry->benefice = 0; + entry->local_adr = 0; + entry->all_const = 0; list_add_tail(&entry->list, &x->calls); } @@ -1547,7 +1550,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, for (i = 0; i < n_irgs; ++i) set_irg_link(get_irp_irg(i), alloc_inline_irg_env()); - /* Precompute information in temporary data structure. */ + /* Pre-compute information in temporary data structure. */ wenv.ignore_runtime = ignore_runtime; wenv.ignore_callers = 0; for (i = 0; i < n_irgs; ++i) { @@ -1601,7 +1604,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, if (did_inline) { inline_irg_env *callee_env = get_irg_link(callee); - /* was inlined, must be recomputed */ + /* call was inlined, Phi/Projs for current graph must be recomputed */ phiproj_computed = 0; /* Do some statistics */ @@ -1704,7 +1707,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, if (did_inline) { inline_irg_env *callee_env = (inline_irg_env *)get_irg_link(callee); - /* was inlined, must be recomputed */ + /* call was inlined, Phi/Projs for current graph must be recomputed */ phiproj_computed = 0; /* callee was inline. Append it's call list. */ @@ -2019,8 +2022,7 @@ static ir_graph **create_irg_list(void) { } /** - * Push a call onto the priority list if its - * benefice is big enough. + * Push a call onto the priority list if its benefice is big enough. * * @param pqueue the priority queue of calls * @param call the call entry @@ -2030,24 +2032,16 @@ static ir_graph **create_irg_list(void) { static void maybe_push_call(pqueue_t *pqueue, call_entry *call, int inline_threshold) { - int benefice; ir_graph *callee = call->callee; irg_inline_property prop = get_irg_inline_property(callee); + int benefice = calc_inline_benefice(call, callee); - if (prop & irg_inline_forced) { - /* give them a big benefice, so forced are inline first */ - benefice = 100000 + call->loop_depth; - call->benefice = benefice; - DB((dbg, LEVEL_2, "In %+F Call %+F to %+F is forced\n", - get_irn_irg(call->call), call->call, callee)); - } else { - benefice = calc_inline_benefice(call, callee); - DB((dbg, LEVEL_2, "In %+F Call %+F to %+F has benefice %d\n", - get_irn_irg(call->call), call->call, callee, benefice)); - } + DB((dbg, LEVEL_2, "In %+F Call %+F to %+F has benefice %d\n", + get_irn_irg(call->call), call->call, callee, benefice)); - if (benefice < inline_threshold && !(prop & irg_inline_forced)) + if (prop < irg_inline_forced && benefice < inline_threshold) { return; + } pqueue_put(pqueue, call, benefice); } @@ -2097,13 +2091,12 @@ static void inline_into(ir_graph *irg, unsigned maxsize, ir_graph *callee = curr_call->callee; ir_node *call_node = curr_call->call; inline_irg_env *callee_env = get_irg_link(callee); + irg_inline_property prop = get_irg_inline_property(callee); int loop_depth; const call_entry *centry; pmap_entry *e; - /* we need a hard limit here, else it would be possible to inline - * recursive functions forever. */ - if (env->n_nodes + callee_env->n_nodes > maxsize) { + if ((prop < irg_inline_forced) && env->n_nodes + callee_env->n_nodes > maxsize) { DB((dbg, LEVEL_2, "%+F: too big (%d) + %+F (%d)\n", irg, env->n_nodes, callee, callee_env->n_nodes)); continue; @@ -2187,7 +2180,7 @@ static void inline_into(ir_graph *irg, unsigned maxsize, if (!did_inline) continue; - /* got inlined, must be recomputed */ + /* call was inlined, Phi/Projs for current graph must be recomputed */ phiproj_computed = 0; /* remove it from the caller list */ @@ -2229,7 +2222,7 @@ static void inline_into(ir_graph *irg, unsigned maxsize, del_pqueue(pqueue); } -/** +/* * Heuristic inliner. Calculates a benefice value for every call and inlines * those calls with a value higher than the threshold. */ @@ -2255,7 +2248,7 @@ void inline_functions(unsigned maxsize, int inline_threshold) { for (i = 0; i < n_irgs; ++i) set_irg_link(irgs[i], alloc_inline_irg_env()); - /* Precompute information in temporary data structure. */ + /* Pre-compute information in temporary data structure. */ wenv.ignore_runtime = 0; wenv.ignore_callers = 0; for (i = 0; i < n_irgs; ++i) { @@ -2281,22 +2274,18 @@ void inline_functions(unsigned maxsize, int inline_threshold) { env = get_irg_link(irg); if (env->got_inline) { /* this irg got calls inlined: optimize it */ - - if (0) { - /* scalar replacement does not work well with Tuple nodes, so optimize them away */ - optimize_graph_df(irg); - + if (get_opt_combo()) { + if (env->local_vars) { + scalar_replacement_opt(irg); + } + combo(irg); + } else { if (env->local_vars) { if (scalar_replacement_opt(irg)) { optimize_graph_df(irg); } } optimize_cf(irg); - } else { - if (env->local_vars) { - scalar_replacement_opt(irg); - } - combo(irg); } } if (env->got_inline || (env->n_callers_orig != env->n_callers)) {