From 6ccb7925180213fd379ff051cfc226547fe895c2 Mon Sep 17 00:00:00 2001 From: Matthias Braun Date: Thu, 1 Mar 2007 21:07:15 +0000 Subject: [PATCH] - we have to handle copies from Unknown nodes - Precalculate liveness info again --- ir/be/ia32/ia32_x87.c | 114 +++++++++++++++++++++++------------------- 1 file changed, 62 insertions(+), 52 deletions(-) diff --git a/ir/be/ia32/ia32_x87.c b/ir/be/ia32/ia32_x87.c index 9cef9e40e..fdceee7be 100644 --- a/ir/be/ia32/ia32_x87.c +++ b/ir/be/ia32/ia32_x87.c @@ -18,6 +18,7 @@ #include "iredges_t.h" #include "irgmod.h" #include "ircons.h" +#include "irgwalk.h" #include "obst.h" #include "pmap.h" #include "pdeq.h" @@ -108,13 +109,13 @@ typedef unsigned char vfp_liveness; * The x87 simulator. */ struct _x87_simulator { - struct obstack obst; /**< An obstack for fast allocating. */ - pmap *blk_states; /**< Map blocks to states. */ - const arch_env_t *env; /**< The architecture environment. */ - be_lv_t *lv; /**< intrablock liveness. */ - vfp_liveness *live; /**< Liveness information. */ - unsigned n_idx; /**< The cached get_irg_last_idx() result. */ - waitq *worklist; /**< list of blocks to process. */ + struct obstack obst; /**< An obstack for fast allocating. */ + pmap *blk_states; /**< Map blocks to states. */ + const arch_env_t *arch_env; /**< The architecture environment. */ + be_lv_t *lv; /**< intrablock liveness. */ + vfp_liveness *live; /**< Liveness information. */ + unsigned n_idx; /**< The cached get_irg_last_idx() result. */ + waitq *worklist; /**< list of blocks to process. */ }; /** @@ -431,7 +432,7 @@ static ir_node *get_irn_Proj_for_mode(ir_node *n, ir_mode *m) { static INLINE const arch_register_t *x87_get_irn_register(x87_simulator *sim, const ir_node *irn) { const arch_register_t *res; - res = arch_get_irn_register(sim->env, irn); + res = arch_get_irn_register(sim->arch_env, irn); assert(res->reg_class->regs == ia32_vfp_regs); return res; } @@ -682,6 +683,7 @@ static ir_node *x87_create_fpop(x87_state *state, ir_node *n, int num, ir_node * attr->x87[1] = &ia32_st_regs[0]; attr->x87[2] = &ia32_st_regs[0]; + keep_alive(fpop); sched_add_before(n, fpop); DB((dbg, LEVEL_1, "<<< %s %s\n", get_irn_opname(fpop), attr->x87[0]->name)); @@ -733,7 +735,7 @@ static vfp_liveness vfp_liveness_transfer(x87_simulator *sim, ir_node *irn, vfp_ { int i, n; const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp]; - const arch_env_t *arch_env = sim->env; + const arch_env_t *arch_env = sim->arch_env; if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) { const arch_register_t *reg = x87_get_irn_register(sim, irn); @@ -765,7 +767,7 @@ static vfp_liveness vfp_liveness_end_of_block(x87_simulator *sim, const ir_node int i; vfp_liveness live = 0; const arch_register_class_t *cls = &ia32_reg_classes[CLASS_ia32_vfp]; - const arch_env_t *arch_env = sim->env; + const arch_env_t *arch_env = sim->arch_env; const be_lv_t *lv = sim->lv; be_lv_foreach(lv, block, be_lv_state_end, i) { @@ -1199,7 +1201,7 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) { assert(mem && "Store memory not found"); - arch_set_irn_register(sim->env, rproj, op2); + arch_set_irn_register(sim->arch_env, rproj, op2); /* reroute all former users of the store memory to the load memory */ edges_reroute(mem, mproj, irg); @@ -1244,11 +1246,11 @@ static int sim_store(x87_state *state, ir_node *n, ir_op *op, ir_op *op_p) { * Simulate a virtual Phi. * Just for cosmetic reasons change the mode of Phi nodes to mode_E. * - * @param state the x87 state - * @param n the node that should be simulated (and patched) - * @param env the architecture environment + * @param state the x87 state + * @param n the node that should be simulated (and patched) + * @param arch_env the architecture environment */ -static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *env) { +static int sim_Phi(x87_state *state, ir_node *n, const arch_env_t *arch_env) { ir_mode *mode = get_irn_mode(n); if (mode_is_float(mode)) @@ -1300,7 +1302,6 @@ GEN_LOAD(fld) GEN_LOAD(fild) GEN_LOAD(fldz) GEN_LOAD(fld1) -GEN_LOAD2(fConst, fldConst) GEN_STORE(fst) GEN_STORE(fist) @@ -1524,6 +1525,7 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) { /* Do not copy constants, recreate them. */ switch (get_ia32_irn_opcode(pred)) { + case iro_ia32_Unknown_VFP: case iro_ia32_fldz: cnstr = new_rd_ia32_fldz; break; @@ -1569,9 +1571,8 @@ static ir_node *create_Copy(x87_state *state, ir_node *n) { attr->x87[0] = op1 = &ia32_st_regs[op1_idx]; attr->x87[2] = out = &ia32_st_regs[0]; } - arch_set_irn_register(sim->env, res, out); + arch_set_irn_register(sim->arch_env, res, out); - DB((dbg, LEVEL_1, ">>> %+F -> %s\n", res, arch_register_get_name(out))); return res; } @@ -1608,8 +1609,19 @@ static int sim_Copy(x87_state *state, ir_node *n) { /* handle the infamous unknown value */ if (arch_register_get_index(op1) == REG_VFP_UKNWN) { - /* Matze: copies of unknowns should not happen (anymore) */ - assert(0); + /* Operand is still live, a real copy. We need here an fpush that can + hold a a register, so use the fpushCopy or recreate constants */ + node = create_Copy(state, n); + + assert(is_ia32_fldz(node)); + next = sched_next(n); + sched_remove(n); + exchange(n, node); + sched_add_before(next, node); + + DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name, + arch_get_irn_register(sim->arch_env, node)->name)); + return 0; } op1_idx = x87_on_stack(state, arch_register_get_index(op1)); @@ -1623,7 +1635,8 @@ static int sim_Copy(x87_state *state, ir_node *n) { sched_remove(n); exchange(n, node); sched_add_before(next, node); - DB((dbg, LEVEL_1, ">>> %+F %s -> %s\n", node, op1->name, out->name)); + DB((dbg, LEVEL_1, "<<< %+F %s -> %s\n", node, op1->name, + arch_get_irn_register(sim->arch_env, node)->name)); } else { out_idx = x87_on_stack(state, arch_register_get_index(out)); @@ -1653,12 +1666,12 @@ static int sim_Copy(x87_state *state, ir_node *n) { x87_pop(state); x87_set_st(state, arch_register_get_index(out), n, out_idx - 1); } - DB((dbg, LEVEL_1, ">>> %+F %s\n", n, op1->name)); + DB((dbg, LEVEL_1, "<<< %+F %s\n", n, op1->name)); } else { /* just a virtual copy */ x87_set_st(state, arch_register_get_index(out), get_unop_op(n), op1_idx); sched_remove(n); - DB((dbg, LEVEL_1, ">>> KILLED %s\n", get_irn_opname(n))); + DB((dbg, LEVEL_1, "<<< KILLED %s\n", get_irn_opname(n))); exchange(n, get_unop_op(n)); } } @@ -1669,11 +1682,11 @@ static int sim_Copy(x87_state *state, ir_node *n) { /** * Simulate a be_Call. * - * @param state the x87 state - * @param n the node that should be simulated - * @param env the architecture environment + * @param state the x87 state + * @param n the node that should be simulated + * @param arch_env the architecture environment */ -static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) { +static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *arch_env) { ir_type *call_tp = be_Call_get_type(n); /* at the begin of a call the x87 state should be empty */ @@ -1705,7 +1718,6 @@ static int sim_Call(x87_state *state, ir_node *n, const arch_env_t *env) { * * @param state the x87 state * @param n the node that should be simulated (and patched) - * @param env the architecture environment * * Should not happen, spills are lowered before x87 simulator see them. */ @@ -1719,7 +1731,6 @@ static int sim_Spill(x87_state *state, ir_node *n) { * * @param state the x87 state * @param n the node that should be simulated (and patched) - * @param env the architecture environment * * Should not happen, reloads are lowered before x87 simulator see them. */ @@ -1733,7 +1744,6 @@ static int sim_Reload(x87_state *state, ir_node *n) { * * @param state the x87 state * @param n the node that should be simulated (and patched) - * @param env the architecture environment */ static int sim_Return(x87_state *state, ir_node *n) { int n_res = be_Return_get_n_rets(n); @@ -1900,7 +1910,7 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) { if(bl_state->end != NULL) return; - update_liveness(sim, block); + //update_liveness(sim, block); DB((dbg, LEVEL_1, "Simulate %+F\n", block)); DB((dbg, LEVEL_2, "State at Block begin:\n ")); @@ -1909,7 +1919,7 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) { /* at block begin, kill all dead registers */ state = x87_kill_deads(sim, block, state); - /* beware, n might changed */ + /* beware, n might change */ for (n = sched_first(block); !sched_is_end(n); n = next) { int node_inserted; sim_func func; @@ -1970,15 +1980,16 @@ static void x87_simulate_block(x87_simulator *sim, ir_node *block) { /** * Create a new x87 simulator. * - * @param sim a simulator handle, will be initialized - * @param irg the current graph - * @param env the architecture environment + * @param sim a simulator handle, will be initialized + * @param irg the current graph + * @param arch_env the architecture environment */ -static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env_t *env) +static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, + const arch_env_t *arch_env) { obstack_init(&sim->obst); sim->blk_states = pmap_create(); - sim->env = env; + sim->arch_env = arch_env; sim->n_idx = get_irg_last_idx(irg); sim->live = obstack_alloc(&sim->obst, sizeof(*sim->live) * sim->n_idx); @@ -1993,7 +2004,6 @@ static void x87_init_simulator(x87_simulator *sim, ir_graph *irg, const arch_env #define ASSOC(op) (op_ ## op)->ops.generic = (op_func)(sim_##op) #define ASSOC_IA32(op) (op_ia32_v ## op)->ops.generic = (op_func)(sim_##op) #define ASSOC_BE(op) (op_be_ ## op)->ops.generic = (op_func)(sim_##op) - ASSOC_IA32(fConst); ASSOC_IA32(fld); ASSOC_IA32(fild); ASSOC_IA32(fld1); @@ -2034,6 +2044,12 @@ static void x87_destroy_simulator(x87_simulator *sim) { DB((dbg, LEVEL_1, "x87 Simulator stopped\n\n")); } /* x87_destroy_simulator */ +static void update_liveness_walker(ir_node *block, void *data) +{ + x87_simulator *sim = data; + update_liveness(sim, block); +} + /** * Run a simulation and fix all virtual instructions for a graph. * @@ -2042,14 +2058,14 @@ static void x87_destroy_simulator(x87_simulator *sim) { * * Needs a block-schedule. */ -void x87_simulate_graph(const arch_env_t *env, be_irg_t *birg) { +void x87_simulate_graph(const arch_env_t *arch_env, be_irg_t *birg) { ir_node *block, *start_block; blk_state *bl_state; x87_simulator sim; ir_graph *irg = birg->irg; /* create the simulator */ - x87_init_simulator(&sim, irg, env); + x87_init_simulator(&sim, irg, arch_env); start_block = get_irg_start_block(irg); bl_state = x87_get_bl_state(&sim, start_block); @@ -2065,19 +2081,13 @@ void x87_simulate_graph(const arch_env_t *env, be_irg_t *birg) { be_assure_liveness(birg); sim.lv = birg->lv; -#if 0 - /* Create the worklist for the schedule and calculate the liveness - for all nodes. We must precalculate this info, because the - simulator adds new nodes (and possible before Phi nodes) which - let fail the old lazy calculation. - On the other hand we reduce the computation amount due to - precaching from O(n^2) to O(n) at the expense of O(n) cache memory. + /* Calculate the liveness for all nodes. We must precalculate this info, + * because the simulator adds new nodes (possible before Phi nodes) which + * would let a lazy calculation fail. + * On the other hand we reduce the computation amount due to + * precaching from O(n^2) to O(n) at the expense of O(n) cache memory. */ - for (i = 0, n = ARR_LEN(blk_list); i < n; ++i) { - update_liveness(&sim, lv, blk_list[i]); - waitq_put(worklist, blk_list[i]); - } -#endif + irg_block_walk_graph(irg, update_liveness_walker, NULL, &sim); /* iterate */ do { -- 2.20.1