in array contained Bads. Now it's possible.
We don't call optimize_in_place as it requires
that the fields in ir_graph are set properly. */
- if (!has_Block_label(nn) &&
+ if (!has_Block_entity(nn) &&
get_opt_control_flow_straightening() &&
get_Block_n_cfgpreds(nn) == 1 &&
is_Jmp(get_Block_cfgpred(nn, 0))) {
copy_node(n, NULL);
if (is_Sel(n)) {
- nn = get_new_node (n);
+ nn = get_new_node(n);
assert(is_Sel(nn));
+ /* use copied entities from the new frame */
if (get_entity_owner(get_Sel_entity(n)) == frame_tp) {
set_Sel_entity(nn, get_entity_link(get_Sel_entity(n)));
}
} else if (is_Block(n)) {
- nn = get_new_node (n);
- nn->attr.block.irg = current_ir_graph;
+ nn = get_new_node(n);
+ nn->attr.block.irg.irg = current_ir_graph;
}
}
mtp = get_entity_type(ent);
ctp = get_Call_type(call);
- if (get_method_n_params(mtp) > get_method_n_params(ctp)) {
+ n_params = get_method_n_params(mtp);
+ n_res = get_method_n_ress(mtp);
+ if (n_params > get_method_n_params(ctp)) {
/* this is a bad feature of C: without a prototype, we can
* call a function with less parameters than needed. Currently
* we don't support this, although we could use Unknown than. */
return 0;
}
+ if (n_res != get_method_n_ress(ctp)) {
+ return 0;
+ }
/* Argh, compiling C has some bad consequences:
* It is implementation dependent what happens in that case.
* We support inlining, if the bitsize of the types matches AND
* the same arithmetic is used. */
- n_params = get_method_n_params(mtp);
for (i = n_params - 1; i >= 0; --i) {
ir_type *param_tp = get_method_param_type(mtp, i);
ir_type *arg_tp = get_method_param_type(ctp, i);
/* otherwise we can simply "reinterpret" the bits */
}
}
+ for (i = n_res - 1; i >= 0; --i) {
+ ir_type *decl_res_tp = get_method_res_type(mtp, i);
+ ir_type *used_res_tp = get_method_res_type(ctp, i);
+
+ if (decl_res_tp != used_res_tp) {
+ ir_mode *decl_mode = get_type_mode(decl_res_tp);
+ ir_mode *used_mode = get_type_mode(used_res_tp);
+ if (decl_mode == NULL || used_mode == NULL)
+ return 0;
+ if (get_mode_size_bits(decl_mode) != get_mode_size_bits(used_mode))
+ return 0;
+ if (get_mode_arithmetic(decl_mode) != get_mode_arithmetic(used_mode))
+ return 0;
+ /* otherwise we can "reinterpret" the bits */
+ }
+ }
irg = get_irn_irg(call);
ir_mode *mode = get_type_mode(param_tp);
if (mode != get_irn_mode(arg)) {
- arg = new_r_Conv(irg, block, arg, mode, 0);
+ arg = new_r_Conv(block, arg, mode);
}
args_in[i] = arg;
}
ir_node *ret;
ret = get_Block_cfgpred(end_bl, i);
if (is_Return(ret)) {
- cf_pred[n_ret] = new_r_Jmp(irg, get_nodes_block(ret));
+ cf_pred[n_ret] = new_r_Jmp(get_nodes_block(ret));
n_ret++;
}
}
/* Now the real results */
if (n_res > 0) {
for (j = 0; j < n_res; j++) {
+ ir_type *res_type = get_method_res_type(ctp, j);
+ ir_mode *res_mode = get_type_mode(res_type);
n_ret = 0;
for (i = 0; i < arity; i++) {
ret = get_Block_cfgpred(end_bl, i);
if (is_Return(ret)) {
- cf_pred[n_ret] = get_Return_res(ret, j);
+ ir_node *res = get_Return_res(ret, j);
+ if (get_irn_mode(res) != res_mode) {
+ ir_node *block = get_nodes_block(res);
+ res = new_r_Conv(block, res, res_mode);
+ }
+ cf_pred[n_ret] = res;
n_ret++;
}
}
ir_node *ret;
ret = skip_Proj(get_Block_cfgpred(end_bl, i));
if (is_Call(ret)) {
- cf_pred[n_exc] = new_r_Proj(irg, get_nodes_block(ret), ret, mode_M, 3);
+ cf_pred[n_exc] = new_r_Proj(get_nodes_block(ret), ret, mode_M, 3);
n_exc++;
} else if (is_fragile_op(ret)) {
/* We rely that all cfops have the memory output at the same position. */
- cf_pred[n_exc] = new_r_Proj(irg, get_nodes_block(ret), ret, mode_M, 0);
+ cf_pred[n_exc] = new_r_Proj(get_nodes_block(ret), ret, mode_M, 0);
n_exc++;
} else if (is_Raise(ret)) {
- cf_pred[n_exc] = new_r_Proj(irg, get_nodes_block(ret), ret, mode_M, 1);
+ cf_pred[n_exc] = new_r_Proj(get_nodes_block(ret), ret, mode_M, 1);
n_exc++;
}
}
for (i = 0; i < n_exc; ++i)
end_preds[main_end_bl_arity + i] = cf_pred[i];
set_irn_in(main_end_bl, n_exc + main_end_bl_arity, end_preds);
- set_Tuple_pred(call, pn_Call_X_except, new_Bad());
- set_Tuple_pred(call, pn_Call_M_except, new_Bad());
+ set_Tuple_pred(call, pn_Call_X_except, new_Bad());
+ set_Tuple_pred(call, pn_Call_M_except, new_Bad());
free(end_preds);
}
free(res_pred);