added include for harness.c
[libfirm] / ir / be / ia32 / ia32_optimize.c
index df7a64b..6d7c40f 100644 (file)
@@ -217,7 +217,7 @@ void ia32_place_consts_set_modes(ir_node *irn, void *env) {
        tenv.block    = get_nodes_block(irn);
        tenv.cg       = cg;
        tenv.irg      = cg->irg;
-       tenv.mod      = cg->mod;
+       DEBUG_ONLY(tenv.mod      = cg->mod;)
 
        /* Loop over all predecessors and check for Sym/Const nodes */
        for (i = get_irn_arity(irn) - 1; i >= 0; --i) {
@@ -398,17 +398,59 @@ static void ia32_optimize_CondJmp(ir_node *irn, ia32_code_gen_t *cg) {
 }
 
 /**
- * Performs Peephole Optimizations
+ * Tries to optimize two following IncSP.
  */
-void ia32_peephole_optimization(ir_node *irn, void *env) {
-       if (is_ia32_TestJmp(irn)) {
-               ia32_optimize_TestJmp(irn, env);
+static void ia32_optimize_IncSP(ir_node *irn, ia32_code_gen_t *cg) {
+       ir_node *prev = be_get_IncSP_pred(irn);
+       int real_uses = get_irn_n_edges(prev);
+
+       if (real_uses != 1) {
+               /*
+                  This is a hack that should be removed if be_abi_fix_stack_nodes()
+                  is fixed. Currently it leaves some IncSP's outside the chain ...
+                  The previous IncSp is NOT our prev, but directly scheduled before ...
+                        Impossible in a bug-free implementation :-)
+                */
+               prev = sched_prev(irn);
+               real_uses = 1;
        }
-       else if (is_ia32_CondJmp(irn)) {
-               ia32_optimize_CondJmp(irn, env);
+
+       if (be_is_IncSP(prev) && real_uses == 1) {
+               /* first IncSP has only one IncSP user, kill the first one */
+               unsigned       prev_offs = be_get_IncSP_offset(prev);
+               be_stack_dir_t prev_dir  = be_get_IncSP_direction(prev);
+               unsigned       curr_offs = be_get_IncSP_offset(irn);
+               be_stack_dir_t curr_dir  = be_get_IncSP_direction(irn);
+
+               int new_ofs = prev_offs * (prev_dir == be_stack_dir_expand ? -1 : +1) +
+                                   curr_offs * (curr_dir == be_stack_dir_expand ? -1 : +1);
+
+               if (new_ofs < 0) {
+                       new_ofs  = -new_ofs;
+                       curr_dir = be_stack_dir_expand;
+               }
+               else
+                       curr_dir = be_stack_dir_shrink;
+               be_set_IncSP_offset(prev, 0);
+               be_set_IncSP_offset(irn, (unsigned)new_ofs);
+               be_set_IncSP_direction(irn, curr_dir);
        }
 }
 
+/**
+ * Performs Peephole Optimizations.
+ */
+void ia32_peephole_optimization(ir_node *irn, void *env) {
+       ia32_code_gen_t *cg = env;
+
+       if (is_ia32_TestJmp(irn))
+               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);
+}
+
 
 
 /******************************************************************
@@ -596,7 +638,7 @@ static int load_store_addr_is_equal(const ir_node *load, const ir_node *store,
 /**
  * Folds Add or Sub to LEA if possible
  */
-static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, firm_dbg_module_t *mod, ir_node *noreg) {
+static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, ir_node *noreg) {
        ir_graph   *irg        = get_irn_irg(irn);
        dbg_info   *dbg        = get_irn_dbg_info(irn);
        ir_node    *block      = get_nodes_block(irn);
@@ -613,6 +655,7 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, firm_dbg_module_t *
        ir_node    *left, *right, *temp;
        ir_node    *base, *index;
        ia32_am_flavour_t am_flav;
+       DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;)
 
        if (is_ia32_Add(irn))
                isadd = 1;
@@ -849,7 +892,6 @@ static ir_node *fold_addr(ia32_code_gen_t *cg, ir_node *irn, firm_dbg_module_t *
  */
 void ia32_optimize_am(ir_node *irn, void *env) {
        ia32_code_gen_t   *cg   = env;
-       firm_dbg_module_t *mod  = cg->mod;
        ir_node           *res  = irn;
        dbg_info          *dbg;
        ir_mode           *mode;
@@ -858,6 +900,7 @@ void ia32_optimize_am(ir_node *irn, void *env) {
        ir_node           *store, *load, *mem_proj;
        ir_node           *succ, *addr_b, *addr_i;
        int                check_am_src = 0;
+       DEBUG_ONLY(firm_dbg_module_t *mod = cg->mod;)
 
        if (! is_ia32_irn(irn))
                return;
@@ -889,7 +932,7 @@ void ia32_optimize_am(ir_node *irn, void *env) {
                /* check is irn is a candidate for address calculation */
                if (is_candidate(block, irn, 1)) {
                        DBG((mod, LEVEL_1, "\tfound address calculation candidate %+F ... ", irn));
-                       res = fold_addr(cg, irn, mod, noreg_gp);
+                       res = fold_addr(cg, irn, noreg_gp);
 
                        if (res == irn)
                                DB((mod, LEVEL_1, "transformed into %+F\n", res));