Commit 75f468ec authored by Matthias Braun's avatar Matthias Braun
Browse files

- don't place copies between proj cascades

parent 47401b7f
......@@ -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)
......
......@@ -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.
......
......@@ -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
......
......@@ -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--;
}
}
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment