Add ALLOCAN() and ALLOCANZ().
[libfirm] / ir / be / bepeephole.c
index e718459..c8869dd 100644 (file)
@@ -23,9 +23,7 @@
  * @author      Matthias Braun
  * @version     $Id$
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include "bepeephole.h"
 
@@ -60,9 +58,9 @@ static void clear_reg_value(ir_node *node)
        if(!mode_is_data(get_irn_mode(node)))
                return;
 
-       reg     = arch_get_irn_register(arch_env, node);
+       reg     = arch_get_irn_register(node);
        if(reg == NULL) {
-               panic("No register assigned at %+F\n", node);
+               panic("No register assigned at %+F", node);
        }
        if(arch_register_type_is(reg, virtual))
                return;
@@ -85,9 +83,9 @@ static void set_reg_value(ir_node *node)
        if(!mode_is_data(get_irn_mode(node)))
                return;
 
-       reg = arch_get_irn_register(arch_env, node);
+       reg = arch_get_irn_register(node);
        if(reg == NULL) {
-               panic("No register assigned at %+F\n", node);
+               panic("No register assigned at %+F", node);
        }
        if(arch_register_type_is(reg, virtual))
                return;
@@ -157,11 +155,11 @@ void be_peephole_before_exchange(const ir_node *old_node, ir_node *new_node)
        if (!mode_is_data(get_irn_mode(old_node)))
                return;
 
-       reg = arch_get_irn_register(arch_env, old_node);
+       reg = arch_get_irn_register(old_node);
        if (reg == NULL) {
-               panic("No register assigned at %+F\n", old_node);
+               panic("No register assigned at %+F", old_node);
        }
-       assert(reg == arch_get_irn_register(arch_env, new_node) &&
+       assert(reg == arch_get_irn_register(new_node) &&
              "KILLING a node and replacing by different register is not allowed");
 
        cls     = arch_register_get_class(reg);
@@ -300,8 +298,31 @@ static void        kill_barriers(ir_graph *irg) {
        skip_barrier(start_blk, irg);
 }
 
+/**
+ * Check whether the node has only one user.  Explicitly ignore the anchor.
+ */
+static int has_only_one_user(ir_node *node)
+{
+       int              n = get_irn_n_edges(node);
+       const ir_edge_t *edge;
+
+       if (n <= 1)
+               return 1;
+
+       if (n > 2)
+               return 0;
+
+       foreach_out_edge(node, edge) {
+               ir_node *src = get_edge_src_irn(edge);
+               if (is_Anchor(src))
+                       return 1;
+       }
+
+       return 0;
+}
+
 /*
- * Tries to optimize a beIncSp node with it's previous IncSP node.
+ * Tries to optimize a beIncSP node with its previous IncSP node.
  * Must be run from a be_peephole_opt() context.
  */
 ir_node *be_peephole_IncSP_IncSP(ir_node *node)
@@ -314,7 +335,7 @@ ir_node *be_peephole_IncSP_IncSP(ir_node *node)
        if (!be_is_IncSP(pred))
                return node;
 
-       if (get_irn_n_edges(pred) > 1)
+       if (!has_only_one_user(pred))
                return node;
 
        pred_offs = be_get_IncSP_offset(pred);
@@ -363,11 +384,11 @@ void be_peephole_opt(be_irg_t *birg)
        lv       = be_get_birg_liveness(birg);
 
        n_classes = arch_env_get_n_reg_class(arch_env);
-       register_values = alloca(sizeof(register_values[0]) * n_classes);
+       register_values = ALLOCAN(ir_node**, n_classes);
        for(i = 0; i < n_classes; ++i) {
                const arch_register_class_t *cls    = arch_env_get_reg_class(arch_env, i);
                unsigned                     n_regs = arch_register_class_n_regs(cls);
-               register_values[i] = alloca(sizeof(ir_node*) * n_regs);
+               register_values[i] = ALLOCAN(ir_node*, n_regs);
        }
 
        irg_block_walk_graph(irg, process_block, NULL, NULL);
@@ -383,4 +404,4 @@ void be_init_peephole(void)
        FIRM_DBG_REGISTER(dbg, "firm.be.peephole");
 }
 
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_spillbelady);
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_peephole);