removed some consts creating MSVC warnings
[libfirm] / ir / opt / tailrec.c
index ea75333..0d10cdc 100644 (file)
@@ -31,6 +31,7 @@
 #include <string.h>
 #include <assert.h>
 
+#include "debug.h"
 #include "iroptimize.h"
 #include "scalar_replace.h"
 #include "array.h"
@@ -47,6 +48,8 @@
 #include "irhooks.h"
 #include "xmalloc.h"
 
+DEBUG_ONLY(static firm_dbg_module_t *dbg);
+
 /**
  * the environment for collecting data
  */
@@ -180,7 +183,7 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) {
                exchange(p, new_r_Bad(irg));
 
                /* we might generate an endless loop, so add
-               * the block to the keep-alive list */
+                * the block to the keep-alive list */
                add_End_keepalive(get_irg_end(irg), block);
        }
 
@@ -273,18 +276,23 @@ static void do_opt_tail_rec(ir_graph *irg, ir_node *rets, int n_tail_calls) {
  * @return non-zero if it's ok to do tail recursion
  */
 static int check_lifetime_of_locals(ir_graph *irg) {
-       ir_node *irg_frame = get_irg_frame(irg);
+       ir_node *irg_frame, *irg_val_param_base;
        int i;
 
-       if (get_irg_outs_state(irg) != outs_consistent)
-               compute_irg_outs(irg);
-
+       irg_frame = get_irg_frame(irg);
        for (i = get_irn_n_outs(irg_frame) - 1; i >= 0; --i) {
                ir_node *succ = get_irn_out(irg_frame, i);
 
                if (is_Sel(succ) && is_address_taken(succ))
                        return 0;
        }
+
+       /* Check if we have compound arguments.
+          For now, we cannot handle them, */
+       irg_val_param_base = get_irg_value_param_base(irg);
+       if (get_irn_n_outs(irg_val_param_base) > 0)
+               return 0;
+
        return 1;
 }
 
@@ -297,8 +305,7 @@ int opt_tail_rec_irg(ir_graph *irg) {
        ir_node *rets = NULL;
        ir_type *mtd_type, *call_type;
 
-       if (! get_opt_tail_recursion() || ! get_opt_optimize())
-               return 0;
+       assure_irg_outs(irg);
 
        if (! check_lifetime_of_locals(irg))
                return 0;
@@ -328,13 +335,14 @@ int opt_tail_rec_irg(ir_graph *irg) {
                if (! is_Call(call))
                        continue;
 
+               /* the call must be in the same block as the return */
+               if (get_nodes_block(call) != get_nodes_block(ret))
+                       continue;
+
                /* check if it's a recursive call */
                call_ptr = get_Call_ptr(call);
 
-               if (get_irn_op(call_ptr) != op_SymConst)
-                       continue;
-
-               if (get_SymConst_kind(call_ptr) != symconst_addr_ent)
+               if (! is_SymConst(call_ptr) || get_SymConst_kind(call_ptr) != symconst_addr_ent)
                        continue;
 
                ent = get_SymConst_entity(call_ptr);
@@ -389,9 +397,8 @@ int opt_tail_rec_irg(ir_graph *irg) {
        if (! n_tail_calls)
                return 0;
 
-       if (get_opt_tail_recursion_verbose() && get_firm_verbosity() > 1)
-               printf("  Performing tail recursion for graph %s and %d Calls\n",
-               get_entity_ld_name(get_irg_entity(irg)), n_tail_calls);
+       DB((dbg, LEVEL_2, "  Performing tail recursion for graph %s and %d Calls\n",
+           get_entity_ld_name(get_irg_entity(irg)), n_tail_calls));
 
        hook_tail_rec(irg, n_tail_calls);
        do_opt_tail_rec(irg, rets, n_tail_calls);
@@ -407,8 +414,7 @@ void opt_tail_recursion(void) {
        int n_opt_applications = 0;
        ir_graph *irg;
 
-       if (! get_opt_tail_recursion() || ! get_opt_optimize())
-               return;
+       FIRM_DBG_REGISTER(dbg, "firm.opt.tailrec");
 
        for (i = get_irp_n_irgs() - 1; i >= 0; --i) {
                irg = get_irp_irg(i);
@@ -419,6 +425,6 @@ void opt_tail_recursion(void) {
                        ++n_opt_applications;
        }
 
-       if (get_opt_tail_recursion_verbose())
-               printf("Performed tail recursion for %d of %d graphs\n", n_opt_applications, get_irp_n_irgs());
+       DB((dbg, LEVEL_1, "Performed tail recursion for %d of %d graphs\n",
+           n_opt_applications, get_irp_n_irgs()));
 }