X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fopt_inline.c;h=edadecd660a781f96cbb63b25585e0a77ea4ca15;hb=d5d7159c209a9e5c5fa276f770b5b28a217990a8;hp=7b868aa4fc66e2287a7ca7895654d33d31695068;hpb=ab182d4b9ed44239ab3ff1d08b2f8e14a3699ccf;p=libfirm diff --git a/ir/opt/opt_inline.c b/ir/opt/opt_inline.c index 7b868aa4f..edadecd66 100644 --- a/ir/opt/opt_inline.c +++ b/ir/opt/opt_inline.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * Copyright (C) 1995-2011 University of Karlsruhe. All right reserved. * * This file is part of libFirm. * @@ -108,7 +108,6 @@ static void copy_node_inline(ir_node *node, void *env) ir_node *new_node = irn_copy_into_irg(node, new_irg); set_new_node(node, new_node); - if (is_Sel(node)) { ir_graph *old_irg = get_irn_irg(node); ir_type *old_frame_type = get_irg_frame_type(old_irg); @@ -116,7 +115,7 @@ static void copy_node_inline(ir_node *node, void *env) assert(is_Sel(new_node)); /* use copied entities from the new frame */ if (get_entity_owner(old_entity) == old_frame_type) { - ir_entity *new_entity = get_entity_link(old_entity); + ir_entity *new_entity = (ir_entity*)get_entity_link(old_entity); assert(new_entity != NULL); set_Sel_entity(new_node, new_entity); } @@ -145,7 +144,7 @@ static void set_preds_inline(ir_node *node, void *env) */ static void find_addr(ir_node *node, void *env) { - bool *allow_inline = env; + bool *allow_inline = (bool*)env; if (is_Sel(node)) { ir_graph *irg = current_ir_graph; @@ -191,11 +190,11 @@ static bool can_inline(ir_node *call, ir_graph *called_graph) ir_entity *called = get_irg_entity(called_graph); ir_type *called_type = get_entity_type(called); ir_type *call_type = get_Call_type(call); - int n_params = get_method_n_params(called_type); - int n_arguments = get_method_n_params(call_type); - int n_res = get_method_n_ress(called_type); + size_t n_params = get_method_n_params(called_type); + size_t n_arguments = get_method_n_params(call_type); + size_t n_res = get_method_n_ress(called_type); irg_inline_property prop = get_irg_inline_property(called_graph); - int i; + size_t i; bool res; if (prop == irg_inline_forbidden) @@ -215,7 +214,7 @@ static bool can_inline(ir_node *call, ir_graph *called_graph) * It is implementation dependent what happens in that case. * We support inlining, if the bitsize of the types matches AND * the same arithmetic is used. */ - for (i = n_params - 1; i >= 0; --i) { + for (i = 0; i < n_params; ++i) { ir_type *param_tp = get_method_param_type(called_type, i); ir_type *arg_tp = get_method_param_type(call_type, i); @@ -232,7 +231,7 @@ static bool can_inline(ir_node *call, ir_graph *called_graph) /* otherwise we can simply "reinterpret" the bits */ } } - for (i = n_res - 1; i >= 0; --i) { + for (i = 0; i < n_res; ++i) { ir_type *decl_res_tp = get_method_res_type(called_type, i); ir_type *used_res_tp = get_method_res_type(call_type, i); @@ -284,8 +283,8 @@ static void copy_frame_entities(ir_graph *from, ir_graph *to) { ir_type *from_frame = get_irg_frame_type(from); ir_type *to_frame = get_irg_frame_type(to); - int n_members = get_class_n_members(from_frame); - int i; + size_t n_members = get_class_n_members(from_frame); + size_t i; assert(from_frame != to_frame); for (i = 0; i < n_members; ++i) { @@ -363,7 +362,8 @@ int inline_method(ir_node *call, ir_graph *called_graph) { ir_node *Xproj = NULL; ir_node *proj; - for (proj = get_irn_link(call); proj; proj = get_irn_link(proj)) { + for (proj = (ir_node*)get_irn_link(call); proj != NULL; + proj = (ir_node*)get_irn_link(proj)) { long proj_nr = get_Proj_proj(proj); if (proj_nr == pn_Call_X_except) Xproj = proj; } @@ -393,7 +393,6 @@ int inline_method(ir_node *call, ir_graph *called_graph) in[pn_Start_M] = get_Call_mem(call); in[pn_Start_X_initial_exec] = new_r_Jmp(post_bl); in[pn_Start_P_frame_base] = get_irg_frame(irg); - in[pn_Start_P_tls] = get_irg_tls(irg); in[pn_Start_T_args] = new_r_Tuple(post_bl, n_params, args_in); pre_call = new_r_Tuple(post_bl, pn_Start_max, in); post_call = call; @@ -558,9 +557,6 @@ int inline_method(ir_node *call, ir_graph *called_graph) /* handle the regular call */ set_Tuple_pred(call, pn_Call_X_regular, new_r_Jmp(post_bl)); - /* For now, we cannot inline calls with value_base */ - set_Tuple_pred(call, pn_Call_P_value_res_base, new_r_Bad(irg)); - /* Finally the exception control flow. We have two possible situations: First if the Call branches to an exception handler: @@ -691,7 +687,7 @@ static void collect_calls(ir_node *call, void *env) if (called_irg != NULL) { /* The Call node calls a locally defined method. Remember to inline. */ - inline_env_t *ienv = env; + inline_env_t *ienv = (inline_env_t*)env; call_entry *entry = OALLOC(&ienv->obst, call_entry); entry->call = call; entry->callee = called_irg; @@ -757,17 +753,17 @@ void inline_small_irgs(ir_graph *irg, int size) current_ir_graph = rem; } -struct inline_small_irgs_pass_t { +typedef struct inline_small_irgs_pass_t { ir_graph_pass_t pass; int size; -}; +} inline_small_irgs_pass_t; /** * Wrapper to run inline_small_irgs() as a pass. */ static int inline_small_irgs_wrapper(ir_graph *irg, void *context) { - struct inline_small_irgs_pass_t *pass = context; + inline_small_irgs_pass_t *pass = (inline_small_irgs_pass_t*)context; inline_small_irgs(irg, pass->size); return 0; @@ -776,8 +772,7 @@ static int inline_small_irgs_wrapper(ir_graph *irg, void *context) /* create a pass for inline_small_irgs() */ ir_graph_pass_t *inline_small_irgs_pass(const char *name, int size) { - struct inline_small_irgs_pass_t *pass = - XMALLOCZ(struct inline_small_irgs_pass_t); + inline_small_irgs_pass_t *pass = XMALLOCZ(inline_small_irgs_pass_t); pass->size = size; return def_graph_pass_constructor( @@ -833,9 +828,9 @@ typedef struct walker_env { */ static void collect_calls2(ir_node *call, void *ctx) { - wenv_t *env = ctx; + wenv_t *env = (wenv_t*)ctx; inline_irg_env *x = env->x; - ir_opcode code = get_irn_opcode(call); + unsigned code = get_irn_opcode(call); ir_graph *callee; call_entry *entry; @@ -870,7 +865,7 @@ static void collect_calls2(ir_node *call, void *ctx) callee = get_call_called_irg(call); if (callee != NULL) { if (! env->ignore_callers) { - inline_irg_env *callee_env = get_irg_link(callee); + inline_irg_env *callee_env = (inline_irg_env*)get_irg_link(callee); /* count all static callers */ ++callee_env->n_callers; ++callee_env->n_callers_orig; @@ -897,7 +892,7 @@ static void collect_calls2(ir_node *call, void *ctx) */ inline static int is_leave(ir_graph *irg) { - inline_irg_env *env = get_irg_link(irg); + inline_irg_env *env = (inline_irg_env*)get_irg_link(irg); return env->n_call_nodes == 0; } @@ -907,7 +902,7 @@ inline static int is_leave(ir_graph *irg) */ inline static int is_smaller(ir_graph *callee, unsigned size) { - inline_irg_env *env = get_irg_link(callee); + inline_irg_env *env = (inline_irg_env*)get_irg_link(callee); return env->n_nodes < size; } @@ -949,7 +944,7 @@ static void append_call_list(inline_irg_env *dst, inline_irg_env *src, int loop_ we need Call nodes in our graph. Luckily the inliner leaves this information in the link field. */ list_for_each_entry(call_entry, entry, &src->calls, list) { - nentry = duplicate_call_entry(entry, get_irn_link(entry->call), loop_depth); + nentry = duplicate_call_entry(entry, (ir_node*)get_irn_link(entry->call), loop_depth); list_add_tail(&nentry->list, &dst->calls); } dst->n_call_nodes += src->n_call_nodes; @@ -969,7 +964,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, { inline_irg_env *env; ir_graph *irg; - int i, n_irgs; + size_t i, n_irgs; ir_graph *rem; int did_inline; wenv_t wenv; @@ -999,7 +994,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, free_callee_info(irg); assure_cf_loop(irg); - wenv.x = get_irg_link(irg); + wenv.x = (inline_irg_env*)get_irg_link(irg); irg_walk_graph(irg, NULL, collect_calls2, &wenv); } @@ -1014,7 +1009,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, int phiproj_computed = 0; current_ir_graph = get_irp_irg(i); - env = get_irg_link(current_ir_graph); + env = (inline_irg_env*)get_irg_link(current_ir_graph); ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_LINK|IR_RESOURCE_PHI_LIST); list_for_each_entry_safe(call_entry, entry, next, &env->calls, list) { @@ -1041,7 +1036,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, did_inline = inline_method(call, callee); if (did_inline) { - inline_irg_env *callee_env = get_irg_link(callee); + inline_irg_env *callee_env = (inline_irg_env*)get_irg_link(callee); /* call was inlined, Phi/Projs for current graph must be recomputed */ phiproj_computed = 0; @@ -1068,7 +1063,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, int phiproj_computed = 0; current_ir_graph = get_irp_irg(i); - env = get_irg_link(current_ir_graph); + env = (inline_irg_env*)get_irg_link(current_ir_graph); ir_reserve_resources(current_ir_graph, IR_RESOURCE_IRN_LINK|IR_RESOURCE_PHI_LIST); @@ -1092,7 +1087,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, * Remap callee if we have a copy. * FIXME: Should we do this only for recursive Calls ? */ - callee = e->value; + callee = (ir_graph*)e->value; } if (prop >= irg_inline_forced || @@ -1155,7 +1150,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, /* call was inlined, Phi/Projs for current graph must be recomputed */ phiproj_computed = 0; - /* callee was inline. Append it's call list. */ + /* callee was inline. Append its call list. */ env->got_inline = 1; --env->n_call_nodes; append_call_list(env, callee_env, entry->loop_depth); @@ -1164,7 +1159,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, /* after we have inlined callee, all called methods inside callee are now called once more */ list_for_each_entry(call_entry, centry, &callee_env->calls, list) { - inline_irg_env *penv = get_irg_link(centry->callee); + inline_irg_env *penv = (inline_irg_env*)get_irg_link(centry->callee); ++penv->n_callers; } @@ -1179,7 +1174,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, for (i = 0; i < n_irgs; ++i) { irg = get_irp_irg(i); - env = get_irg_link(irg); + env = (inline_irg_env*)get_irg_link(irg); if (env->got_inline) { optimize_graph_df(irg); @@ -1195,7 +1190,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, /* kill the copied graphs: we don't need them anymore */ foreach_pmap(copied_graphs, pm_entry) { - ir_graph *copy = pm_entry->value; + ir_graph *copy = (ir_graph*)pm_entry->value; /* reset the entity, otherwise it will be deleted in the next step ... */ set_irg_entity(copy, NULL); @@ -1207,20 +1202,20 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize, current_ir_graph = rem; } -struct inline_leave_functions_pass_t { +typedef struct inline_leave_functions_pass_t { ir_prog_pass_t pass; unsigned maxsize; unsigned leavesize; unsigned size; int ignore_runtime; -}; +} inline_leave_functions_pass_t; /** * Wrapper to run inline_leave_functions() as a ir_prog pass. */ static int inline_leave_functions_wrapper(ir_prog *irp, void *context) { - struct inline_leave_functions_pass_t *pass = context; + inline_leave_functions_pass_t *pass = (inline_leave_functions_pass_t*)context; (void)irp; inline_leave_functions( @@ -1234,8 +1229,7 @@ ir_prog_pass_t *inline_leave_functions_pass( const char *name, unsigned maxsize, unsigned leavesize, unsigned size, int ignore_runtime) { - struct inline_leave_functions_pass_t *pass = - XMALLOCZ(struct inline_leave_functions_pass_t); + inline_leave_functions_pass_t *pass = XMALLOCZ(inline_leave_functions_pass_t); pass->maxsize = maxsize; pass->leavesize = leavesize; @@ -1320,7 +1314,9 @@ static void analyze_irg_local_weights(inline_irg_env *env, ir_graph *irg) { ir_entity *ent = get_irg_entity(irg); ir_type *mtp; - int nparams, i, proj_nr; + size_t nparams; + int i; + long proj_nr; ir_node *irg_args, *arg; mtp = get_entity_type(ent); @@ -1347,17 +1343,12 @@ static void analyze_irg_local_weights(inline_irg_env *env, ir_graph *irg) * After inlining, the local variable might be transformed into a * SSA variable by scalar_replacement(). */ -static unsigned get_method_local_adress_weight(ir_graph *callee, int pos) +static unsigned get_method_local_adress_weight(ir_graph *callee, size_t pos) { - inline_irg_env *env = get_irg_link(callee); - - if (env->local_weights != NULL) { - if (pos < ARR_LEN(env->local_weights)) - return env->local_weights[pos]; - return 0; - } + inline_irg_env *env = (inline_irg_env*)get_irg_link(callee); - analyze_irg_local_weights(env, callee); + if (env->local_weights == NULL) + analyze_irg_local_weights(env, callee); if (pos < ARR_LEN(env->local_weights)) return env->local_weights[pos]; @@ -1440,7 +1431,7 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee) } entry->all_const = all_const; - callee_env = get_irg_link(callee); + callee_env = (inline_irg_env*)get_irg_link(callee); if (callee_env->n_callers == 1 && callee != current_ir_graph && !entity_is_externally_visible(ent)) { @@ -1475,16 +1466,18 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee) return entry->benefice = weight; } -static ir_graph **irgs; -static int last_irg; +typedef struct walk_env_t { + ir_graph **irgs; + size_t last_irg; +} walk_env_t; /** * Callgraph walker, collect all visited graphs. */ static void callgraph_walker(ir_graph *irg, void *data) { - (void) data; - irgs[last_irg++] = irg; + walk_env_t *env = (walk_env_t *)data; + env->irgs[env->last_irg++] = irg; } /** @@ -1494,22 +1487,22 @@ static void callgraph_walker(ir_graph *irg, void *data) */ static ir_graph **create_irg_list(void) { - ir_entity **free_methods; - int arr_len; - int n_irgs = get_irp_n_irgs(); + ir_entity **free_methods; + size_t n_irgs = get_irp_n_irgs(); + walk_env_t env; - cgana(&arr_len, &free_methods); + cgana(&free_methods); xfree(free_methods); compute_callgraph(); - last_irg = 0; - irgs = XMALLOCNZ(ir_graph*, n_irgs); + env.irgs = XMALLOCNZ(ir_graph*, n_irgs); + env.last_irg = 0; - callgraph_walk(NULL, callgraph_walker, NULL); - assert(n_irgs == last_irg); + callgraph_walk(NULL, callgraph_walker, &env); + assert(n_irgs == env.last_irg); - return irgs; + return env.irgs; } /** @@ -1552,7 +1545,7 @@ static void inline_into(ir_graph *irg, unsigned maxsize, int inline_threshold, pmap *copied_graphs) { int phiproj_computed = 0; - inline_irg_env *env = get_irg_link(irg); + inline_irg_env *env = (inline_irg_env*)get_irg_link(irg); call_entry *curr_call; wenv_t wenv; pqueue_t *pqueue; @@ -1579,10 +1572,10 @@ static void inline_into(ir_graph *irg, unsigned maxsize, /* note that the list of possible calls is updated during the process */ while (!pqueue_empty(pqueue)) { int did_inline; - call_entry *curr_call = pqueue_pop_front(pqueue); + call_entry *curr_call = (call_entry*)pqueue_pop_front(pqueue); ir_graph *callee = curr_call->callee; ir_node *call_node = curr_call->call; - inline_irg_env *callee_env = get_irg_link(callee); + inline_irg_env *callee_env = (inline_irg_env*)get_irg_link(callee); irg_inline_property prop = get_irg_inline_property(callee); int loop_depth; const call_entry *centry; @@ -1609,8 +1602,8 @@ static void inline_into(ir_graph *irg, unsigned maxsize, /* * Remap callee if we have a copy. */ - callee = e->value; - callee_env = get_irg_link(callee); + callee = (ir_graph*)e->value; + callee_env = (inline_irg_env*)get_irg_link(callee); } if (current_ir_graph == callee) { @@ -1682,14 +1675,14 @@ static void inline_into(ir_graph *irg, unsigned maxsize, /* remove it from the caller list */ list_del(&curr_call->list); - /* callee was inline. Append it's call list. */ + /* callee was inline. Append its call list. */ env->got_inline = 1; --env->n_call_nodes; /* we just generate a bunch of new calls */ loop_depth = curr_call->loop_depth; list_for_each_entry(call_entry, centry, &callee_env->calls, list) { - inline_irg_env *penv = get_irg_link(centry->callee); + inline_irg_env *penv = (inline_irg_env*)get_irg_link(centry->callee); ir_node *new_call; call_entry *new_entry; @@ -1700,7 +1693,7 @@ static void inline_into(ir_graph *irg, unsigned maxsize, /* Note that the src list points to Call nodes in the inlined graph, * but we need Call nodes in our graph. Luckily the inliner leaves * this information in the link field. */ - new_call = get_irn_link(centry->call); + new_call = (ir_node*)get_irn_link(centry->call); assert(is_Call(new_call)); new_entry = duplicate_call_entry(centry, new_call, loop_depth); @@ -1724,7 +1717,7 @@ void inline_functions(unsigned maxsize, int inline_threshold, opt_ptr after_inline_opt) { inline_irg_env *env; - int i, n_irgs; + size_t i, n_irgs; ir_graph *rem; wenv_t wenv; pmap *copied_graphs; @@ -1752,7 +1745,7 @@ void inline_functions(unsigned maxsize, int inline_threshold, free_callee_info(irg); - wenv.x = get_irg_link(irg); + wenv.x = (inline_irg_env*)get_irg_link(irg); assure_cf_loop(irg); irg_walk_graph(irg, NULL, collect_calls2, &wenv); } @@ -1767,7 +1760,7 @@ void inline_functions(unsigned maxsize, int inline_threshold, for (i = 0; i < n_irgs; ++i) { ir_graph *irg = irgs[i]; - env = get_irg_link(irg); + env = (inline_irg_env*)get_irg_link(irg); if (env->got_inline && after_inline_opt != NULL) { /* this irg got calls inlined: optimize it */ after_inline_opt(irg); @@ -1782,7 +1775,7 @@ void inline_functions(unsigned maxsize, int inline_threshold, /* kill the copied graphs: we don't need them anymore */ foreach_pmap(copied_graphs, pm_entry) { - ir_graph *copy = pm_entry->value; + ir_graph *copy = (ir_graph*)pm_entry->value; /* reset the entity, otherwise it will be deleted in the next step ... */ set_irg_entity(copy, NULL); @@ -1796,19 +1789,19 @@ void inline_functions(unsigned maxsize, int inline_threshold, current_ir_graph = rem; } -struct inline_functions_pass_t { +typedef struct inline_functions_pass_t { ir_prog_pass_t pass; unsigned maxsize; int inline_threshold; opt_ptr after_inline_opt; -}; +} inline_functions_pass_t; /** * Wrapper to run inline_functions() as a ir_prog pass. */ static int inline_functions_wrapper(ir_prog *irp, void *context) { - struct inline_functions_pass_t *pass = context; + inline_functions_pass_t *pass = (inline_functions_pass_t*)context; (void)irp; inline_functions(pass->maxsize, pass->inline_threshold, @@ -1821,8 +1814,7 @@ ir_prog_pass_t *inline_functions_pass( const char *name, unsigned maxsize, int inline_threshold, opt_ptr after_inline_opt) { - struct inline_functions_pass_t *pass = - XMALLOCZ(struct inline_functions_pass_t); + inline_functions_pass_t *pass = XMALLOCZ(inline_functions_pass_t); pass->maxsize = maxsize; pass->inline_threshold = inline_threshold;