}
}
if (n_exc > 0) {
- ir_node *block = new_Block(n_exc, cf_pred);
- set_cur_block(block);
- set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
+ if (n_exc == 1) {
+ /* simple fix */
+ set_Tuple_pred(call, pn_Call_X_except, cf_pred[0]);
+ } else {
+ ir_node *block = new_Block(n_exc, cf_pred);
+ set_cur_block(block);
+ set_Tuple_pred(call, pn_Call_X_except, new_Jmp());
+ }
} else {
set_Tuple_pred(call, pn_Call_X_except, new_Bad());
}
*
* @param call the call node
*/
-static ir_graph *get_call_called_irg(ir_node *call) {
+static ir_graph *get_call_called_irg(ir_node *call)
+{
ir_node *addr;
addr = get_Call_ptr(call);
if (is_Global(addr)) {
ir_entity *ent = get_Global_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;
+
return get_entity_irg(ent);
}
ir_graph *callee = entry->callee;
irg_inline_property prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden || get_irg_additional_properties(callee) & mtp_property_weak) {
- /* do not inline forbidden / weak graphs */
+ if (prop == irg_inline_forbidden) {
continue;
}
unsigned n_callers; /**< Number of known graphs that call this graphs. */
unsigned n_callers_orig; /**< for statistics */
unsigned got_inline:1; /**< Set, if at least one call inside this graph was inlined. */
- unsigned local_vars:1; /**< Set, if an inlined function got the address of a local variable. */
unsigned recursive:1; /**< Set, if this function is self recursive. */
} inline_irg_env;
env->n_callers = 0;
env->n_callers_orig = 0;
env->got_inline = 0;
- env->local_vars = 0;
env->recursive = 0;
return env;
}
callee = entry->callee;
prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden || get_irg_additional_properties(callee) & mtp_property_weak) {
- /* do not inline forbidden / weak graphs */
+ if (prop == irg_inline_forbidden) {
continue;
}
callee = entry->callee;
prop = get_irg_inline_property(callee);
- if (prop == irg_inline_forbidden || get_irg_additional_properties(callee) & mtp_property_weak) {
- /* do not inline forbidden / weak graphs */
+ if (prop == irg_inline_forbidden) {
continue;
}
return entry->benefice = INT_MIN;
}
- if (get_irg_additional_properties(callee) & (mtp_property_noreturn | mtp_property_weak)) {
+ 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));
return entry->benefice = INT_MIN;
callee_env = get_irg_link(callee);
if (callee_env->n_callers == 1 &&
callee != current_ir_graph &&
- get_entity_visibility(ent) == visibility_local) {
+ !entity_is_externally_visible(ent)) {
weight += 700;
}
/* callee was inline. Append it's call list. */
env->got_inline = 1;
- if (curr_call->local_adr)
- env->local_vars = 1;
--env->n_call_nodes;
/* we just generate a bunch of new calls */
* Heuristic inliner. Calculates a benefice value for every call and inlines
* those calls with a value higher than the threshold.
*/
-void inline_functions(unsigned maxsize, int inline_threshold) {
+void inline_functions(unsigned maxsize, int inline_threshold,
+ opt_ptr after_inline_opt)
+{
inline_irg_env *env;
int i, n_irgs;
ir_graph *rem;
ir_graph *irg = irgs[i];
env = get_irg_link(irg);
- if (env->got_inline) {
+ if (env->got_inline && after_inline_opt != NULL) {
/* this irg got calls inlined: optimize it */
- if (get_opt_combo()) {
- if (env->local_vars) {
- scalar_replacement_opt(irg);
- }
- combo(irg);
- } else {
- if (env->local_vars) {
- if (scalar_replacement_opt(irg)) {
- optimize_graph_df(irg);
- }
- }
- optimize_cf(irg);
- }
+ after_inline_opt(irg);
}
if (env->got_inline || (env->n_callers_orig != env->n_callers)) {
DB((dbg, LEVEL_1, "Nodes:%3d ->%3d, calls:%3d ->%3d, callers:%3d ->%3d, -- %s\n",
ir_prog_pass_t pass;
unsigned maxsize;
int inline_threshold;
+ opt_ptr after_inline_opt;
};
/**
struct inline_functions_pass_t *pass = context;
(void)irp;
- inline_functions(pass->maxsize, pass->inline_threshold);
+ inline_functions(pass->maxsize, pass->inline_threshold,
+ pass->after_inline_opt);
return 0;
}
/* create a ir_prog pass for inline_functions */
ir_prog_pass_t *inline_functions_pass(
- const char *name, unsigned maxsize, int inline_threshold) {
+ const char *name, unsigned maxsize, int inline_threshold,
+ opt_ptr after_inline_opt) {
struct inline_functions_pass_t *pass =
XMALLOCZ(struct inline_functions_pass_t);
pass->maxsize = maxsize;
pass->inline_threshold = inline_threshold;
+ pass->after_inline_opt = after_inline_opt;
return def_prog_pass_constructor(
&pass->pass, name ? name : "inline_functions",