From 75f468ecd02d392bc08492a343cc3fc1f58cbab4 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Mon, 12 Jun 2006 13:56:26 +0000 Subject: [PATCH] - don't place copies between proj cascades --- ir/be/benode.c | 3 +++ ir/be/benode_t.h | 2 +- ir/be/bespill.c | 47 +++++++++++++++++++++++++++++++++++++++++------ ir/be/beverify.c | 18 +++++++++++------- 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/ir/be/benode.c b/ir/be/benode.c index 487166bbf..432ba1de4 100644 --- a/ir/be/benode.c +++ b/ir/be/benode.c @@ -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) diff --git a/ir/be/benode_t.h b/ir/be/benode_t.h index a0c199744..a50c5cf83 100644 --- a/ir/be/benode_t.h +++ b/ir/be/benode_t.h @@ -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. diff --git a/ir/be/bespill.c b/ir/be/bespill.c index ea69d806b..29d2a7d56 100644 --- a/ir/be/bespill.c +++ b/ir/be/bespill.c @@ -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 diff --git a/ir/be/beverify.c b/ir/be/beverify.c index 15a553379..24fa71beb 100644 --- a/ir/be/beverify.c +++ b/ir/be/beverify.c @@ -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--; + } } } -- 2.20.1