Remove arch_get_allocatable_regs().
[libfirm] / ir / opt / return.c
index fb1e3c2..426ea72 100644 (file)
  * @author  Michael Beck
  * @version $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include "iroptimize.h"
 #include "irgraph_t.h"
 #include "ircons_t.h"
 #include "irnode_t.h"
 #include "irgmod.h"
-#include "xmalloc.h"
 
 #define set_bit(n)      (returns[(n) >> 3] |= 1 << ((n) & 7))
 #define get_bit(n)      (returns[(n) >> 3] & (1 << ((n) & 7)))
@@ -155,11 +152,11 @@ void normalize_one_return(ir_graph *irg) {
        set_irg_doms_inconsistent(irg);
        set_irg_outs_inconsistent(irg);
        set_irg_extblk_inconsistent(irg);
-       set_irg_loopinfo_state(irg, loopinfo_cf_inconsistent);
+       set_irg_loopinfo_inconsistent(irg);
 }
 
 /**
- * check, whether a Ret can be moved on block upwards.
+ * Check, whether a Return can be moved on block upwards.
  *
  * In a block with a Return, all live nodes must be linked
  * with the Return, otherwise they are dead (because the Return leaves
@@ -172,7 +169,7 @@ void normalize_one_return(ir_graph *irg) {
  * block of the Return block as well.
  *
  * All predecessors of the Return block must be Jmp's of course, or we
- * cannot move it up, so we check this either.
+ * cannot move it up, so we add blocks if needed.
  */
 static int can_move_ret(ir_node *ret) {
        ir_node *retbl = get_nodes_block(ret);
@@ -190,12 +187,21 @@ static int can_move_ret(ir_node *ret) {
 
        /* check, that predecessors are Jmps */
        n = get_Block_n_cfgpreds(retbl);
-       for (i = 0; i < n; ++i)
-               if (get_irn_op(get_Block_cfgpred(retbl, i)) != op_Jmp)
-                       return 0;
-
-       /* if we have 0 control flow predecessors, we cannot move :-) */
-       return n > 0;
+       if (n <= 1)
+               return 0;
+       for (i = 0; i < n; ++i) {
+               ir_node *pred = get_Block_cfgpred(retbl, i);
+
+               pred = skip_Tuple(pred);
+               if (! is_Jmp(pred) && !is_Bad(pred)) {
+                       /* simply place a new block here */
+                       ir_graph *irg  = get_irn_irg(retbl);
+                       ir_node *block = new_r_Block(irg, 1, &pred);
+                       ir_node *jmp   = new_r_Jmp(irg, block);
+                       set_Block_cfgpred(retbl, i, jmp);
+               }
+       }
+       return 1;
 }
 
 /*
@@ -238,9 +244,9 @@ void normalize_n_returns(ir_graph *irg) {
 
                if (is_Return(ret) && can_move_ret(ret)) {
                        /*
-                       * Ok, all conditions met, we can move this Return, put it
-                       * on our work list.
-                       */
+                        * Ok, all conditions met, we can move this Return, put it
+                        * on our work list.
+                        */
                        set_irn_link(ret, list);
                        list = ret;
                        ++n_rets;
@@ -276,12 +282,13 @@ void normalize_n_returns(ir_graph *irg) {
                        ir_node *jmp = get_Block_cfgpred(block, i);
                        ir_node *new_bl, *new_ret;
 
-                       if (get_irn_op(jmp) != op_Jmp)
+                       if (is_Bad(jmp))
                                continue;
+                       assert(is_Jmp(jmp));
 
                        new_bl = get_nodes_block(jmp);
 
-                       /* create the in-array for the new Ret */
+                       /* create the in-array for the new Return */
                        for (j = 0; j < n_ret_vals; ++j) {
                                ir_node *pred = get_irn_n(ret, j);
 
@@ -302,8 +309,7 @@ void normalize_n_returns(ir_graph *irg) {
                                        set_irn_link(new_ret, list);
                                        list = new_ret;
                                        ++n_rets;
-                               }
-                               else {
+                               } else {
                                        set_irn_link(new_ret, final);
                                        final = new_ret;
                                        ++n_finals;
@@ -352,5 +358,5 @@ void normalize_n_returns(ir_graph *irg) {
        set_irg_doms_inconsistent(irg);
        set_irg_extblk_inconsistent(irg);  /* may not be needed */
        set_irg_outs_inconsistent(irg);
-       set_irg_loopinfo_state(current_ir_graph, loopinfo_cf_inconsistent);
+       set_irg_loopinfo_inconsistent(current_ir_graph);
 }