Ignore generated files.
[libfirm] / ir / opt / opt_inline.c
index 5ec85e6..eb01365 100644 (file)
@@ -50,7 +50,7 @@
 #include "irouts.h"
 #include "irloop_t.h"
 #include "irbackedge_t.h"
-#include "opt_inline_t.h"
+#include "opt_init.h"
 #include "cgana.h"
 #include "trouts.h"
 #include "error.h"
@@ -1205,9 +1205,14 @@ int inline_method(ir_node *call, ir_graph *called_graph) {
                        }
                }
                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());
                }
@@ -1280,12 +1285,17 @@ typedef struct _inline_env_t {
  *
  * @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);
        }
 
@@ -1352,8 +1362,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
                        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;
                        }
 
@@ -1407,7 +1416,6 @@ typedef struct {
        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;
 
@@ -1426,7 +1434,6 @@ static inline_irg_env *alloc_inline_irg_env(void) {
        env->n_callers         = 0;
        env->n_callers_orig    = 0;
        env->got_inline        = 0;
-       env->local_vars        = 0;
        env->recursive         = 0;
        return env;
 }
@@ -1633,8 +1640,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize,
                                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;
                                }
 
@@ -1688,8 +1694,7 @@ void inline_leave_functions(unsigned maxsize, unsigned leavesize,
                        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;
                        }
 
@@ -1992,7 +1997,7 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee)
                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;
@@ -2045,7 +2050,7 @@ static int calc_inline_benefice(call_entry *entry, ir_graph *callee)
        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;
        }
 
@@ -2284,8 +2289,6 @@ static void inline_into(ir_graph *irg, unsigned maxsize,
 
                /* 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 */
@@ -2322,7 +2325,9 @@ static void inline_into(ir_graph *irg, unsigned maxsize,
  * 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;
@@ -2368,21 +2373,9 @@ void inline_functions(unsigned maxsize, int inline_threshold) {
                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",
@@ -2412,6 +2405,7 @@ struct inline_functions_pass_t {
        ir_prog_pass_t pass;
        unsigned       maxsize;
        int            inline_threshold;
+       opt_ptr        after_inline_opt;
 };
 
 /**
@@ -2421,18 +2415,21 @@ static int inline_functions_wrapper(ir_prog *irp, void *context) {
        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",