Commit 9db506dd authored by Matthias Braun's avatar Matthias Braun
Browse files

- Tried to remove empty blocks before emitting, but commented it out again

  as the irextbb algo fails for critical edges
- Make sure removed nodes have their preds set to Bad
- some cleanups
parent cfb8a461
......@@ -41,6 +41,7 @@
#include "../besched_t.h"
#include "../be.h"
#include "../be_t.h"
#include "../beirgmod.h"
#include "bearch_ia32_t.h"
#include "ia32_new_nodes.h" /* ia32 nodes interface */
......@@ -907,8 +908,12 @@ static void remove_unused_nodes(ir_node *irn, bitset_t *already_visited) {
remove_unused_nodes(pred, already_visited);
}
if (sched_is_scheduled(irn))
if (sched_is_scheduled(irn)) {
set_irn_n(irn, 0, new_Bad());
set_irn_n(irn, 1, new_Bad());
set_irn_n(irn, 2, new_Bad());
sched_remove(irn);
}
}
static void remove_unused_loads_walker(ir_node *irn, void *env) {
......@@ -926,8 +931,6 @@ static void ia32_before_ra(void *self) {
ia32_code_gen_t *cg = self;
bitset_t *already_visited = bitset_irg_malloc(cg->irg);
cg->blk_sched = sched_create_block_schedule(cg->irg);
/*
Handle special case:
There are sometimes unused loads, only pinned by memory.
......@@ -1163,6 +1166,11 @@ static void transform_MemPerm(ia32_transform_env_t *env) {
set_Proj_proj(proj, 3);
}
// remove memperm
arity = get_irn_arity(node);
for(i = 0; i < arity; ++i) {
set_irn_n(node, i, new_Bad());
}
sched_remove(node);
}
......@@ -1232,7 +1240,7 @@ static void ia32_after_ra(void *self) {
ia32_code_gen_t *cg = self;
ir_graph *irg = cg->irg;
irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, self);
irg_block_walk_graph(irg, NULL, ia32_after_ra_walker, cg);
ia32_finish_irg(irg, cg);
}
......@@ -1244,6 +1252,12 @@ static void ia32_finish(void *self) {
ia32_code_gen_t *cg = self;
ir_graph *irg = cg->irg;
// Matze: disabled for now, as the irextbb algo sometimes returns extbb in
// the wrong order if the graph has critical edges
//be_remove_empty_blocks(irg, cg);
cg->blk_sched = sched_create_block_schedule(cg->irg);
/* if we do x87 code generation, rewrite all the virtual instructions and registers */
if (cg->used_fp == fp_x87 || cg->force_sim) {
x87_simulate_graph(cg->arch_env, irg, cg->blk_sched);
......
......@@ -829,57 +829,59 @@ static ir_node *get_proj(const ir_node *irn, long proj) {
* Emits the jump sequence for a conditional jump (cmp + jmp_true + jmp_false)
*/
static void finish_CondJmp(FILE *F, const ir_node *irn, ir_mode *mode) {
const ir_node *proj1, *proj2 = NULL;
const ir_node *block, *next_bl = NULL;
const ir_node *proj_true;
const ir_node *proj_false;
const ir_node *block;
const ir_node *next_block;
char buf[SNPRINTF_BUF_LEN];
char cmd_buf[SNPRINTF_BUF_LEN];
char cmnt_buf[SNPRINTF_BUF_LEN];
int is_unsigned;
int pnc;
int flipped = 0;
/* get both Proj's */
proj1 = get_proj(irn, pn_Cond_true);
assert(proj1 && "CondJmp without true Proj");
proj_true = get_proj(irn, pn_Cond_true);
assert(proj_true && "CondJmp without true Proj");
proj2 = get_proj(irn, pn_Cond_false);
assert(proj2 && "CondJmp without false Proj");
proj_false = get_proj(irn, pn_Cond_false);
assert(proj_false && "CondJmp without false Proj");
pnc = get_ia32_pncode(irn);
/* for now, the code works for scheduled and non-schedules blocks */
block = get_nodes_block(irn);
/* we have a block schedule */
next_bl = next_blk_sched(block);
next_block = next_blk_sched(block);
if (get_cfop_target_block(proj1) == next_bl) {
if (get_cfop_target_block(proj_true) == next_block) {
/* exchange both proj's so the second one can be omitted */
const ir_node *t = proj1;
proj1 = proj2;
proj2 = t;
const ir_node *t = proj_true;
proj_true = proj_false;
proj_false = t;
flipped = 1;
pnc = get_negated_pnc(pnc, mode);
}
/* the first Proj must always be created */
is_unsigned = mode_is_float(mode) || ! mode_is_signed(mode);
if (get_Proj_proj(proj1) == pn_Cond_true) {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
get_cmp_suffix(get_ia32_pncode(irn), is_unsigned),
get_cfop_target(proj1, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == TRUE */");
}
else {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
get_cmp_suffix(get_negated_pnc(get_ia32_pncode(irn), mode), is_unsigned),
get_cfop_target(proj1, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* cmp(a, b) == FALSE */");
}
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "j%s %s",
get_cmp_suffix(pnc, is_unsigned),
get_cfop_target(proj_true, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* %s(a, b) %s*/",
get_pnc_string(pnc), flipped ? "(was flipped)" : "");
IA32_DO_EMIT(irn);
/* the second Proj might be a fallthrough */
if (get_cfop_target_block(proj2) != next_bl) {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(proj2, buf));
if (get_cfop_target_block(proj_false) != next_block) {
snprintf(cmd_buf, SNPRINTF_BUF_LEN, "jmp %s", get_cfop_target(proj_false, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* otherwise */");
}
else {
cmd_buf[0] = '\0';
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrough %s */", get_cfop_target(proj2, buf));
snprintf(cmnt_buf, SNPRINTF_BUF_LEN, "/* fallthrough %s */", get_cfop_target(proj_false, buf));
}
IA32_DO_EMIT(irn);
}
......
......@@ -447,78 +447,6 @@ static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) {
}
}
#if 0
/**
* Creates a Push from Store(IncSP(gp_reg_size))
*/
static void ia32_create_Push(ir_node *irn, ia32_code_gen_t *cg) {
ir_node *sp = get_irn_n(irn, 0);
ir_graph *irg = cg->irg;
ir_node *val, *next, *push, *bl, *proj_M, *proj_res, *old_proj_M, *mem;
const ir_edge_t *edge;
heights_t *h;
/* do not create push if store has already an offset assigned or base is not a IncSP */
if (get_ia32_am_offs(irn) || ! be_is_IncSP(sp))
return;
/* do not create push if index is not NOREG */
if (arch_get_irn_register(cg->arch_env, get_irn_n(irn, 1)) !=
&ia32_gp_regs[REG_GP_NOREG])
return;
/* do not create push for floating point */
val = get_irn_n(irn, 2);
if (mode_is_float(get_irn_mode(val)))
return;
/* do not create push if IncSp doesn't expand stack or expand size is different from register size */
if (be_get_IncSP_offset(sp) != get_mode_size_bytes(ia32_reg_classes[CLASS_ia32_gp].mode))
return;
/* do not create push, if there is a path (inside the block) from the push value to IncSP */
h = heights_new(cg->irg);
if (get_nodes_block(val) == get_nodes_block(sp) &&
heights_reachable_in_block(h, val, sp))
{
heights_free(h);
return;
}
heights_free(h);
/* ok, translate into Push */
edge = get_irn_out_edge_first(irn);
old_proj_M = get_edge_src_irn(edge);
bl = get_nodes_block(irn);
next = sched_next(irn);
sched_remove(irn);
sched_remove(sp);
/*
build memory input:
if the IncSP points to NoMem -> just use the memory input from store
if IncSP points to somewhere else -> sync memory of IncSP and Store
*/
mem = get_irn_n(irn, 3);
push = new_rd_ia32_Push(NULL, irg, bl, be_get_IncSP_pred(sp), val, mem);
proj_res = new_r_Proj(irg, bl, push, get_irn_mode(sp), pn_ia32_Push_stack);
proj_M = new_r_Proj(irg, bl, push, mode_M, pn_ia32_Push_M);
/* copy a possible constant from the store */
set_ia32_id_cnst(push, get_ia32_id_cnst(irn));
set_ia32_immop_type(push, get_ia32_immop_type(irn));
/* the push must have SP out register */
arch_set_irn_register(cg->arch_env, push, arch_get_irn_register(cg->arch_env, sp));
exchange(old_proj_M, proj_M);
exchange(sp, proj_res);
sched_add_before(next, push);
sched_add_after(push, proj_res);
}
#endif
// only optimize up to 48 stores behind IncSPs
#define MAXPUSH_OPTIMIZE 48
......@@ -642,7 +570,11 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) {
set_irn_n(succ, 0, push);
}
// we can remove the store from schedule now
// we can remove the store now
set_irn_n(store, 0, new_Bad());
set_irn_n(store, 1, new_Bad());
set_irn_n(store, 2, new_Bad());
set_irn_n(store, 3, new_Bad());
sched_remove(store);
offset -= 4;
......@@ -654,9 +586,6 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) {
if(offset == 0) {
const ir_edge_t *edge, *next;
sched_remove(irn);
set_irn_n(irn, 0, new_Bad());
foreach_out_edge_safe(irn, edge, next) {
ir_node *arg = get_edge_src_irn(edge);
int pos = get_edge_src_pos(edge);
......@@ -664,8 +593,8 @@ static void ia32_create_Pushs(ir_node *irn, ia32_code_gen_t *cg) {
set_irn_n(arg, pos, curr_sp);
}
sched_remove(irn);
set_irn_n(irn, 0, new_Bad());
sched_remove(irn);
} else {
set_irn_n(irn, 0, curr_sp);
}
......@@ -687,6 +616,8 @@ static void ia32_optimize_IncSP(ir_node *irn, ia32_code_gen_t *cg) {
/* Omit the optimized IncSP */
be_set_IncSP_pred(irn, be_get_IncSP_pred(prev));
set_irn_n(prev, 0, new_Bad());
sched_remove(prev);
}
}
......@@ -716,7 +647,6 @@ void ia32_peephole_optimization(ir_graph *irg, ia32_code_gen_t *cg) {
irg_walk_graph(irg, ia32_peephole_optimize_node, NULL, cg);
}
/******************************************************************
* _ _ __ __ _
* /\ | | | | | \/ | | |
......@@ -1064,15 +994,24 @@ static INLINE void try_add_to_sched(ir_node *irn, ir_node *res) {
* @param irn The irn to be removed from schedule
*/
static INLINE void try_remove_from_sched(ir_node *irn) {
int i, arity;
if (sched_is_scheduled(irn)) {
if (get_irn_mode(irn) == mode_T) {
const ir_edge_t *edge;
foreach_out_edge(irn, edge) {
ir_node *proj = get_edge_src_irn(edge);
if (sched_is_scheduled(proj))
if (sched_is_scheduled(proj)) {
set_irn_n(proj, 0, new_Bad());
sched_remove(proj);
}
}
}
arity = get_irn_arity(irn);
for(i = 0; i < arity; ++i) {
set_irn_n(irn, i, new_Bad());
}
sched_remove(irn);
}
}
......
Markdown is supported
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