BugFix:
[libfirm] / ir / opt / tailrec.c
index 45f1b50..28ab28f 100644 (file)
@@ -24,9 +24,7 @@
  * @author  Michael Beck
  * @version $Id$
  */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+#include "config.h"
 
 #include <string.h>
 #include <assert.h>
@@ -34,7 +32,7 @@
 #include "debug.h"
 #include "iroptimize.h"
 #include "scalar_replace.h"
-#include "array.h"
+#include "array_t.h"
 #include "irprog_t.h"
 #include "irgwalk.h"
 #include "irgmod.h"
@@ -47,7 +45,6 @@
 #include "irouts.h"
 #include "irhooks.h"
 #include "ircons_t.h"
-#include "xmalloc.h"
 
 DEBUG_ONLY(static firm_dbg_module_t *dbg);
 
@@ -307,9 +304,9 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env) {
 
                        modes[i] = mode;
                        if (env->variants[i] == TR_ADD) {
-                               set_value(i, new_Const(mode, get_mode_null(mode)));
+                               set_value(i, new_Const(get_mode_null(mode)));
                        } else if (env->variants[i] == TR_MUL) {
-                               set_value(i, new_Const(mode, get_mode_one(mode)));
+                               set_value(i, new_Const(get_mode_one(mode)));
                        }
                }
                mature_immBlock(start_block);
@@ -420,23 +417,24 @@ static void do_opt_tail_rec(ir_graph *irg, tr_env *env) {
  * @return non-zero if it's ok to do tail recursion
  */
 static int check_lifetime_of_locals(ir_graph *irg) {
-       ir_node *irg_frame, *irg_val_param_base;
+       ir_node *irg_frame;
        int i;
+       ir_type *frame_tp = get_irg_frame_type(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;
+               if (is_Sel(succ)) {
+                       /* Check if we have compound arguments.
+                          For now, we cannot handle them, */
+                       if (get_entity_owner(get_Sel_entity(succ)) != frame_tp)
+                               return 0;
 
+                       if (is_address_taken(succ))
+                               return 0;
+               }
+       }
        return 1;
 }