X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fia32%2Fia32_optimize.c;h=769bebb6331a3f1f921aa5ab976222212f0aeee7;hb=1161999117f5c0f56b3af2dc9bb7150e03761905;hp=1f99048434b1177847e9c03ccb2957dde6b074bc;hpb=d98d4ab0a6cf8e162331f4f908b17ecd874e941d;p=libfirm diff --git a/ir/be/ia32/ia32_optimize.c b/ir/be/ia32/ia32_optimize.c index 1f9904843..769bebb63 100644 --- a/ir/be/ia32/ia32_optimize.c +++ b/ir/be/ia32/ia32_optimize.c @@ -92,7 +92,9 @@ static ir_node *gen_SymConst(ia32_transform_env_t *env) { } else cnst = new_rd_ia32_Const(dbg, irg, block, get_irg_no_mem(irg), mode); + set_ia32_Const_attr(cnst, env->irn); + return cnst; } @@ -371,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; } @@ -397,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)); } @@ -440,6 +442,10 @@ static void ia32_create_Push(ir_node *irn, ia32_code_gen_t *cg) { 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)); @@ -510,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. */ @@ -554,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); } @@ -1184,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. */ @@ -1196,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)) @@ -1294,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; } } @@ -1353,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))); } } @@ -1416,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; } } @@ -1467,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); @@ -1487,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); + } } } }