* @file
* @brief Dead node elimination and Procedure Inlining.
* @author Michael Beck, Goetz Lindenmaier
- * @version $Id$
*/
#include "config.h"
#include "irtools.h"
#include "iropt_dbg.h"
#include "irpass_t.h"
-#include "irphase_t.h"
+#include "irnodemap.h"
DEBUG_ONLY(static firm_dbg_module_t *dbg;)
{
bool *allow_inline = (bool*)env;
- if (is_Sel(node)) {
+ if (is_Block(node) && get_Block_entity(node)) {
+ /**
+ * Currently we can't handle blocks whose address was taken correctly
+ * when inlining
+ */
+ *allow_inline = false;
+ } else if (is_Sel(node)) {
ir_graph *irg = current_ir_graph;
if (get_Sel_ptr(node) == get_irg_frame(irg)) {
/* access to frame */
/* 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));
}
}
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_extblk_inconsistent(irg);
- set_irg_doms_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 */
ir_node *addr;
addr = get_Call_ptr(call);
- if (is_Global(addr)) {
- ir_entity *ent = get_Global_entity(addr);
+ if (is_SymConst_addr_ent(addr)) {
+ ir_entity *ent = get_SymConst_entity(addr);
/* we don't know which function gets finally bound to a weak symbol */
if (get_entity_linkage(ent) & IR_LINKAGE_WEAK)
return NULL;
if (env->ignore_runtime) {
ir_node *symc = get_Call_ptr(call);
- if (is_Global(symc)) {
- ir_entity *ent = get_Global_entity(symc);
+ if (is_SymConst_addr_ent(symc)) {
+ ir_entity *ent = get_SymConst_entity(symc);
if (get_entity_additional_properties(ent) & mtp_property_runtime)
return;
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;
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);
}