X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fanalyze_irg_args.c;h=9cf6b2b1c14c398e00a1298b851ddb277758b34f;hb=0bddf6c31e2dc664e50eed6609ac36a1a86e1536;hp=a40cc6ab2c5366c21888adaa3a229c09e04221a8;hpb=ee44e33167b44432066f2ca6c7e413daa1949280;p=libfirm diff --git a/ir/ana/analyze_irg_args.c b/ir/ana/analyze_irg_args.c index a40cc6ab2..9cf6b2b1c 100644 --- a/ir/ana/analyze_irg_args.c +++ b/ir/ana/analyze_irg_args.c @@ -20,27 +20,21 @@ /** * @file * @brief read/write analyze of graph argument, which have mode reference. - * @author Beyhan Veliev, Michael Beck - * @version $Id$ + * @author Beyhan Veliev */ #include "config.h" #include -#include "adt/raw_bitset.h" #include "irouts.h" #include "irnode_t.h" #include "irmode_t.h" #include "array_t.h" #include "irprog.h" #include "entity_t.h" -#include "irgwalk.h" #include "analyze_irg_args.h" -static char v; -static void *VISITED = &v; - /** * Walk recursive the successors of a graph argument * with mode reference and mark if it will be read, @@ -49,18 +43,19 @@ static void *VISITED = &v; * @param arg The graph argument with mode reference, * that must be checked. */ -static unsigned analyze_arg(ir_node *arg, unsigned bits) { +static ptr_access_kind analyze_arg(ir_node *arg, ptr_access_kind bits) +{ int i, p; ir_node *succ; /* We must visit a node once to avoid endless recursion.*/ - set_irn_link(arg, VISITED); + mark_irn_visited(arg); for (i = get_irn_n_outs(arg) - 1; i >= 0; --i) { succ = get_irn_out(arg, i); /* We was here.*/ - if (get_irn_link(succ) == VISITED) + if (irn_visited(succ)) continue; /* We should not walk over the memory edge.*/ @@ -84,8 +79,8 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) { } else { ir_entity *meth_ent; - if (is_Global(ptr)) { - meth_ent = get_Global_entity(ptr); + if (is_SymConst_addr_ent(ptr)) { + meth_ent = get_SymConst_entity(ptr); for (p = get_Call_n_params(succ) - 1; p >= 0; --p) { if (get_Call_param(succ, p) == arg) { @@ -95,14 +90,15 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) { } } else if (is_Sel(ptr) && get_irp_callee_info_state() == irg_callee_info_consistent) { /* is be a polymorphic call but callee information is available */ - int i, n_params = get_Call_n_params(succ); + int n_params = get_Call_n_params(succ); + int c; /* simply look into ALL possible callees */ - for (i = get_Call_n_callees(succ) - 1; i >= 0; --i) { - meth_ent = get_Call_callee(succ, i); + for (c = get_Call_n_callees(succ) - 1; c >= 0; --c) { + meth_ent = get_Call_callee(succ, c); /* unknown_entity is used to signal that we don't know what is called */ - if (meth_ent == unknown_entity) { + if (is_unknown_entity(meth_ent)) { bits |= ptr_access_all; break; } @@ -178,7 +174,8 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) { * * @param irg The ir graph to analyze. */ -static void analyze_ent_args(ir_entity *ent) { +static void analyze_ent_args(ir_entity *ent) +{ ir_graph *irg; ir_node *irg_args, *arg; ir_mode *arg_mode; @@ -256,13 +253,8 @@ static void analyze_ent_args(ir_entity *ent) { #endif } -/** - * Analyze how pointer arguments of a given - * ir graph are accessed. - * - * @param irg The ir graph to analyze. - */ -void analyze_irg_args(ir_graph *irg) { +void analyze_irg_args(ir_graph *irg) +{ ir_entity *ent; if (irg == get_const_code_irg()) @@ -276,17 +268,13 @@ void analyze_irg_args(ir_graph *irg) { analyze_ent_args(ent); } -/* - * Compute for a method with pointer parameter(s) - * if they will be read or written. - */ -ptr_access_kind get_method_param_access(ir_entity *ent, int pos) +ptr_access_kind get_method_param_access(ir_entity *ent, size_t pos) { #ifndef NDEBUG ir_type *mtp = get_entity_type(ent); int is_variadic = get_method_variadicity(mtp) == variadicity_variadic; - assert(0 <= pos && (is_variadic || pos < get_method_n_params(mtp))); + assert(is_variadic || pos < get_method_n_params(mtp)); #endif if (ent->attr.mtd_attr.param_access) { @@ -319,19 +307,20 @@ enum args_weight { * * @param arg The parameter them weight muss be computed. */ -static unsigned calc_method_param_weight(ir_node *arg) { +static unsigned calc_method_param_weight(ir_node *arg) +{ int i, j, k; ir_node *succ, *op; unsigned weight = null_weight; /* We mark the nodes to avoid endless recursion */ - set_irn_link(arg, VISITED); + mark_irn_visited(arg); for (i = get_irn_n_outs(arg) - 1; i >= 0; i--) { succ = get_irn_out(arg, i); /* We was here.*/ - if (get_irn_link(succ) == VISITED) + if (irn_visited(succ)) continue; /* We should not walk over the memory edge.*/ @@ -422,7 +411,8 @@ static unsigned calc_method_param_weight(ir_node *arg) { * * @param ent The entity of the ir_graph. */ -static void analyze_method_params_weight(ir_entity *ent) { +static void analyze_method_params_weight(ir_entity *ent) +{ ir_type *mtp; ir_graph *irg; int nparams, i, proj_nr; @@ -457,28 +447,9 @@ static void analyze_method_params_weight(ir_entity *ent) { proj_nr = get_Proj_proj(arg); ent->attr.mtd_attr.param_weight[proj_nr] += calc_method_param_weight(arg); } - -#if 0 - printf("\n%s:\n", get_entity_name(ent)); - for (i = nparams - 1; i >= 0; --i) - printf("The weight of argument %i is %f \n", i, ent->param_weight[i]); -#endif } -/* - * Returns for a method the 'weight' that every parameter - * has on optimization possibility. Higher values allows - * higher optimization with procedure cloning. - * - * The values are calculation on demand only. - * - * @param ent the entity to analyze - * @param pos the argument number - * - * @return the parameter weight or null_weight if pos is greater - * than the number of arguments. - */ -unsigned get_method_param_weight(ir_entity *ent, int pos) +unsigned get_method_param_weight(ir_entity *ent, size_t pos) { if (ent->attr.mtd_attr.param_weight) { if (pos < ARR_LEN(ent->attr.mtd_attr.param_weight)) @@ -495,123 +466,18 @@ unsigned get_method_param_weight(ir_entity *ent, int pos) return null_weight; } -typedef struct walk_env { - unsigned *marks; /**< raw bitset for nodes that could be analysed */ - unsigned *param_mask; /**< raw bitset of constant parameters */ - unsigned mask_len; /**< length of the parameter bitmask */ - unsigned weight; /**< the accumulated weight */ -} walk_env; - -/** - * Walker, evaluates possible constant folding - */ -static void evaluate_weight(ir_node *irn, void *ctx) { - walk_env *env = ctx; - int i, n; - ir_node *ptr; - - if (is_arg_Proj(irn)) { - unsigned argnum = (unsigned)get_Proj_proj(irn); - - if (argnum < env->mask_len) { - if (rbitset_is_set(env->param_mask, argnum)) { - /* is a constant parameter */ - rbitset_set(env->marks, get_irn_idx(irn)); - } - } - return; - } - if (is_irn_constlike(irn)) { - /* is a constant by itself */ - rbitset_set(env->marks, get_irn_idx(irn)); - return; - } - - if (is_Block(irn)) +void analyze_irg_args_weight(ir_graph *irg) +{ + ir_entity *entity = get_irg_entity(irg); + if (entity == NULL) return; - /* handle some special cases */ - switch (get_irn_opcode(irn)) { - case iro_Div: - case iro_Quot: - case iro_Mod: - case iro_DivMod: - /* skip the memory input of these nodes */ - assert(pn_Generic_M_regular == 0); - n = 1; - break; - case iro_Call: - ptr = get_Call_ptr(irn); - if (! is_SymConst(ptr) && rbitset_is_set(env->marks, get_irn_idx(ptr))) { - /* the arguments is used as an pointer input for a call, - we can probably change an indirect Call into a direct one. */ - env->weight += indirect_call_weight; - } - n = 2; - break; - default: - n = 0; - break; - } - for (i = get_irn_arity(irn) - 1; i >= n; --i) { - ir_node *pred = get_irn_n(irn, i); - - if (! rbitset_is_set(env->marks, get_irn_idx(pred))) { - /* not constant predecessor ... */ - return; - } - } - - /* all predecessors are constant, we probably can fold this node */ - rbitset_set(env->marks, get_irn_idx(irn)); - - if (is_binop(irn)) { - env->weight += const_binop_weight; - } else if (is_unop(irn)) { - env->weight += const_binop_weight; - } else if (is_Proj(irn)) { - ir_node *pred = get_Proj_pred(irn); - if (is_Cmp(pred)) { - env->weight += const_cmp_weight; - } else if (is_Cond(pred)) { - /* the argument is used for a SwitchCond, a big win */ - env->weight += const_cmp_weight; - } - } -} - -/** - * - */ -unsigned analyze_irg_param_weights(ir_graph *irg, unsigned *bitmask, unsigned len) { - unsigned nodes = get_irg_last_idx(irg); - unsigned *marks = rbitset_malloc(nodes); - walk_env env; - - env.marks = marks; - env.param_mask = bitmask; - env.mask_len = len; - env.weight = null_weight; - - irg_walk_graph(irg, NULL, evaluate_weight, &env); - - xfree(marks); - return env.weight; -} - -/** - * Analyze argument's weight of a given - * ir graph. - * - * @param irg The ir graph to analyze. - */ -void analyze_irg_args_weight(ir_graph *irg) { - ir_entity *ent; - - ent = get_irg_entity(irg); - if (ent == NULL) + assert(is_method_entity(entity)); + if (entity->attr.mtd_attr.param_weight != NULL) return; - if (! ent->attr.mtd_attr.param_weight) - analyze_method_params_weight(ent); + ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED); + inc_irg_visited(irg); + analyze_method_params_weight(entity); + ir_free_resources(irg, IR_RESOURCE_IRN_VISITED); }