X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=769bebb6331a3f1f921aa5ab976222212f0aeee7;hb=1161999117f5c0f56b3af2dc9bb7150e03761905;hp=ea107be42b903062f45902b366d28a516c15818e;hpb=cd39b81dc83c8be8efe91c586b85c9f00b7cebe6;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index ea107be42..769bebb63 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -86,14 +86,15 @@ static ir_node *gen_SymConst(ia32_transform_env_t *env) { if (mode_is_float(mode)) { FP_USED(env->cg); if (USE_SSE2(env->cg)) - cnst = new_rd_ia32_fConst(dbg, irg, block, mode); + cnst = new_rd_ia32_xConst(dbg, irg, block, get_irg_no_mem(irg), mode); else - cnst = new_rd_ia32_vfConst(dbg, irg, block, mode); - } - else { - cnst = new_rd_ia32_Const(dbg, irg, block, mode); + cnst = new_rd_ia32_vfConst(dbg, irg, block, get_irg_no_mem(irg), mode); } + else + cnst = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode); + set_ia32_Const_attr(cnst, env->irn); + return cnst; } @@ -188,7 +189,7 @@ static ir_node *gen_Const(ia32_transform_env_t *env) { cnst = gen_SymConst(env); } else { - cnst = new_rd_ia32_Const(dbg, irg, block, get_irn_mode(node)); + cnst = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), get_irn_mode(node)); set_ia32_Const_attr(cnst, node); } return cnst; @@ -372,7 +373,7 @@ static int is_CondJmp_replacement(ir_node *cand, ir_node *irn) { int same_args = 1; for (i = 0; i < n; i++) { - if (get_irn_n(cand, i) == get_irn_n(irn, i)) { + if (get_irn_n(cand, i) != get_irn_n(irn, i)) { same_args = 0; break; } @@ -398,7 +399,7 @@ static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) { DBG((cg->mod, LEVEL_1, "replacing %+F by ", irn)); DBG_OPT_CJMP(irn); - set_irn_op(irn, op_ia32_CJmp); + set_irn_op(irn, op_ia32_CJmpAM); DB((cg->mod, LEVEL_1, "%+F\n", irn)); } @@ -437,9 +438,13 @@ static void ia32_create_Push(ir_node *irn, ia32_code_gen_t *cg) { bl = get_nodes_block(irn); push = new_rd_ia32_Push(NULL, current_ir_graph, bl, - be_get_IncSP_pred(sp), val, be_get_IncSP_mem(sp), mode_T); - proj_res = new_r_Proj(current_ir_graph, bl, push, get_irn_mode(sp), 0); - proj_M = new_r_Proj(current_ir_graph, bl, push, mode_M, 1); + be_get_IncSP_pred(sp), val, be_get_IncSP_mem(sp)); + proj_res = new_r_Proj(current_ir_graph, bl, push, get_irn_mode(sp), pn_ia32_Push_stack); + proj_M = new_r_Proj(current_ir_graph, 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)); @@ -494,10 +499,10 @@ static void ia32_create_Pop(ir_node *irn, ia32_code_gen_t *cg) { reg = arch_get_irn_register(cg->arch_env, load); sp = arch_get_irn_register(cg->arch_env, irn); - pop = new_rd_ia32_Pop(NULL, current_ir_graph, bl, get_irn_n(irn, 0), get_irn_n(load, 2), mode_T); - proj_res = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(old_proj_res), 0); - proj_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(irn), 1); - proj_M = new_r_Proj(current_ir_graph, bl, pop, mode_M, 2); + pop = new_rd_ia32_Pop(NULL, current_ir_graph, bl, get_irn_n(irn, 0), get_irn_n(load, 2)); + proj_res = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(old_proj_res), pn_ia32_Pop_res); + proj_sp = new_r_Proj(current_ir_graph, bl, pop, get_irn_mode(irn), pn_ia32_Pop_stack); + proj_M = new_r_Proj(current_ir_graph, bl, pop, mode_M, pn_ia32_Pop_M); exchange(old_proj_M, proj_M); exchange(old_proj_res, proj_res); @@ -511,8 +516,6 @@ static void ia32_create_Pop(ir_node *irn, ia32_code_gen_t *cg) { sched_add_before(proj_res,pop); } -/** - /** * Tries to optimize two following IncSP. */ @@ -555,8 +558,11 @@ void ia32_peephole_optimization(ir_node *irn, void *env) { ia32_optimize_TestJmp(irn, cg); else if (is_ia32_CondJmp(irn)) ia32_optimize_CondJmp(irn, cg); - else if (be_is_IncSP(irn)) - ia32_optimize_IncSP(irn, cg); + /* seems to be buggy when using Pushes */ +// else if (be_is_IncSP(irn)) +// ia32_optimize_IncSP(irn, cg); + else if (is_ia32_Store(irn)) + ia32_create_Push(irn, cg); } @@ -1185,6 +1191,25 @@ static void merge_loadstore_lea(ir_node *irn, ir_node *lea) { } +/** + * Sets new_right index of irn to right and new_left index to left. + * Also exchange left and right + */ +static void exchange_left_right(ir_node *irn, ir_node **left, ir_node **right, int new_left, int new_right) { + ir_node *temp; + + set_irn_n(irn, new_right, *right); + set_irn_n(irn, new_left, *left); + + temp = *left; + *left = *right; + *right = temp; + + /* this is only needed for Compares, but currently ALL nodes + * have this attribute :-) */ + set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn))); +} + /** * Optimizes a pattern around irn to address mode if possible. */ @@ -1197,7 +1222,8 @@ void ia32_optimize_am(ir_node *irn, void *env) { ir_node *left, *right, *temp; ir_node *store, *load, *mem_proj; ir_node *succ, *addr_b, *addr_i; - int check_am_src = 0; + int check_am_src = 0; + int need_exchange_on_fail = 0; DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;) if (! is_ia32_irn(irn)) @@ -1295,12 +1321,8 @@ void ia32_optimize_am(ir_node *irn, void *env) { /* operand is a load, so we only need to check right operand. */ if (pred_is_specific_nodeblock(block, left, is_ia32_Ld)) { - set_irn_n(irn, 2, right); - set_irn_n(irn, 3, left); - - temp = left; - left = right; - right = temp; + exchange_left_right(irn, &left, &right, 3, 2); + need_exchange_on_fail = 1; } } @@ -1328,7 +1350,7 @@ void ia32_optimize_am(ir_node *irn, void *env) { if (ia32_get_irn_n_edges(succ) == 1) { succ = get_edge_src_irn(get_irn_out_edge_first(succ)); - if (is_ia32_fStore(succ) || is_ia32_Store(succ)) { + if (is_ia32_xStore(succ) || is_ia32_Store(succ)) { store = succ; addr_b = get_irn_n(store, 0); addr_i = get_irn_n(store, 1); @@ -1354,6 +1376,10 @@ void ia32_optimize_am(ir_node *irn, void *env) { temp = left; left = right; right = temp; + + /* this is only needed for Compares, but currently ALL nodes + * have this attribute :-) */ + set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn))); } } @@ -1417,19 +1443,21 @@ void ia32_optimize_am(ir_node *irn, void *env) { check_am_src = 1; } + /* was exchanged but optimize failed: exchange back */ + if (check_am_src && need_exchange_on_fail) + exchange_left_right(irn, &left, &right, 3, 2); + + need_exchange_on_fail = 0; + /* normalize commutative ops */ - if (node_is_ia32_comm(irn)) { + if (check_am_src && node_is_ia32_comm(irn)) { /* Assure that left operand is always a Load if there is one */ /* because non-commutative ops can only use Source AM if the */ /* left operand is a Load, so we only need to check the left */ /* operand afterwards. */ if (pred_is_specific_nodeblock(block, right, is_ia32_Ld)) { - set_irn_n(irn, 2, right); - set_irn_n(irn, 3, left); - - temp = left; - left = right; - right = temp; + exchange_left_right(irn, &left, &right, 3, 2); + need_exchange_on_fail = 1; } } @@ -1468,14 +1496,23 @@ void ia32_optimize_am(ir_node *irn, void *env) { if (get_irn_arity(irn) == 5) { /* binary AMop */ set_irn_n(irn, 4, get_irn_n(left, 2)); + + /* this is only needed for Compares, but currently ALL nodes + * have this attribute :-) */ + set_ia32_pncode(irn, get_inversed_pnc(get_ia32_pncode(irn))); + + /* disconnect from Load */ + /* (make second op -> first, set second in to noreg) */ + set_irn_n(irn, 2, get_irn_n(irn, 3)); + set_irn_n(irn, 3, noreg_gp); } else { /* unary AMop */ set_irn_n(irn, 3, get_irn_n(left, 2)); - } - /* disconnect from Load */ - set_irn_n(irn, 2, noreg_gp); + /* disconnect from Load */ + set_irn_n(irn, 2, noreg_gp); + } DBG_OPT_AM_S(left, irn); @@ -1488,6 +1525,11 @@ void ia32_optimize_am(ir_node *irn, void *env) { DB((mod, LEVEL_1, "merged with %+F into source AM\n", left)); } + else { + /* was exchanged but optimize failed: exchange back */ + if (need_exchange_on_fail) + exchange_left_right(irn, &left, &right, 3, 2); + } } } }