removed some consts creating MSVC warnings
[libfirm] / ir / opt / tailrec.c
index 93d9083..0d10cdc 100644 (file)
 # include "config.h"
 #endif
 
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
-
 #include <assert.h>
-#include "tailrec.h"
+
+#include "debug.h"
+#include "iroptimize.h"
+#include "scalar_replace.h"
 #include "array.h"
 #include "irprog_t.h"
 #include "irgwalk.h"
 #include "ircons.h"
 #include "irflag.h"
 #include "trouts.h"
-#include "return.h"
-#include "scalar_replace.h"
 #include "irouts.h"
 #include "irhooks.h"
 #include "xmalloc.h"
 
+DEBUG_ONLY(static firm_dbg_module_t *dbg);
+
 /**
  * the environment for collecting data
  */
@@ -183,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);
        }
 
@@ -276,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;
 }
 
@@ -300,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;
@@ -331,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);
@@ -358,9 +363,9 @@ int opt_tail_rec_irg(ir_graph *irg) {
                        continue;
 
                /*
-               * Check, that the types match. At least in C
-               * this might fail.
-               */
+                * Check, that the types match. At least in C
+                * this might fail.
+                */
                mtd_type  = get_entity_type(ent);
                call_type = get_Call_type(call);
 
@@ -375,7 +380,7 @@ int opt_tail_rec_irg(ir_graph *irg) {
                        dump_type(mtd_type);
                        dump_type(call_type);
 #endif
-                       return 0;
+                       continue;
                }
 
                /* here, we have found a call */
@@ -392,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);
@@ -410,16 +414,17 @@ 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);
 
+               current_ir_graph = irg;
+
                if (opt_tail_rec_irg(irg))
                        ++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()));
 }