/* access to value_type */
*allow_inline = false;
}
+ if (is_parameter_entity(ent)) {
+ *allow_inline = false;
+ }
}
} else if (is_Alloc(node) && get_Alloc_where(node) == stack_alloc) {
/* From GCC:
ir_entity *old_ent = get_class_member(from_frame, i);
ir_entity *new_ent = copy_entity_own(old_ent, to_frame);
set_entity_link(old_ent, new_ent);
+ assert (!is_parameter_entity(old_ent));
}
}
{
ir_node *pre_call;
ir_node *post_call, *post_bl;
- ir_node *in[pn_Start_max];
+ ir_node *in[pn_Start_max+1];
ir_node *end, *end_bl, *block;
ir_node **res_pred;
ir_node **cf_pred;
assert(get_irg_phase_state(irg) != phase_building);
assert(get_irg_pinned(irg) == op_pin_state_pinned);
assert(get_irg_pinned(called_graph) == op_pin_state_pinned);
- set_irg_outs_inconsistent(irg);
- set_irg_extblk_inconsistent(irg);
- set_irg_doms_inconsistent(irg);
- set_irg_loopinfo_inconsistent(irg);
+ clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE
+ | IR_GRAPH_STATE_VALID_EXTENDED_BLOCKS
+ | IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE);
set_irg_callee_info_state(irg, irg_callee_info_inconsistent);
- set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
+ clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_ENTITY_USAGE);
edges_deactivate(irg);
/* here we know we WILL inline, so inform the statistics */
in[pn_Start_X_initial_exec] = new_r_Jmp(post_bl);
in[pn_Start_P_frame_base] = get_irg_frame(irg);
in[pn_Start_T_args] = new_r_Tuple(post_bl, n_params, args_in);
- pre_call = new_r_Tuple(post_bl, pn_Start_max, in);
+ pre_call = new_r_Tuple(post_bl, pn_Start_max+1, in);
post_call = call;
/* --
{
ir_node *start_block;
ir_node *start;
- ir_node *bad;
ir_node *nomem;
start_block = get_irg_start_block(called_graph);
set_new_node(start, pre_call);
mark_irn_visited(start);
- bad = get_irg_bad(called_graph);
- set_new_node(bad, get_irg_bad(irg));
- mark_irn_visited(bad);
-
nomem = get_irg_no_mem(called_graph);
set_new_node(nomem, get_irg_no_mem(irg));
mark_irn_visited(nomem);
/* entitiy link is used to link entities on old stackframe to the
* new stackframe */
- irp_reserve_resources(irp, IR_RESOURCE_ENTITY_LINK);
+ irp_reserve_resources(irp, IRP_RESOURCE_ENTITY_LINK);
/* copy entities and nodes */
assert(!irn_visited(get_irg_end(called_graph)));
irg_walk_core(get_irg_end(called_graph), copy_node_inline, set_preds_inline,
irg);
- irp_free_resources(irp, IR_RESOURCE_ENTITY_LINK);
+ irp_free_resources(irp, IRP_RESOURCE_ENTITY_LINK);
/* -- Merge the end of the inlined procedure with the call site -- */
/* We will turn the old Call node into a Tuple with the following
/* build a Tuple for all results of the method.
* add Phi node if there was more than one Return. */
- turn_into_tuple(post_call, pn_Call_max);
+ turn_into_tuple(post_call, pn_Call_max+1);
/* First the Memory-Phi */
n_mem_phi = 0;
for (i = 0; i < arity; i++) {
}
}
if (n_ret > 0) {
- ir_mode *mode = get_irn_mode(cf_pred[0]);
- phi = new_r_Phi(post_bl, n_ret, cf_pred, mode);
+ phi = new_r_Phi(post_bl, n_ret, cf_pred, res_mode);
} else {
- phi = new_r_Bad(irg);
+ phi = new_r_Bad(irg, res_mode);
}
res_pred[j] = phi;
/* Conserve Phi-list for further inlinings -- but might be optimized */
result_tuple = new_r_Tuple(post_bl, n_res, res_pred);
set_Tuple_pred(call, pn_Call_T_result, result_tuple);
} else {
- set_Tuple_pred(call, pn_Call_T_result, new_r_Bad(irg));
+ set_Tuple_pred(call, pn_Call_T_result, new_r_Bad(irg, mode_T));
}
/* handle the regular call */
set_Tuple_pred(call, pn_Call_X_regular, new_r_Jmp(post_bl));
set_Tuple_pred(call, pn_Call_X_except, new_r_Jmp(block));
}
} else {
- set_Tuple_pred(call, pn_Call_X_except, new_r_Bad(irg));
+ set_Tuple_pred(call, pn_Call_X_except, new_r_Bad(irg, mode_X));
}
} else {
ir_node *main_end_bl;
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_r_Bad(irg));
+ set_Tuple_pred(call, pn_Call_X_except, new_r_Bad(irg, mode_X));
free(end_preds);
}
free(res_pred);
assert(get_irg_phase_state(irg) != phase_building);
free_callee_info(irg);
- assure_cf_loop(irg);
+ assure_loopinfo(irg);
wenv.x = (inline_irg_env*)get_irg_link(irg);
irg_walk_graph(irg, NULL, collect_calls2, &wenv);
}
callee_env = alloc_inline_irg_env();
set_irg_link(copy, callee_env);
- assure_cf_loop(copy);
+ assure_loopinfo(copy);
wenv.x = callee_env;
wenv.ignore_callers = 1;
irg_walk_graph(copy, NULL, collect_calls2, &wenv);
{
ir_node *call = entry->call;
ir_entity *ent = get_irg_entity(callee);
+ ir_type *callee_frame;
+ size_t i, n_members, n_params;
ir_node *frame_ptr;
ir_type *mtp;
int weight = 0;
- int i, n_params, all_const;
+ int all_const;
unsigned cc, v;
irg_inline_property prop;
return entry->benefice = INT_MIN;
}
+ callee_frame = get_irg_frame_type(callee);
+ n_members = get_class_n_members(callee_frame);
+ for (i = 0; i < n_members; ++i) {
+ ir_entity *frame_ent = get_class_member(callee_frame, i);
+ if (is_parameter_entity(frame_ent)) {
+ // TODO inliner should handle parameter entities by inserting Store operations
+ DB((dbg, LEVEL_2, "In %+F Call to %+F: inlining forbidden due to parameter entity\n", call, callee));
+ set_irg_inline_property(callee, irg_inline_forbidden);
+ return entry->benefice = INT_MIN;
+ }
+ }
+
if (get_irg_additional_properties(callee) & mtp_property_noreturn) {
DB((dbg, LEVEL_2, "In %+F Call to %+F: not inlining noreturn or weak\n",
call, callee));
cc = get_method_calling_convention(mtp);
if (cc & cc_reg_param) {
/* register parameter, smaller costs for register parameters */
- int max_regs = cc & ~cc_bits;
+ size_t max_regs = cc & ~cc_bits;
if (max_regs < n_params)
weight += max_regs * 2 + (n_params - max_regs) * 5;
callee_env = alloc_inline_irg_env();
set_irg_link(copy, callee_env);
- assure_cf_loop(copy);
+ assure_loopinfo(copy);
+ memset(&wenv, 0, sizeof(wenv));
wenv.x = callee_env;
wenv.ignore_callers = 1;
irg_walk_graph(copy, NULL, collect_calls2, &wenv);
* but we need Call nodes in our graph. Luckily the inliner leaves
* this information in the link field. */
new_call = (ir_node*)get_irn_link(centry->call);
+ if (get_irn_irg(new_call) != irg) {
+ /* centry->call has not been copied, which means it is dead.
+ * This might happen during inlining, if a const function,
+ * which cannot be inlined is only used as an unused argument
+ * of another function, which is inlined. */
+ continue;
+ }
assert(is_Call(new_call));
new_entry = duplicate_call_entry(centry, new_call, loop_depth);
free_callee_info(irg);
wenv.x = (inline_irg_env*)get_irg_link(irg);
- assure_cf_loop(irg);
+ assure_loopinfo(irg);
irg_walk_graph(irg, NULL, collect_calls2, &wenv);
}