X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fanalyze_irg_args.c;h=7b6a98907a3a8cd94f5aa977c7c773c6208c3b5d;hb=6ccff2965d94c272f71df2a1655336af47bb7753;hp=bb1c80b80718b21c309ab764f4deb930e4ee9933;hpb=4377f9bab6b511699c50ba4e8eaf1b5abcf30a68;p=libfirm diff --git a/ir/ana/analyze_irg_args.c b/ir/ana/analyze_irg_args.c index bb1c80b80..7b6a98907 100644 --- a/ir/ana/analyze_irg_args.c +++ b/ir/ana/analyze_irg_args.c @@ -21,29 +21,20 @@ * @file * @brief read/write analyze of graph argument, which have mode reference. * @author Beyhan Veliev - * @version $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif -#ifdef HAVE_STDLIB_H -# include -#endif +#include #include "irouts.h" #include "irnode_t.h" #include "irmode_t.h" -#include "array.h" +#include "array_t.h" #include "irprog.h" #include "entity_t.h" -#include "xmalloc.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, @@ -52,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.*/ @@ -87,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) { @@ -98,11 +90,12 @@ 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) { @@ -181,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; @@ -265,7 +259,8 @@ static void analyze_ent_args(ir_entity *ent) { * * @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()) @@ -283,13 +278,13 @@ void analyze_irg_args(ir_graph *irg) { * 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) { @@ -322,30 +317,35 @@ enum args_weight { * * @param arg The parameter them weight muss be computed. */ -static unsigned calc_method_param_weight(ir_node *arg) { - int i; +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.*/ if (get_irn_mode(succ) == mode_M) continue; - if (is_Call(succ) && get_Call_ptr(succ) == arg) { - /* the arguments is used as an pointer input for a call, - we can probably change an indirect Call into a direct one. */ - weight += indirect_call_weight; - } else if (is_Cmp(succ)) { + switch (get_irn_opcode(succ)) { + case iro_Call: + if (get_Call_ptr(succ) == arg) { + /* the arguments is used as an pointer input for a call, + we can probably change an indirect Call into a direct one. */ + weight += indirect_call_weight; + } + break; + case iro_Cmp: /* We have reached a cmp and we must increase the weight with the cmp_weight. */ if (get_Cmp_left(succ) == arg) @@ -357,30 +357,59 @@ static unsigned calc_method_param_weight(ir_node *arg) { weight += const_cmp_weight; } else weight += cmp_weight; - } else if (is_Cond(succ)) { + break; + case iro_Cond: /* the argument is used for a SwitchCond, a big win */ weight += const_cmp_weight * get_irn_n_outs(succ); - } else if (is_binop(succ)) { - /* We have reached a BinOp and we must increase the - weight with the binop_weight. If the other operand of the - BinOp is a constant we increase the weight with const_binop_weight - and call the function recursive. - */ - if (get_binop_left(succ) == arg) - op = get_binop_right(succ); - else - op = get_binop_left(succ); - - if (is_irn_constlike(op)) { + break; + case iro_Id: + /* when looking backward we might find Id nodes */ + weight += calc_method_param_weight(succ); + break; + case iro_Tuple: + /* unoptimized tuple */ + for (j = get_Tuple_n_preds(succ) - 1; j >= 0; --j) { + ir_node *pred = get_Tuple_pred(succ, j); + if (pred == arg) { + /* look for Proj(j) */ + for (k = get_irn_n_outs(succ) - 1; k >= 0; --k) { + ir_node *succ_succ = get_irn_out(succ, k); + if (is_Proj(succ_succ)) { + if (get_Proj_proj(succ_succ) == j) { + /* found */ + weight += calc_method_param_weight(succ_succ); + } + } else { + /* this should NOT happen */ + } + } + } + } + break; + default: + if (is_binop(succ)) { + /* We have reached a BinOp and we must increase the + weight with the binop_weight. If the other operand of the + BinOp is a constant we increase the weight with const_binop_weight + and call the function recursive. + */ + if (get_binop_left(succ) == arg) + op = get_binop_right(succ); + else + op = get_binop_left(succ); + + if (is_irn_constlike(op)) { + weight += const_binop_weight; + weight += calc_method_param_weight(succ); + } else + weight += binop_weight; + } else if (is_unop(succ)) { + /* We have reached a binop and we must increase the + weight with the const_binop_weight and call the function recursive.*/ weight += const_binop_weight; weight += calc_method_param_weight(succ); - } else - weight += binop_weight; - } else if (is_unop(succ)) { - /* We have reached a binop and we must increase the - weight with the const_binop_weight and call the function recursive.*/ - weight += const_binop_weight; - weight += calc_method_param_weight(succ); + } + break; } } set_irn_link(arg, NULL); @@ -392,7 +421,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; @@ -422,18 +452,11 @@ static void analyze_method_params_weight(ir_entity *ent) { assure_irg_outs(irg); irg_args = get_irg_args(irg); - for (i = get_irn_n_outs(irg_args) - 1; i >= 0; --i) { arg = get_irn_out(irg_args, i); proj_nr = get_Proj_proj(arg); - ent->attr.mtd_attr.param_weight[proj_nr] += calc_method_param_weight(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 } /* @@ -442,15 +465,15 @@ static void analyze_method_params_weight(ir_entity *ent) { * 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) { -#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))); -#endif - if (ent->attr.mtd_attr.param_weight) { if (pos < ARR_LEN(ent->attr.mtd_attr.param_weight)) return ent->attr.mtd_attr.param_weight[pos]; @@ -472,13 +495,18 @@ unsigned get_method_param_weight(ir_entity *ent, int pos) * * @param irg The ir graph to analyze. */ -void analyze_irg_args_weight(ir_graph *irg) { - ir_entity *ent; +void analyze_irg_args_weight(ir_graph *irg) +{ + ir_entity *entity = get_irg_entity(irg); + if (entity == NULL) + return; - 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); }