+ * @param arg The parameter them weight muss be computed.
+ */
+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);
+
+ 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)
+ continue;
+
+ /* We should not walk over the memory edge.*/
+ if (get_irn_mode(succ) == mode_M)
+ continue;
+
+ 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)
+ op = get_Cmp_right(succ);
+ else
+ op = get_Cmp_left(succ);
+
+ if (is_irn_constlike(op)) {
+ weight += const_cmp_weight;
+ } else
+ weight += cmp_weight;
+ break;
+ case iro_Cond:
+ /* the argument is used for a SwitchCond, a big win */
+ weight += const_cmp_weight * get_irn_n_outs(succ);
+ 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);
+ }
+ break;
+ }
+ }
+ set_irn_link(arg, NULL);
+ return weight;
+}
+
+/**
+ * Calculate a weight for each argument of an entity.
+ *
+ * @param ent The entity of the ir_graph.
+ */
+static void analyze_method_params_weight(ir_entity *ent) {
+ ir_type *mtp;
+ ir_graph *irg;
+ int nparams, i, proj_nr;
+ ir_node *irg_args, *arg;
+
+ 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(unsigned, nparams);
+
+ /* If the method haven't parameters we have nothing to do. */
+ if (nparams <= 0)
+ return;
+
+ /* First we initialize the parameter weights with 0. */
+ for (i = nparams - 1; i >= 0; i--)
+ ent->attr.mtd_attr.param_weight[i] = null_weight;
+
+ irg = get_entity_irg(ent);
+ if (irg == NULL) {
+ /* no graph, no better info */
+ return;
+ }
+
+ /* Call algorithm that computes the out edges */
+ 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);
+ }
+
+#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.