- don't place copies between proj cascades
authorMatthias Braun <matze@braunis.de>
Mon, 12 Jun 2006 13:56:26 +0000 (13:56 +0000)
committerMatthias Braun <matze@braunis.de>
Mon, 12 Jun 2006 13:56:26 +0000 (13:56 +0000)
ir/be/benode.c
ir/be/benode_t.h
ir/be/bespill.c
ir/be/beverify.c

index 487166b..432ba1d 100644 (file)
@@ -894,7 +894,9 @@ ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn, ir_node *ctx)
        const arch_register_class_t *cls_frame = arch_get_irn_reg_class(arch_env, frame, -1);
 
        spill = be_new_Spill(cls, cls_frame, irg, bl, frame, irn, ctx);
+       return spill;
 
+#if 0
        /*
         * search the right insertion point. a spill of a phi cannot be put
         * directly after the phi, if there are some phis behind the one which
@@ -916,6 +918,7 @@ ir_node *be_spill(const arch_env_t *arch_env, ir_node *irn, ir_node *ctx)
 
        sched_add_before(insert, spill);
        return spill;
+#endif
 }
 
 ir_node *be_reload(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *insert, ir_mode *mode, ir_node *spill)
index a0c1997..a50c5cf 100644 (file)
@@ -273,7 +273,7 @@ ir_node *be_new_RegParams(ir_graph *irg, ir_node *bl, int n_out);
 ir_node *be_new_Barrier(ir_graph *irg, ir_node *bl, int n, ir_node *in[]);
 
 /**
- * Make a spill node and insert it into the schedule.
+ * Make a spill node.
  *
  * @param arch_env  The architecture environment.
  * @param irn       The node to be spilled.
index ea69d80..29d2a7d 100644 (file)
@@ -144,6 +144,26 @@ static spill_ctx_t *be_get_spill_ctx(set *sc, ir_node *to_spill, ir_node *ctx_ir
        return set_insert(sc, &templ, sizeof(templ), HASH_COMBINE(HASH_PTR(to_spill), HASH_PTR(ctx_irn)));
 }
 
+/**
+ * Schedules a node after an instruction. (That is the place after all projs and phis
+ * that are scheduled after the instruction)
+ */
+static void sched_add_after_insn(ir_node *sched_after, ir_node *node) {
+       ir_node *next = sched_next(sched_after);
+       while(!sched_is_end(next)) {
+               if(!is_Proj(next) && !is_Phi(next))
+                       break;
+               next = sched_next(next);
+       }
+
+       if(sched_is_end(next)) {
+               next = sched_last(get_nodes_block(sched_after));
+               sched_add_after(next, node);
+       } else {
+               sched_add_before(next, node);
+       }
+}
+
 /**
  * Creates a spill.
  *
@@ -171,6 +191,7 @@ static ir_node *be_spill_irn(spill_env_t *senv, ir_node *irn, ir_node *ctx_irn)
        }
 
        ctx->spill = be_spill(env->arch_env, irn, ctx_irn);
+       sched_add_after_insn(irn, ctx->spill);
 
        return ctx->spill;
 }
@@ -200,9 +221,18 @@ static void remove_copies(spill_env_t *env) {
        ARR_SETLEN(ir_node*, env->copies, 0);
 }
 
+static INLINE ir_node *skip_projs(ir_node *node) {
+       while(is_Proj(node)) {
+               node = sched_next(node);
+               assert(!sched_is_end(node));
+       }
+
+       return node;
+}
+
 /**
- * Searchs the schedule of a block backwards until we reach the first
- * use or def of a value or a phi.
+ * Searchs the schedule backwards until we reach the first use or def of a
+ * value or a phi.
  * Returns the node before this node (so that you can do sched_add_before)
  */
 static ir_node *find_last_use_def(spill_env_t *env, ir_node *block, ir_node *value) {
@@ -216,12 +246,12 @@ static ir_node *find_last_use_def(spill_env_t *env, ir_node *block, ir_node *val
                        return last;
                }
                if(value == node) {
-                       return last;
+                       return skip_projs(last);
                }
                for(i = 0, arity = get_irn_arity(node); i < arity; ++i) {
                        ir_node *arg = get_irn_n(node, i);
                        if(arg == value) {
-                               return last;
+                               return skip_projs(node);
                        }
                }
                last = node;
@@ -572,10 +602,15 @@ void be_add_reload_on_edge(spill_env_t *env, ir_node *to_spill, ir_node *block,
                return;
        }
 
-       // We have to reload the value in pred-block
+       /* We have to reload the value in pred-block */
        predblock = get_Block_cfgpred_block(block, pos);
        last = sched_last(predblock);
-       // there should be exactly 1 jump at the end of the block
+
+       /* we might have projs and keepanys behind the jump... */
+       while(is_Proj(last) || be_is_Keep(last)) {
+               last = sched_prev(last);
+               assert(!sched_is_end(last));
+       }
        assert(is_cfop(last));
 
        // add the reload before the (cond-)jump
index 15a5533..24fa71b 100644 (file)
@@ -18,6 +18,7 @@
 #include "irgwalk.h"
 #include "irprintf.h"
 #include "irdump_t.h"
+#include "benode_t.h"
 
 typedef struct be_verify_register_pressure_env_t_ {
        ir_graph                    *irg;                 /**< the irg to verify */
@@ -148,13 +149,16 @@ static void verify_schedule_walker(ir_node *block, void *data)
                        }
                        cfchange_found = 1;
                } else if (cfchange_found) {
-                       /* check for delay branches */
-                       if (delay_branches == 0) {
-                               ir_fprintf(stderr, "Verify Warning: Node %+F scheduled after control flow changing node (+delay branches) in block %+F (%s)\n",
-                                       node, block, get_irg_dump_name(env->irg));
-                               env->problem_found = 1;
-                       } else {
-                               delay_branches--;
+                       // proj and keepany aren't real instructions...
+                       if(!is_Proj(node) && !be_is_Keep(node)) {
+                               /* check for delay branches */
+                               if (delay_branches == 0) {
+                                       ir_fprintf(stderr, "Verify Warning: Node %+F scheduled after control flow changing node (+delay branches) in block %+F (%s)\n",
+                                               node, block, get_irg_dump_name(env->irg));
+                                       env->problem_found = 1;
+                               } else {
+                                       delay_branches--;
+                               }
                        }
                }