*/
static ir_type *create_modified_mtd_type(const lower_params_t *lp, ir_type *mtp)
{
- ir_type *lowered, *ptr_tp, *value_type;
+ ir_type *lowered, *ptr_tp;
ir_type **params, **results, *res_tp;
size_t *param_map;
ir_mode *modes[MAX_REGISTER_RET_VAL];
int changed = 0;
ir_variadicity var;
- if (is_lowered_type(mtp)) {
- /* the type is already lowered. Not handled yet. */
- assert(0 && "lowered types NYI");
- }
-
lowered = get_associated_type(mtp);
if (lowered != NULL)
return lowered;
set_lowered_type(mtp, lowered);
- value_type = get_method_value_param_type(mtp);
- if (value_type != NULL) {
- /* set new param positions */
- for (i = 0; i < nn_params; ++i) {
- ir_entity *ent = get_method_value_param_ent(lowered, i);
- size_t pos = param_map[i];
- ident *id;
-
- set_entity_link(ent, INT_TO_PTR(pos));
- if (pos >= n_params) {
- /* formally return value, ignore for now */
- continue;
- }
-
- id = get_method_param_ident(mtp, pos);
- if (id != NULL) {
- set_method_param_ident(lowered, i, id);
- set_entity_ident(ent, id);
- }
- }
-
- set_lowered_type(value_type, get_method_value_param_type(lowered));
- }
-
return lowered;
}
if (env->params->flags & LF_COMPOUND_RETURN) {
/* check for compound returns */
ir_node *src = get_CopyB_src(n);
- /* older scheme using value_res_ent */
- if (is_Sel(src)) {
- ir_node *proj = get_Sel_ptr(src);
- if (is_Proj(proj) && get_Proj_proj(proj) == pn_Call_P_value_res_base) {
+ if (is_Proj(src)) {
+ ir_node *proj = get_Proj_pred(src);
+ if (is_Proj(proj) && get_Proj_proj(proj) == pn_Call_T_result) {
ir_node *call = get_Proj_pred(proj);
if (is_Call(call)) {
- /* found a CopyB from compound Call result */
- cl_entry *e = get_Call_entry(call, env);
- set_irn_link(n, e->copyb);
- e->copyb = n;
- }
- }
- } else {
- /* new scheme: compound results are determined by the call type only */
- if (is_Proj(src)) {
- ir_node *proj = get_Proj_pred(src);
- if (is_Proj(proj) && get_Proj_proj(proj) == pn_Call_T_result) {
- ir_node *call = get_Proj_pred(proj);
- if (is_Call(call)) {
- ctp = get_Call_type(call);
- if (is_compound_type(get_method_res_type(ctp, get_Proj_proj(src)))) {
- /* found a CopyB from compound Call result */
- cl_entry *e = get_Call_entry(call, env);
- set_irn_link(n, e->copyb);
- e->copyb = n;
- }
+ ctp = get_Call_type(call);
+ if (is_compound_type(get_method_res_type(ctp, get_Proj_proj(src)))) {
+ /* found a CopyB from compound Call result */
+ cl_entry *e = get_Call_entry(call, env);
+ set_irn_link(n, e->copyb);
+ e->copyb = n;
}
}
}
*/
static void add_hidden_param(ir_graph *irg, size_t n_com, ir_node **ins, cl_entry *entry, wlk_env *env)
{
- ir_node *p, *n, *src, *mem, *blk;
- ir_entity *ent;
- ir_type *owner;
+ ir_node *p, *n, *mem, *blk;
size_t n_args;
n_args = 0;
for (p = entry->copyb; p; p = n) {
- size_t idx;
- n = (ir_node*)get_irn_link(p);
- src = get_CopyB_src(p);
-
- /* old scheme using value_res_ent */
- if (is_Sel(src)) {
- ent = get_Sel_entity(src);
- owner = get_entity_owner(ent);
-
- /* find the hidden parameter index */
- for (idx = 0; idx < get_struct_n_members(owner); ++idx)
- if (get_struct_member(owner, idx) == ent)
- break;
- assert(idx < get_struct_n_members(owner));
- } else {
- /* new scheme: compound returns are determined by the call type and are Proj's */
- idx = get_Proj_proj(src);
- }
+ ir_node *src = get_CopyB_src(p);
+ size_t idx = get_Proj_proj(src);
+ n = (ir_node*)get_irn_link(p);
ins[idx] = get_CopyB_dst(p);
mem = get_CopyB_mem(p);
if (n_ret_com) {
int idx;
- /*
- * Now fix the Return node of the current graph.
- */
- env.changed = 1;
-
/* STEP 1: find the return. This is simple, we have normalized the graph. */
endbl = get_irg_end_block(irg);
ret = NULL;
break;
}
}
- /* there should always be a return */
- assert(ret);
-
- /*
- * STEP 2: fix it. For all compound return values add a CopyB,
- * all others are copied.
- */
- NEW_ARR_A(ir_node *, new_in, n_ress + 1);
-
- bl = get_nodes_block(ret);
- mem = get_Return_mem(ret);
-
- ft = get_irg_frame_type(irg);
- NEW_ARR_A(cr_pair, cr_opt, n_ret_com);
- n_cr_opt = 0;
- for (j = 1, i = k = 0; i < n_ress; ++i) {
- ir_node *pred = get_Return_res(ret, i);
- tp = get_method_res_type(mtp, i);
- if (is_compound_type(tp)) {
- ir_node *arg = get_irg_args(irg);
- arg = new_r_Proj(arg, mode_P_data, env.first_hidden + k);
- ++k;
-
- if (is_Unknown(pred)) {
- /* The Return(Unknown) is the Firm construct for a missing return.
- Do nothing. */
- } else {
- /**
- * Sorrily detecting that copy-return is possible isn't that simple.
- * We must check, that the hidden address is alias free during the whole
- * function.
- * A simple heuristic: all Loads/Stores inside
- * the function access only local frame.
- */
- if (env.only_local_mem && is_compound_address(ft, pred)) {
- /* we can do the copy-return optimization here */
- cr_opt[n_cr_opt].ent = get_Sel_entity(pred);
- cr_opt[n_cr_opt].arg = arg;
- ++n_cr_opt;
- } else { /* copy-return optimization is impossible, do the copy. */
- copy = new_r_CopyB(
- bl,
- mem,
- arg,
- pred,
- tp
- );
- mem = new_r_Proj(copy, mode_M, pn_CopyB_M);
+ /* in case of infinite loops, there might be no return */
+ if (ret != NULL) {
+ /*
+ * Now fix the Return node of the current graph.
+ */
+ env.changed = 1;
+
+ /*
+ * STEP 2: fix it. For all compound return values add a CopyB,
+ * all others are copied.
+ */
+ NEW_ARR_A(ir_node *, new_in, n_ress + 1);
+
+ bl = get_nodes_block(ret);
+ mem = get_Return_mem(ret);
+
+ ft = get_irg_frame_type(irg);
+ NEW_ARR_A(cr_pair, cr_opt, n_ret_com);
+ n_cr_opt = 0;
+ for (j = 1, i = k = 0; i < n_ress; ++i) {
+ ir_node *pred = get_Return_res(ret, i);
+ tp = get_method_res_type(mtp, i);
+
+ if (is_compound_type(tp)) {
+ ir_node *arg = get_irg_args(irg);
+ arg = new_r_Proj(arg, mode_P_data, env.first_hidden + k);
+ ++k;
+
+ if (is_Unknown(pred)) {
+ /* The Return(Unknown) is the Firm construct for a missing return.
+ Do nothing. */
+ } else {
+ /**
+ * Sorrily detecting that copy-return is possible isn't that simple.
+ * We must check, that the hidden address is alias free during the whole
+ * function.
+ * A simple heuristic: all Loads/Stores inside
+ * the function access only local frame.
+ */
+ if (env.only_local_mem && is_compound_address(ft, pred)) {
+ /* we can do the copy-return optimization here */
+ cr_opt[n_cr_opt].ent = get_Sel_entity(pred);
+ cr_opt[n_cr_opt].arg = arg;
+ ++n_cr_opt;
+ } else { /* copy-return optimization is impossible, do the copy. */
+ copy = new_r_CopyB(
+ bl,
+ mem,
+ arg,
+ pred,
+ tp
+ );
+ mem = new_r_Proj(copy, mode_M, pn_CopyB_M);
+ }
}
- }
- if (lp->flags & LF_RETURN_HIDDEN) {
- new_in[j] = arg;
+ if (lp->flags & LF_RETURN_HIDDEN) {
+ new_in[j] = arg;
+ ++j;
+ }
+ } else { /* scalar return value */
+ new_in[j] = pred;
++j;
}
- } else { /* scalar return value */
- new_in[j] = pred;
- ++j;
}
- }
- /* replace the in of the Return */
- new_in[0] = mem;
- set_irn_in(ret, j, new_in);
+ /* replace the in of the Return */
+ new_in[0] = mem;
+ set_irn_in(ret, j, new_in);
- if (n_cr_opt > 0) {
- size_t i, n;
+ if (n_cr_opt > 0) {
+ size_t i, n;
- irg_walk_graph(irg, NULL, do_copy_return_opt, cr_opt);
+ irg_walk_graph(irg, NULL, do_copy_return_opt, cr_opt);
- for (i = 0, n = ARR_LEN(cr_opt); i < n; ++i) {
- free_entity(cr_opt[i].ent);
+ for (i = 0, n = ARR_LEN(cr_opt); i < n; ++i) {
+ free_entity(cr_opt[i].ent);
+ }
}
}
} /* if (n_ret_com) */