Revert reversion of r28379. Maybe this way it's clear why the assert was wrong.
[libfirm] / ir / opt / combo.c
index 5f7c680..bb00e89 100644 (file)
@@ -290,8 +290,12 @@ static void check_opcode(const partition_t *Z)
                                key.u.intVal = get_Conv_strict(irn);
                                break;
                        case iro_Div:
+                               key.mode = get_Div_resmode(irn);
                                key.u.intVal = get_Div_no_remainder(irn);
                                break;
+                       case iro_Mod:
+                               key.mode = get_Mod_resmode(irn);
+                               break;
                        case iro_Block:
                                key.u.block = irn;
                                break;
@@ -307,32 +311,41 @@ static void check_opcode(const partition_t *Z)
                        first = 0;
                } else {
                        assert((unsigned)key.code  == get_irn_opcode(irn));
-                       assert(key.mode  == get_irn_mode(irn));
                        assert(key.arity == get_irn_arity(irn));
 
                        switch (get_irn_opcode(irn)) {
                        case iro_Proj:
+                               assert(key.mode  == get_irn_mode(irn));
                                assert(key.u.proj == get_Proj_proj(irn));
                                break;
                        case iro_Sel:
+                               assert(key.mode  == get_irn_mode(irn));
                                assert(key.u.ent == get_Sel_entity(irn));
                                break;
                        case iro_Conv:
+                               assert(key.mode  == get_irn_mode(irn));
                                assert(key.u.intVal == get_Conv_strict(irn));
                                break;
                        case iro_Div:
+                               assert(key.mode  == get_Div_resmode(irn));
                                assert(key.u.intVal == get_Div_no_remainder(irn));
                                break;
+                       case iro_Mod:
+                               assert(key.mode == get_Mod_resmode(irn));
+                               break;
                        case iro_Block:
+                               assert(key.mode  == get_irn_mode(irn));
                                assert(key.u.block == irn);
                                break;
                        case iro_Load:
                                assert(key.mode == get_Load_mode(irn));
                                break;
                        case iro_Builtin:
+                               assert(key.mode  == get_irn_mode(irn));
                                assert(key.u.intVal == (int) get_Builtin_kind(irn));
                                break;
                        default:
+                               assert(key.mode  == get_irn_mode(irn));
                                break;
                        }
                }
@@ -2618,7 +2631,7 @@ static void compute(node_t *node)
 }  /* compute */
 
 /*
- * Identity functions: Note that one might thing that identity() is just a
+ * Identity functions: Note that one might think that identity() is just a
  * synonym for equivalent_node(). While this is true, we cannot use it for the algorithm
  * here, because it expects that the identity node is one of the inputs, which is NOT
  * always true for equivalent_node() which can handle (and does sometimes) DAGs.
@@ -3255,8 +3268,20 @@ static void exchange_leader(ir_node *irn, ir_node *leader)
                 * the number of Conv due to CSE. */
                ir_node  *block = get_nodes_block(leader);
                dbg_info *dbg   = get_irn_dbg_info(irn);
-
-               leader = new_rd_Conv(dbg, block, leader, mode);
+               ir_node  *nlead = new_rd_Conv(dbg, block, leader, mode);
+
+               if (nlead != leader) {
+                       /* Note: this newly create irn has no node info because
+                        * it is created after the analysis. However, this node
+                        * replaces the node irn and should not be visited again,
+                        * so set its visited count to the count of irn.
+                        * Otherwise we might visited this node more than once if
+                        * irn had more than one user.
+                        */
+                       set_irn_node(nlead, NULL);
+                       set_irn_visited(nlead, get_irn_visited(irn));
+                       leader = nlead;
+               }
        }
        exchange(irn, leader);
 }  /* exchange_leader */
@@ -3507,10 +3532,10 @@ static void apply_end(ir_node *end, environment_t *env)
  */
 static void set_compute_functions(void)
 {
-       int i;
+       size_t i, n;
 
        /* set the default compute function */
-       for (i = get_irp_n_opcodes() - 1; i >= 0; --i) {
+       for (i = 0, n = get_irp_n_opcodes(); i < n; ++i) {
                ir_op *op = get_irp_opcode(i);
                op->ops.generic = (op_func)default_compute;
        }
@@ -3536,10 +3561,11 @@ static void set_compute_functions(void)
 /**
  * Add memory keeps.
  */
-static void add_memory_keeps(ir_node **kept_memory, int len)
+static void add_memory_keeps(ir_node **kept_memory, size_t len)
 {
        ir_node      *end = get_irg_end(current_ir_graph);
        int          i;
+       size_t       idx;
        ir_nodeset_t set;
 
        ir_nodeset_init(&set);
@@ -3548,8 +3574,8 @@ static void add_memory_keeps(ir_node **kept_memory, int len)
        for (i = get_End_n_keepalives(end) - 1; i >= 0; --i)
                ir_nodeset_insert(&set, get_End_keepalive(end, i));
 
-       for (i = len - 1; i >= 0; --i) {
-               ir_node *ka = kept_memory[i];
+       for (idx = 0; idx < len; ++idx) {
+               ir_node *ka = kept_memory[idx];
 
                if (! ir_nodeset_contains(&set, ka)) {
                        add_End_keepalive(end, ka);