X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fana%2Fanalyze_irg_args.c;h=bfed9def0b4975f0835f1d1d64300a77a70ff974;hb=d0d85962ef52c14950db90e5981a7bea36023ab3;hp=dbe28c155d74e7c9b6a93b79d431016cd227428d;hpb=06bfa9ab2557aaa9e2c1da9d25418781dce701d4;p=libfirm diff --git a/ir/ana/analyze_irg_args.c b/ir/ana/analyze_irg_args.c index dbe28c155..bfed9def0 100644 --- a/ir/ana/analyze_irg_args.c +++ b/ir/ana/analyze_irg_args.c @@ -72,30 +72,59 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) "Call" isn't computed else we analyze that graph. If our reference is the address of this Call node that mean the reference will be read.*/ - if (get_irn_op(succ) == op_Call) { - ir_node *Call_ptr = get_Call_ptr(succ); + switch (get_irn_opcode(succ)) { - if (Call_ptr == arg) { + case iro_Call: { + ir_node *ptr = get_Call_ptr(succ); + + if (ptr == arg) { /* Hmm: not sure what this is, most likely a read */ bits |= ptr_access_read; } - else if (op_SymConst == get_irn_op(Call_ptr) && - get_SymConst_kind(Call_ptr) == symconst_addr_ent) { - entity *meth_ent = get_SymConst_entity(Call_ptr); - - for (p = get_Call_n_params(succ) - 1; p >= 0; --p){ - if (get_Call_param(succ, p) == arg) { - /* an arg can be used more than once ! */ - bits |= get_method_param_access(meth_ent, p); - } - } - } else /* can do anything */ - bits |= ptr_access_all; + else { + ir_op *op = get_irn_op(ptr); + ir_entity *meth_ent; + + if (op == op_SymConst && get_SymConst_kind(ptr) == symconst_addr_ent) { + meth_ent = get_SymConst_entity(ptr); + + for (p = get_Call_n_params(succ) - 1; p >= 0; --p) { + if (get_Call_param(succ, p) == arg) { + /* an arg can be used more than once ! */ + bits |= get_method_param_access(meth_ent, p); + } + } + } + else if (op == op_Sel && 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); + + /* simply look into ALL possible callees */ + for (i = get_Call_n_callees(succ) - 1; i >= 0; --i) { + meth_ent = get_Call_callee(succ, i); + + /* unknown_entity is used to signal that we don't know what is called */ + if (meth_ent == unknown_entity) { + bits |= ptr_access_all; + break; + } + + for (p = n_params - 1; p >= 0; --p) { + if (get_Call_param(succ, p) == arg) { + /* an arg can be used more than once ! */ + bits |= get_method_param_access(meth_ent, p); + } + } + } + } + else /* can do anything */ + bits |= ptr_access_all; + } /* search stops here anyway */ continue; } - else if (get_irn_op(succ) == op_Store) { + case iro_Store: /* We have reached a Store node => the reference is written or stored. */ if (get_Store_ptr(succ) == arg) { /* written to */ @@ -108,18 +137,21 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) /* search stops here anyway */ continue; - } - else if (get_irn_op(succ) == op_Load) { + + case iro_Load: /* We have reached a Load node => the reference is read. */ bits |= ptr_access_read; /* search stops here anyway */ continue; - } - else if (get_irn_op(succ) == op_Conv) { + + case iro_Conv: /* our address is casted into something unknown. Break our search. */ bits = ptr_access_all; break; + + default: + break; } /* If we know that, the argument will be read, write and stored, we @@ -150,20 +182,20 @@ static unsigned analyze_arg(ir_node *arg, unsigned bits) * * @param irg The ir graph to analyze. */ -static void analyze_ent_args(entity *ent) +static void analyze_ent_args(ir_entity *ent) { ir_graph *irg; ir_node *irg_args, *arg; ir_mode *arg_mode; int nparams, i; long proj_nr; - type *mtp; + ir_type *mtp; ptr_access_kind *rw_info; mtp = get_entity_type(ent); nparams = get_method_n_params(mtp); - ent->param_access = NEW_ARR_F(ptr_access_kind, nparams); + ent->attr.mtd_attr.param_access = NEW_ARR_F(ptr_access_kind, nparams); /* If the method haven't parameters we have * nothing to do. @@ -175,7 +207,7 @@ static void analyze_ent_args(entity *ent) /* we have not yet analyzed the graph, set ALL access for pointer args */ for (i = nparams - 1; i >= 0; --i) - ent->param_access[i] = + ent->attr.mtd_attr.param_access[i] = is_Pointer_type(get_method_param_type(mtp, i)) ? ptr_access_all : ptr_access_none; if (! irg) { @@ -183,9 +215,7 @@ static void analyze_ent_args(entity *ent) return; } - /* Call algorithm that computes the out edges */ - if (get_irg_outs_state(irg) != outs_consistent) - compute_outs(irg); + assure_irg_outs(irg); irg_args = get_irg_args(irg); @@ -209,22 +239,25 @@ static void analyze_ent_args(entity *ent) } /* copy the temporary info */ - memcpy(ent->param_access, rw_info, nparams * sizeof(ent->param_access[0])); + memcpy(ent->attr.mtd_attr.param_access, rw_info, + nparams * sizeof(ent->attr.mtd_attr.param_access[0])); +#if 0 printf("\n%s:\n", get_entity_name(ent)); for (i = 0; i < nparams; ++i) { if (is_Pointer_type(get_method_param_type(mtp, i))) - if (ent->param_access[i] != ptr_access_none) { + if (ent->attr.mtd_attr.param_access[i] != ptr_access_none) { printf(" Pointer Arg %d access: ", i); - if (ent->param_access[i] & ptr_access_read) + if (ent->attr.mtd_attr.param_access[i] & ptr_access_read) printf("READ "); - if (ent->param_access[i] & ptr_access_write) + if (ent->attr.mtd_attr.param_access[i] & ptr_access_write) printf("WRITE "); - if (ent->param_access[i] & ptr_access_store) + if (ent->attr.mtd_attr.param_access[i] & ptr_access_store) printf("STORE "); printf("\n"); } } +#endif } /** @@ -235,7 +268,7 @@ static void analyze_ent_args(entity *ent) */ void analyze_irg_args(ir_graph *irg) { - entity *ent; + ir_entity *ent; if (irg == get_const_code_irg()) return; @@ -244,7 +277,7 @@ void analyze_irg_args(ir_graph *irg) if (! ent) return; - if (! ent->param_access) + if (! ent->attr.mtd_attr.param_access) analyze_ent_args(ent); } @@ -252,34 +285,34 @@ 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(entity *ent, int pos) +ptr_access_kind get_method_param_access(ir_entity *ent, int pos) { - type *mtp = get_entity_type(ent); - int is_variadic = get_method_variadicity(mtp) == variadicity_variadic; + 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))); - if (ent->param_access) { - if (pos < ARR_LEN(ent->param_access)) - return ent->param_access[pos]; + if (ent->attr.mtd_attr.param_access) { + if (pos < ARR_LEN(ent->attr.mtd_attr.param_access)) + return ent->attr.mtd_attr.param_access[pos]; else return ptr_access_all; } analyze_ent_args(ent); - if (pos < ARR_LEN(ent->param_access)) - return ent->param_access[pos]; + if (pos < ARR_LEN(ent->attr.mtd_attr.param_access)) + return ent->attr.mtd_attr.param_access[pos]; else return ptr_access_all; } enum args_weight { - null_weight = 0, /* If can't be anything optimized. */ - binop_weight = 1, /* If the argument have mode_weight and take part in binop. */ - const_binop_weight = 1, /* If the argument have mode_weight and take part in binop with a constant.*/ - cmp_weight = 4, /* If the argument take part in cmp. */ - const_cmp_weight = 10 /* If the argument take part in cmp with a constant. */ + null_weight = 0, /**< If can't be anything optimized. */ + binop_weight = 1, /**< If the argument have mode_weight and take part in binop. */ + const_binop_weight = 1, /**< If the argument have mode_weight and take part in binop with a constant.*/ + cmp_weight = 4, /**< If the argument take part in cmp. */ + const_cmp_weight = 10 /**< If the argument take part in cmp with a constant. */ }; /** @@ -356,9 +389,9 @@ static float calc_method_param_weight(ir_node *arg) * * @param ent The entity of the ir_graph. */ -static void analyze_method_params_weight(entity *ent) +static void analyze_method_params_weight(ir_entity *ent) { - type *mtp; + ir_type *mtp; ir_graph *irg; int nparams, i, proj_nr; ir_node *irg_args, *arg; @@ -366,18 +399,20 @@ static void analyze_method_params_weight(entity *ent) mtp = get_entity_type(ent); nparams = get_method_n_params(mtp); + /* allocate a new array. currently used as 'analysed' flag */ + ent->attr.mtd_attr.param_weight = NEW_ARR_F(float, nparams); + /* If the method haven't parameters we have * nothing to do. */ if (nparams <= 0) return; - ent->param_weight = NEW_ARR_F(float, nparams); - irg = get_entity_irg(ent); + irg = get_entity_irg(ent); /* First we initialize the parameter weight with 0. */ for (i = nparams - 1; i >= 0; i--) - ent->param_weight[i] = null_weight; + ent->attr.mtd_attr.param_weight[i] = null_weight; if (! irg) { /* no graph, no better info */ @@ -385,15 +420,14 @@ static void analyze_method_params_weight(entity *ent) } /* Call algorithm that computes the out edges */ - if (get_irg_outs_state(irg) != outs_consistent) - compute_outs(irg); + 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->param_weight[proj_nr] += calc_method_param_weight(arg); + 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); } #if 0 @@ -407,24 +441,24 @@ static void analyze_method_params_weight(entity *ent) * Compute for a method with pointer parameter(s) * if they will be read or written. */ -float get_method_param_weight(entity *ent, int pos) +float get_method_param_weight(ir_entity *ent, int pos) { - type *mtp = get_entity_type(ent); - int is_variadic = get_method_variadicity(mtp) == variadicity_variadic; + 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))); - if (ent->param_weight) { - if (pos < ARR_LEN(ent->param_weight)) - return ent->param_weight[pos]; + 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]; else return 0.0f; } analyze_method_params_weight(ent); - if (pos < ARR_LEN(ent->param_weight)) - return ent->param_weight[pos]; + if (pos < ARR_LEN(ent->attr.mtd_attr.param_weight)) + return ent->attr.mtd_attr.param_weight[pos]; else return 0.0f; } @@ -438,12 +472,12 @@ float get_method_param_weight(entity *ent, int pos) */ void analyze_irg_args_weight(ir_graph *irg) { - entity *ent; + ir_entity *ent; ent = get_irg_entity(irg); - if(! ent) + if (! ent) return; - if(! ent->param_weight) + if (! ent->attr.mtd_attr.param_weight) analyze_method_params_weight(ent); }