- fix stack bias wrongly calculated with non-scheduled projs in ia32 mode
authorMatthias Braun <matze@braunis.de>
Thu, 21 Jun 2007 22:14:35 +0000 (22:14 +0000)
committerMatthias Braun <matze@braunis.de>
Thu, 21 Jun 2007 22:14:35 +0000 (22:14 +0000)
- switch all liveness users to use ir_nodesets
- fixed warnings

[r14708]

16 files changed:
ir/be/arm/arm_new_nodes.c
ir/be/beabi.c
ir/be/becopyopt.c
ir/be/beirgmod.c
ir/be/belive.c
ir/be/belive.h
ir/be/beloopana.c
ir/be/belower.c
ir/be/beschedrss.c
ir/be/bespilldaemel.c
ir/be/bespillmorgan.c
ir/be/bestat.c
ir/be/beverify.c
ir/be/ia32/bearch_ia32.c
ir/be/ia32/ia32_spec.pl
ir/be/ia32/ia32_transform.c

index d8fda8c..c0a4764 100644 (file)
@@ -530,12 +530,16 @@ arm_shift_modifier get_arm_shift_modifier(const ir_node *node) {
 }
 
 /* Set the ARM machine node attributes to default values. */
-static void init_arm_attributes(ir_node *node, int flags, const arch_register_req_t ** in_reqs,
-                                                const arch_register_req_t ** out_reqs, const be_execution_unit_t ***execution_units,
+void init_arm_attributes(ir_node *node, int flags,
+                         const arch_register_req_t ** in_reqs,
+                                                const arch_register_req_t ** out_reqs,
+                         const be_execution_unit_t ***execution_units,
                                                 int n_res, unsigned latency) {
        ir_graph       *irg  = get_irn_irg(node);
        struct obstack *obst = get_irg_obstack(irg);
        arm_attr_t     *attr = get_arm_attr(node);
+       (void) execution_units;
+       (void) latency;
 
        attr->in_req           = in_reqs;
        attr->out_req          = out_reqs;
@@ -680,11 +684,15 @@ static int cmp_attr_arm(ir_node *a, ir_node *b) {
 }
 
 static int cmp_attr_arm_CondJmp(ir_node *a, ir_node *b) {
+       (void) a;
+       (void) b;
        /* never identical */
        return 1;
 }
 
 static int cmp_attr_arm_SwitchJmp(ir_node *a, ir_node *b) {
+       (void) a;
+       (void) b;
        /* never identical */
        return 1;
 }
index 818b871..c40b764 100644 (file)
@@ -2233,6 +2233,7 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
        ir_node *irn;
 
        sched_foreach(bl, irn) {
+               int ofs;
 
                /*
                   Check, if the node relates to an entity on the stack frame.
@@ -2246,12 +2247,12 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
                        DBG((env->dbg, LEVEL_2, "%F has offset %d (including bias %d)\n", ent, offset, bias));
                }
 
-               /*
-                  If the node modifies the stack pointer by a constant offset,
-                  record that in the bias.
-                */
-               if(arch_irn_is(arch_env, irn, modify_sp)) {
-                       int ofs = arch_get_sp_bias(arch_env, irn);
+               if(omit_fp) {
+                       /*
+                        * If the node modifies the stack pointer by a constant offset,
+                        * record that in the bias.
+                        */
+                       ofs = arch_get_sp_bias(arch_env, irn);
 
                        if(be_is_IncSP(irn)) {
                                if(ofs == BE_STACK_FRAME_SIZE_EXPAND) {
@@ -2263,8 +2264,7 @@ static int process_stack_bias(be_abi_irg_t *env, ir_node *bl, int bias)
                                }
                        }
 
-                       if(omit_fp)
-                               bias += ofs;
+                       bias += ofs;
                }
        }
 
index f181523..70ebdfc 100644 (file)
@@ -967,15 +967,16 @@ static int appel_get_live_end_nr(appel_clique_walker_t *env, ir_node *bl, ir_nod
        return -1;
 }
 
-static int appel_dump_clique(appel_clique_walker_t *env, pset *live, ir_node *bl, int curr_nr, int start_nr)
+static int appel_dump_clique(appel_clique_walker_t *env, const ir_nodeset_t *live, ir_node *bl, int curr_nr, int start_nr)
 {
        ir_node **live_arr = alloca(env->co->cls->n_regs * sizeof(live_arr[0]));
        ir_node *irn;
        int n_live;
        int j;
+       ir_nodeset_iterator_t iter;
 
        n_live = 0;
-       foreach_pset(live, irn)
+       foreach_ir_nodeset(live, irn, iter)
                live_arr[n_live++] = irn;
 
        /* dump the live after clique */
@@ -1017,7 +1018,8 @@ static void appel_walker(ir_node *bl, void *data)
        appel_block_info_t *bli    = phase_get_or_set_irn_data(&env->ph, bl);
        struct obstack *obst       = &env->obst;
        void *base                 = obstack_base(obst);
-       pset *live                 = pset_new_ptr_default();
+       ir_nodeset_t live;
+       ir_nodeset_iterator_t iter;
        be_lv_t *lv                = env->co->cenv->birg->lv;
 
        int n_insns  = 0;
@@ -1052,7 +1054,8 @@ static void appel_walker(ir_node *bl, void *data)
        }
 
        DBG((dbg, LEVEL_2, "%+F\n", bl));
-       be_liveness_end_of_block(lv, env->co->aenv, env->co->cls, bl, live);
+       ir_nodeset_init(&live);
+       be_liveness_end_of_block(lv, env->co->aenv, env->co->cls, bl, &live);
 
        /* Generate the bad and ugly. */
        for(i = n_insns - 1; i >= 0; --i) {
@@ -1061,7 +1064,7 @@ static void appel_walker(ir_node *bl, void *data)
                /* The first live set has to be saved in the block border set. */
                if(i == n_insns - 1) {
                        j = 0;
-                       foreach_pset(live, irn) {
+                       foreach_ir_nodeset(&live, irn, iter) {
                                bli->live_end[j]    = irn;
                                bli->live_end_nr[j] = curr_nr + j;
                                ++j;
@@ -1074,21 +1077,20 @@ static void appel_walker(ir_node *bl, void *data)
                                ir_node *op   = insn->ops[j].carrier;
                                bitset_t *adm = insn->ops[j].regs;
                                int k;
-                               int nr;
+                               size_t nr;
 
                                if(!insn->ops[j].has_constraints)
                                        continue;
 
                                nr = 0;
-                               foreach_pset(live, irn) {
+                               foreach_ir_nodeset(&live, irn, iter) {
                                        if(irn == op) {
-                                               pset_break(live);
                                                break;
                                        }
                                        ++nr;
                                }
 
-                               assert(nr < pset_count(live));
+                               assert(nr < ir_nodeset_size(&live));
 
                                for(k = 0; k < env->co->cls->n_regs; ++k) {
                                        int mapped_col = env->color_map[k];
@@ -1099,11 +1101,11 @@ static void appel_walker(ir_node *bl, void *data)
                }
 
                /* dump the clique and update the stuff. */
-               curr_nr = appel_dump_clique(env, live, bl, curr_nr, start_nr);
+               curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr);
 
                /* remove all defs. */
                for(j = 0; j < insn->use_start; ++j)
-                       pset_remove_ptr(live, insn->ops[j].carrier);
+                       ir_nodeset_remove(&live, insn->ops[j].carrier);
 
                if(is_Phi(insn->irn) && arch_irn_consider_in_reg_alloc(env->co->aenv, env->co->cls, insn->irn)) {
                        bli->phi[bli->n_phi]    = insn->irn;
@@ -1114,21 +1116,21 @@ static void appel_walker(ir_node *bl, void *data)
                /* add all uses */
                else
                        for(j = insn->use_start; j < insn->n_ops; ++j)
-                               pset_insert_ptr(live, insn->ops[j].carrier);
+                               ir_nodeset_insert(&live, insn->ops[j].carrier);
        }
 
        /* print the start clique. */
-       curr_nr = appel_dump_clique(env, live, bl, curr_nr, start_nr);
+       curr_nr = appel_dump_clique(env, &live, bl, curr_nr, start_nr);
 
        i = 0;
-       foreach_pset(live, irn) {
+       foreach_ir_nodeset(&live, irn, iter) {
                bli->live_in[i]    = irn;
                bli->live_in_nr[i] = PTR_TO_INT(get_irn_link(irn));
                ++i;
        }
        bli->n_live_in = i;
 
-       del_pset(live);
+       ir_nodeset_destroy(&live);
        free(insns);
        obstack_free(obst, base);
        env->curr_nr = curr_nr;
index e859281..b19e689 100644 (file)
@@ -88,30 +88,33 @@ ir_node *insert_Perm_after(be_irg_t *birg,
        be_lv_t *lv     = birg->lv;
        ir_node *bl     = is_Block(pos) ? pos : get_nodes_block(pos);
        ir_graph *irg   = get_irn_irg(bl);
-       pset *live      = pset_new_ptr_default();
+       ir_nodeset_t          live;
+       ir_nodeset_iterator_t iter;
 
        ir_node *curr, *irn, *perm, **nodes;
-       int i, n;
+       size_t i, n;
 
        DBG((dbg, LEVEL_1, "Insert Perm after: %+F\n", pos));
 
-       be_liveness_nodes_live_at(lv, arch_env, cls, pos, live);
-
-       n = pset_count(live);
+       ir_nodeset_init(&live);
+       be_liveness_nodes_live_at(lv, arch_env, cls, pos, &live);
 
+       n = ir_nodeset_size(&live);
        if(n == 0) {
-               del_pset(live);
+               ir_nodeset_destroy(&live);
                return NULL;
        }
 
        nodes = xmalloc(n * sizeof(nodes[0]));
 
        DBG((dbg, LEVEL_1, "live:\n"));
-       for(irn = pset_first(live), i = 0; irn; irn = pset_next(live), i++) {
+       i = 0;
+       foreach_ir_nodeset(&live, irn, iter) {
                DBG((dbg, LEVEL_1, "\t%+F\n", irn));
                nodes[i] = irn;
+               i++;
        }
-       del_pset(live);
+       ir_nodeset_destroy(&live);
 
        perm = be_new_Perm(cls, irg, bl, n, nodes);
        sched_add_after(pos, perm);
index a26ec2f..0becbab 100644 (file)
@@ -759,49 +759,9 @@ int be_check_dominance(ir_graph *irg)
        return !problem_found;
 }
 
-pset *be_liveness_transfer(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *irn, pset *live)
-{
-       int i, n;
-
-       /* You should better break out of your loop when hitting the first phi function. */
-       assert(!is_Phi(irn) && "liveness_transfer produces invalid results for phi nodes");
-
-#ifndef SCHEDULE_PROJS
-       /* kill all Proj's if a node is killed */
-       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 (arch_irn_consider_in_reg_alloc(arch_env, cls, proj)) {
-                               ir_node *del = pset_remove_ptr(live, proj);
-                               (void) del;
-                               assert(proj == del);
-                       }
-               }
-       }
-#endif
-
-       if (arch_irn_consider_in_reg_alloc(arch_env, cls, irn)) {
-               ir_node *del = pset_remove_ptr(live, irn);
-               (void) del;
-               assert(irn == del);
-       }
-
-       for (i = 0, n = get_irn_arity(irn); i < n; ++i) {
-               ir_node *op = get_irn_n(irn, i);
-
-               if (arch_irn_consider_in_reg_alloc(arch_env, cls, op))
-                       pset_insert_ptr(live, op);
-       }
-
-       return live;
-}
-
-void be_liveness_transfer_ir_nodeset(const arch_env_t *arch_env,
-                                     const arch_register_class_t *cls,
-                                     ir_node *node, ir_nodeset_t *nodeset)
+void be_liveness_transfer(const arch_env_t *arch_env,
+                          const arch_register_class_t *cls,
+                          ir_node *node, ir_nodeset_t *nodeset)
 {
        int i, arity;
 
@@ -839,24 +799,9 @@ void be_liveness_transfer_ir_nodeset(const arch_env_t *arch_env,
 
 
 
-pset *be_liveness_end_of_block(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *bl, pset *live)
-{
-       int i;
-       assert(lv->nodes && "live sets must be computed");
-       be_lv_foreach(lv, bl, be_lv_state_end, i) {
-               ir_node *irn = be_lv_get_irn(lv, bl, i);
-               if(arch_irn_consider_in_reg_alloc(arch_env, cls, irn))
-                       pset_insert_ptr(live, irn);
-       }
-
-       return live;
-}
-
-void be_liveness_end_of_block_ir_nodeset(const be_lv_t *lv,
-                                         const arch_env_t *arch_env,
-                                         const arch_register_class_t *cls,
-                                         const ir_node *block,
-                                         ir_nodeset_t *live)
+void be_liveness_end_of_block(const be_lv_t *lv, const arch_env_t *arch_env,
+                              const arch_register_class_t *cls,
+                              const ir_node *block, ir_nodeset_t *live)
 {
        int i;
 
@@ -872,7 +817,9 @@ void be_liveness_end_of_block_ir_nodeset(const be_lv_t *lv,
 
 
 
-pset *be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live)
+void be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env,
+                               const arch_register_class_t *cls,
+                               const ir_node *pos, ir_nodeset_t *live)
 {
        const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
        ir_node *irn;
@@ -884,15 +831,16 @@ pset *be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env, c
                 * exit immediately, so that this node is still live
                 */
                if(irn == pos)
-                       return live;
+                       return;
 
                be_liveness_transfer(arch_env, cls, irn, live);
        }
-
-       return live;
 }
 
-pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live)
+void be_liveness_nodes_live_at_input(const be_lv_t *lv,
+                                     const arch_env_t *arch_env,
+                                     const arch_register_class_t *cls,
+                                     const ir_node *pos, ir_nodeset_t *live)
 {
        const ir_node *bl = is_Block(pos) ? pos : get_nodes_block(pos);
        ir_node *irn;
@@ -902,10 +850,8 @@ pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_
        sched_foreach_reverse(bl, irn) {
                be_liveness_transfer(arch_env, cls, irn, live);
                if(irn == pos)
-                       return live;
+                       return;
        }
-
-       return live;
 }
 
 static void collect_node(ir_node *irn, void *data)
index 4234d1a..dbd71ab 100644 (file)
@@ -152,9 +152,9 @@ int be_check_dominance(ir_graph *irg);
  *                 the nodes live after irn.
  * @return live.
  */
-pset *be_liveness_transfer(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *irn, pset *live);
-
-void be_liveness_transfer_ir_nodeset(const arch_env_t *arch_env, const arch_register_class_t *cls, ir_node *node, ir_nodeset_t *nodeset);
+void be_liveness_transfer(const arch_env_t *arch_env,
+                          const arch_register_class_t *cls, ir_node *node,
+                          ir_nodeset_t *nodeset);
 
 /**
  * Put all node live at the end of a block into a set.
@@ -164,9 +164,9 @@ void be_liveness_transfer_ir_nodeset(const arch_env_t *arch_env, const arch_regi
  * @param live     The set to put them into.
  * @return live.
  */
-pset *be_liveness_end_of_block(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *bl, pset *live);
-
-void be_liveness_end_of_block_ir_nodeset(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *bl, ir_nodeset_t *nodeset);
+void be_liveness_end_of_block(const be_lv_t *lv, const arch_env_t *arch_env,
+                              const arch_register_class_t *cls,
+                              const ir_node *bl, ir_nodeset_t *nodeset);
 
 /**
  * Compute a set of nodes which are live at another node.
@@ -176,9 +176,10 @@ void be_liveness_end_of_block_ir_nodeset(const be_lv_t *lv, const arch_env_t *ar
  * @param cls      The register class to consider.
  * @param pos      The node.
  * @param live     The set to put them into.
- * @return live.
  */
-pset *be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live);
+void be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env,
+                               const arch_register_class_t *cls,
+                               const ir_node *pos, ir_nodeset_t *live);
 
 /**
  * Compute a set of nodes which are live at another node.
@@ -188,9 +189,11 @@ pset *be_liveness_nodes_live_at(const be_lv_t *lv, const arch_env_t *arch_env, c
  * @param cls      The register class to consider.
  * @param pos      The node.
  * @param live     The set to put them into.
- * @return live.
  */
-pset *be_liveness_nodes_live_at_input(const be_lv_t *lv, const arch_env_t *arch_env, const arch_register_class_t *cls, const ir_node *pos, pset *live);
+void be_liveness_nodes_live_at_input(const be_lv_t *lv,
+                                     const arch_env_t *arch_env,
+                                     const arch_register_class_t *cls,
+                                     const ir_node *pos, ir_nodeset_t *live);
 
 /**
  * Make sure the live sets are computed.
index 69c73a8..65541ae 100644 (file)
@@ -76,15 +76,16 @@ static unsigned be_compute_block_pressure(be_loopana_t *loop_ana, ir_node *block
        const be_irg_t   *birg       = loop_ana->birg;
        const arch_env_t *aenv       = be_get_birg_arch_env(birg);
        be_lv_t          *lv         = be_get_birg_liveness(birg);
-       pset             *live_nodes = pset_new_ptr_default();
+       ir_nodeset_t      live_nodes;
        ir_node          *irn;
        int              max_live;
 
        DBG((dbg, LEVEL_1, "Processing Block %+F\n", block));
 
        /* determine largest pressure with this block */
-       live_nodes = be_liveness_end_of_block(lv, aenv, cls, block, live_nodes);
-       max_live   = pset_count(live_nodes);
+       ir_nodeset_init(&live_nodes);
+       be_liveness_end_of_block(lv, aenv, cls, block, &live_nodes);
+       max_live   = ir_nodeset_size(&live_nodes);
 
        sched_foreach_reverse(block, irn) {
                int cnt;
@@ -92,14 +93,14 @@ static unsigned be_compute_block_pressure(be_loopana_t *loop_ana, ir_node *block
                if (is_Phi(irn))
                        break;
 
-               live_nodes = be_liveness_transfer(aenv, cls, irn, live_nodes);
-               cnt        = pset_count(live_nodes);
+               be_liveness_transfer(aenv, cls, irn, &live_nodes);
+               cnt        = ir_nodeset_size(&live_nodes);
                max_live   = MAX(cnt, max_live);
        }
 
        DBG((dbg, LEVEL_1, "Finished with Block %+F (%s %u)\n", block, cls->name, max_live));
 
-       del_pset(live_nodes);
+       ir_nodeset_destroy(&live_nodes);
        return max_live;
 }
 
index b6112eb..b8e9cdd 100644 (file)
@@ -1034,7 +1034,7 @@ found_front:
 static void lower_nodes_after_ra_walker(ir_node *irn, void *walk_env) {
        if (! is_Block(irn) && ! is_Proj(irn)) {
                if (be_is_Perm(irn)) {
-                       int perm_stayed = 1; //push_through_perm(irn, walk_env);
+                       int perm_stayed = push_through_perm(irn, walk_env);
                        if (perm_stayed)
                                lower_perm_node(irn, walk_env);
                }
index edfa554..633e897 100644 (file)
@@ -157,7 +157,7 @@ typedef struct _rss {
        unsigned         max_height;      /**< maximum height in the current block */
        rss_opts_t       *opts;           /**< The options */
        be_lv_t          *liveness;       /**< The liveness information for this irg */
-       pset             *live_block;     /**< Values alive at end of block */
+       ir_nodeset_t      live_block;     /**< Values alive at end of block */
        const arch_register_class_t *cls; /**< The current register class */
        DEBUG_ONLY(firm_dbg_module_t *dbg);
 } rss_t;
@@ -2068,8 +2068,8 @@ static void process_block(ir_node *block, void *env) {
                DBG((rss->dbg, LEVEL_1, "register class %s\n", arch_register_class_name(cls)));
 
                /* Get all live value at end of Block having current register class */
-               rss->live_block = pset_new_ptr(10);
-               be_liveness_end_of_block(rss->liveness, rss->arch_env, rss->cls, rss->block, rss->live_block);
+               ir_nodeset_init(&rss->live_block);
+               be_liveness_end_of_block(rss->liveness, rss->arch_env, rss->cls, rss->block, &rss->live_block);
 
                /* reset the list of interesting nodes */
                plist_clear(rss->nodes);
@@ -2126,7 +2126,7 @@ static void process_block(ir_node *block, void *env) {
                */
                perform_value_serialization_heuristic(rss);
 
-               del_pset(rss->live_block);
+               ir_nodeset_destroy(&rss->live_block);
        }
 
        phase_free(&rss->ph);
index 09dbee2..956ed8d 100644 (file)
@@ -309,7 +309,7 @@ void spill_block(ir_node *block, void *data)
        DBG((dbg, LEVEL_1, "spilling block %+F\n", block));
 
        ir_nodeset_init(&live_nodes);
-       be_liveness_end_of_block_ir_nodeset(lv, arch_env, cls, block, &live_nodes);
+       be_liveness_end_of_block(lv, arch_env, cls, block, &live_nodes);
 
        foreach_ir_nodeset(&live_nodes, node, iter) {
                DBG((dbg, LEVEL_2, "\t%+F is live-end... ", node));
index 3c8ce5f..d43b91d 100644 (file)
@@ -466,11 +466,13 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, const ir_node* b
        ir_node *node;
        int max_pressure;
        int loop_unused_spills_needed;
-       pset *live_nodes = pset_new_ptr_default();
+       ir_nodeset_t live_nodes;
        const be_lv_t *lv = env->lv;
 
-       be_liveness_end_of_block(lv, env->arch, env->cls, block, live_nodes);
-       max_pressure = pset_count(live_nodes);
+       ir_nodeset_init(&live_nodes);
+
+       be_liveness_end_of_block(lv, env->arch, env->cls, block, &live_nodes);
+       max_pressure = ir_nodeset_size(&live_nodes);
 
        DBG((dbg, DBG_LIVE, "Reduce pressure to %d In Block %+F:\n", env->registers_available, block));
 
@@ -483,12 +485,12 @@ static int reduce_register_pressure_in_block(morgan_env_t *env, const ir_node* b
                if(is_Phi(node))
                        break;
 
-               be_liveness_transfer(env->arch, env->cls, node, live_nodes);
-               pressure = pset_count(live_nodes);
+               be_liveness_transfer(env->arch, env->cls, node, &live_nodes);
+               pressure = ir_nodeset_size(&live_nodes);
                if(pressure > max_pressure)
                        max_pressure = pressure;
        }
-       del_pset(live_nodes);
+       ir_nodeset_destroy(&live_nodes);
 
        loop_unused_spills_needed = max_pressure - env->registers_available;
 
index ad6e65d..7fe6404 100644 (file)
@@ -130,12 +130,13 @@ static void stat_reg_pressure_block(ir_node *block, void *data) {
 
        for (i = 0; i < n; i++) {
                const arch_register_class_t *cls = arch_isa_get_reg_class(aenv->isa, i);
-               ir_node  *irn;
-               pset     *live_nodes = pset_new_ptr(64);
-               int       max_live;
+               ir_node      *irn;
+               ir_nodeset_t  live_nodes;
+               int           max_live;
 
-               live_nodes = be_liveness_end_of_block(env->lv, aenv, cls, block, live_nodes);
-               max_live   = pset_count(live_nodes);
+               ir_nodeset_init(&live_nodes);
+               be_liveness_end_of_block(env->lv, aenv, cls, block, &live_nodes);
+               max_live = ir_nodeset_size(&live_nodes);
 
                sched_foreach_reverse(block, irn) {
                        int cnt;
@@ -143,12 +144,13 @@ static void stat_reg_pressure_block(ir_node *block, void *data) {
                        if(is_Phi(irn))
                                break;
 
-                       live_nodes = be_liveness_transfer(aenv, cls, irn, live_nodes);
-                       cnt        = pset_count(live_nodes);
+                       be_liveness_transfer(aenv, cls, irn, &live_nodes);
+                       cnt        = ir_nodeset_size(&live_nodes);
                        max_live   = cnt < max_live ? max_live : cnt;
                }
 
                stat_be_block_regpressure(irg, block, max_live, cls->name);
+               ir_nodeset_destroy(&live_nodes);
        }
 }
 
index bc281ae..7939d2d 100644 (file)
@@ -62,11 +62,12 @@ typedef struct be_verify_register_pressure_env_t_ {
 /**
  * Print all nodes of a pset into a file.
  */
-static void print_living_values(FILE *F, pset *live_nodes) {
+static void print_living_values(FILE *F, const ir_nodeset_t *live_nodes) {
+       ir_nodeset_iterator_t iter;
        ir_node *node;
 
        ir_fprintf(F, "\t");
-       foreach_pset(live_nodes, node) {
+       foreach_ir_nodeset(live_nodes, node, iter) {
                ir_fprintf(F, "%+F ", node);
        }
        ir_fprintf(F, "\n");
@@ -77,18 +78,20 @@ static void print_living_values(FILE *F, pset *live_nodes) {
  */
 static void verify_liveness_walker(ir_node *block, void *data) {
        be_verify_register_pressure_env_t *env = (be_verify_register_pressure_env_t *)data;
-       pset    *live_nodes = pset_new_ptr_default();
+       ir_nodeset_t live_nodes;
        ir_node *irn;
        int pressure;
 
        /* collect register pressure info, start with end of a block */
-       be_liveness_end_of_block(env->lv, env->arch_env, env->cls, block, live_nodes);
+       ir_nodeset_init(&live_nodes);
+       be_liveness_end_of_block(env->lv, env->arch_env, env->cls, block,
+                                &live_nodes);
 
-       pressure = pset_count(live_nodes);
+       pressure = ir_nodeset_size(&live_nodes);
        if(pressure > env->registers_available) {
                ir_fprintf(stderr, "Verify Warning: Register pressure too high at end of block %+F(%s) (%d/%d):\n",
                        block, get_irg_dump_name(env->irg), pressure, env->registers_available);
-               print_living_values(stderr, live_nodes);
+               print_living_values(stderr, &live_nodes);
                env->problem_found = 1;
        }
 
@@ -96,18 +99,18 @@ static void verify_liveness_walker(ir_node *block, void *data) {
                if (is_Phi(irn))
                        break;
 
-               be_liveness_transfer(env->arch_env, env->cls, irn, live_nodes);
+               be_liveness_transfer(env->arch_env, env->cls, irn, &live_nodes);
 
-               pressure = pset_count(live_nodes);
+               pressure = ir_nodeset_size(&live_nodes);
 
                if(pressure > env->registers_available) {
                        ir_fprintf(stderr, "Verify Warning: Register pressure too high before node %+F in %+F(%s) (%d/%d):\n",
                                irn, block, get_irg_dump_name(env->irg), pressure, env->registers_available);
-                       print_living_values(stderr, live_nodes);
+                       print_living_values(stderr, &live_nodes);
                        env->problem_found = 1;
                }
        }
-       del_pset(live_nodes);
+       ir_nodeset_destroy(&live_nodes);
 }
 
 /**
@@ -731,7 +734,9 @@ typedef struct _be_verify_register_allocation_env_t {
        int problem_found;
 } be_verify_register_allocation_env_t;
 
-static void check_register_constraints(ir_node *node, be_verify_register_allocation_env_t *env) {
+static void check_register_constraints(ir_node *node,
+                                       be_verify_register_allocation_env_t *env)
+{
        const arch_env_t      *arch_env = env->arch_env;
        const arch_register_t *reg;
        int                   i, arity;
@@ -785,14 +790,17 @@ static void check_register_constraints(ir_node *node, be_verify_register_allocat
 }
 
 static void check_register_allocation(be_verify_register_allocation_env_t *env,
-                                      const arch_register_class_t *regclass, pset *nodes) {
+                                      const arch_register_class_t *regclass,
+                                      ir_nodeset_t *nodes)
+{
        const arch_env_t      *arch_env  = env->arch_env;
        const arch_register_t *reg       = NULL;
        int                   fail       = 0;
        bitset_t              *registers = bitset_alloca(arch_register_class_n_regs(regclass));
        ir_node               *node;
+       ir_nodeset_iterator_t  iter;
 
-       foreach_pset(nodes, node) {
+       foreach_ir_nodeset(nodes, node, iter) {
                if (arch_get_irn_reg_class(arch_env, node, -1) != regclass)
                        continue;
 
@@ -803,7 +811,6 @@ static void check_register_allocation(be_verify_register_allocation_env_t *env,
                        continue;
 
                if (bitset_is_set(registers, reg->index)) {
-                       pset_break(nodes);
                        fail = 1;
                        break;
                }
@@ -815,7 +822,7 @@ static void check_register_allocation(be_verify_register_allocation_env_t *env,
                               reg->name, get_nodes_block(node), get_irg_dump_name(env->irg));
                env->problem_found = 1;
 
-               foreach_pset(nodes, node) {
+               foreach_ir_nodeset(nodes, node, iter) {
                        if (arch_get_irn_register(arch_env, node) == reg) {
                                ir_fprintf(stderr, "  at node %+F\n", node);
                        }
@@ -833,21 +840,24 @@ static void verify_block_register_allocation(ir_node *block, void *data) {
        for (i = 0; i < nregclasses; ++i) {
                const arch_register_class_t *regclass = arch_isa_get_reg_class(isa, i);
                ir_node *node;
-               pset *live_nodes = pset_new_ptr_default();
+               ir_nodeset_t live_nodes;
+
+               ir_nodeset_init(&live_nodes);
 
-               be_liveness_end_of_block(env->lv, env->arch_env, regclass, block, live_nodes);
-               check_register_allocation(env, regclass, live_nodes);
+               be_liveness_end_of_block(env->lv, env->arch_env, regclass, block,
+                                        &live_nodes);
+               check_register_allocation(env, regclass, &live_nodes);
 
                sched_foreach_reverse(block, node) {
                        if (is_Phi(node))
                                break;
 
-                       be_liveness_transfer(env->arch_env, regclass, node, live_nodes);
-                       check_register_allocation(env, regclass, live_nodes);
+                       be_liveness_transfer(env->arch_env, regclass, node, &live_nodes);
+                       check_register_allocation(env, regclass, &live_nodes);
                        check_register_constraints(node, env);
                }
 
-               del_pset(live_nodes);
+               ir_nodeset_destroy(&live_nodes);
        }
 }
 
index 195c12d..24c18e0 100644 (file)
@@ -370,17 +370,15 @@ static void ia32_set_frame_offset(const void *self, ir_node *irn, int bias) {
        }
 }
 
-static int ia32_get_sp_bias(const void *self, const ir_node *irn) {
+static int ia32_get_sp_bias(const void *self, const ir_node *node)
+{
        (void) self;
-       if(is_Proj(irn)) {
-               long proj = get_Proj_proj(irn);
-               ir_node *pred = get_Proj_pred(irn);
 
-               if (is_ia32_Push(pred) && proj == pn_ia32_Push_stack)
-                       return 4;
-               if (is_ia32_Pop(pred) && proj == pn_ia32_Pop_stack)
-                       return -4;
-       }
+       if (is_ia32_Push(node))
+               return 4;
+
+       if (is_ia32_Pop(node))
+               return -4;
 
        return 0;
 }
@@ -618,10 +616,17 @@ static int ia32_get_op_estimated_cost(const void *self, const ir_node *irn)
        /* in case of address mode operations add additional cycles */
        else if (op_tp == ia32_AddrModeD || op_tp == ia32_AddrModeS) {
                /*
-                       In case of stack access add 5 cycles (we assume stack is in cache),
-                       other memory operations cost 20 cycles.
+                       In case of stack access and access to fixed addresses add 5 cycles
+                       (we assume they are in cache), other memory operations cost 20
+                       cycles.
                */
-               cost += is_ia32_use_frame(irn) ? 5 : 20;
+               if(is_ia32_use_frame(irn) ||
+                               (is_ia32_NoReg_GP(get_irn_n(irn, 0)) &&
+                        is_ia32_NoReg_GP(get_irn_n(irn, 1)))) {
+                       cost += 5;
+               } else {
+                       cost += 20;
+               }
        }
 
        return cost;
@@ -1084,7 +1089,7 @@ static ir_node *create_pop(ia32_code_gen_t *cg, ir_node *node, ir_node *schedpoi
        return pop;
 }
 
-static ir_node* create_spproj(ia32_code_gen_t *cg, ir_node *node, ir_node *pred, int pos, ir_node *schedpoint) {
+static ir_node* create_spproj(ia32_code_gen_t *cg, ir_node *node, ir_node *pred, int pos) {
        ir_graph *irg = get_irn_irg(node);
        dbg_info *dbg = get_irn_dbg_info(node);
        ir_node *block = get_nodes_block(node);
@@ -1094,9 +1099,6 @@ static ir_node* create_spproj(ia32_code_gen_t *cg, ir_node *node, ir_node *pred,
 
        sp = new_rd_Proj(dbg, irg, block, pred, spmode, pos);
        arch_set_irn_register(cg->arch_env, sp, spreg);
-#ifdef SCHEDULE_PROJS
-       sched_add_before(schedpoint, sp);
-#endif
 
        return sp;
 }
@@ -1136,12 +1138,12 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) {
                assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
 
                push = create_push(cg, node, node, sp, mem, inent);
-               sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
+               sp = create_spproj(cg, node, push, pn_ia32_Push_stack);
                if(entbits == 64) {
                        // add another push after the first one
                        push = create_push(cg, node, node, sp, mem, inent);
                        add_ia32_am_offs_int(push, 4);
-                       sp = create_spproj(cg, node, push, pn_ia32_Push_stack, node);
+                       sp = create_spproj(cg, node, push, pn_ia32_Push_stack);
                }
 
                set_irn_n(node, i, new_Bad());
@@ -1162,13 +1164,13 @@ static void transform_MemPerm(ia32_code_gen_t *cg, ir_node *node) {
                assert( (entbits == 32 || entbits == 64) && "spillslot on x86 should be 32 or 64 bit");
 
                pop = create_pop(cg, node, node, sp, outent);
-               sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
+               sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack);
                if(entbits == 64) {
                        add_ia32_am_offs_int(pop, 4);
 
                        // add another pop after the first one
                        pop = create_pop(cg, node, node, sp, outent);
-                       sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack, node);
+                       sp = create_spproj(cg, node, pop, pn_ia32_Pop_stack);
                }
 
                pops[i] = pop;
index 694252c..e454642 100644 (file)
@@ -920,12 +920,15 @@ Cltd => {
 },
 
 # Load / Store
+#
+# Note that we add additional latency values depending on address mode, so a
+# lateny of 0 for load is correct
 
 Load => {
        op_flags  => "L|F",
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "none" ], out => [ "gp", "none" ] },
-       latency   => 3,
+       latency   => 0,
        emit      => ". mov%SE%ME%.l %AM, %D0",
        outs      => [ "res", "M" ],
        units     => [ "GP" ],
@@ -951,7 +954,7 @@ Store => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "gp", "none" ], out => [ "none" ] },
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
@@ -961,7 +964,7 @@ Store8Bit => {
        state     => "exc_pinned",
        reg_req   => { in => [ "gp", "gp", "eax ebx ecx edx", "none" ], out => ["none" ] },
        emit      => '. mov%M %binop',
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        mode      => "mode_M",
 },
@@ -981,7 +984,7 @@ Push => {
        emit      => '. push%M %unop2',
        ins       => [ "base", "index", "val", "stack", "mem" ],
        outs      => [ "stack:I|S", "M" ],
-       latency   => 3,
+       latency   => 2,
        units     => [ "GP" ],
        modified_flags => [],
 },
@@ -991,7 +994,7 @@ Pop => {
        emit      => '. pop%M %DAM1',
        outs      => [ "stack:I|S", "res", "M" ],
        ins       => [ "base", "index", "stack", "mem" ],
-       latency   => 4,
+       latency   => 3, # Pop is more expensive than Push on Athlon
        units     => [ "GP" ],
        modified_flags => [],
 },
index a357551..a1604cd 100644 (file)
@@ -288,7 +288,8 @@ static ir_node *gen_Const(ir_node *node) {
                                set_ia32_op_type(load, ia32_AddrModeS);
                                set_ia32_am_flavour(load, ia32_am_N);
                                set_ia32_am_sc(load, floatent);
-                               res      = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
+                               set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
+                               res = new_r_Proj(irg, block, load, mode_vfp, pn_ia32_vfld_res);
                        }
                        set_ia32_ls_mode(load, mode);
                } else {
@@ -300,6 +301,7 @@ static ir_node *gen_Const(ir_node *node) {
                        set_ia32_am_flavour(load, ia32_am_N);
                        set_ia32_am_sc(load, floatent);
                        set_ia32_ls_mode(load, mode);
+                       set_ia32_flags(load, get_ia32_flags(load) | arch_irn_flags_rematerializable);
 
                        res = new_r_Proj(irg, block, load, mode_xmm, pn_ia32_xLoad_res);
                }
@@ -2364,13 +2366,8 @@ static ir_node *gen_Conv(ir_node *node) {
 }
 
 static
-int check_immediate_constraint(tarval *tv, char immediate_constraint_type)
+int check_immediate_constraint(long val, char immediate_constraint_type)
 {
-       long val;
-
-       assert(tarval_is_long(tv));
-       val = get_tarval_long(tv);
-
        switch (immediate_constraint_type) {
        case 0:
                return 1;
@@ -2463,14 +2460,20 @@ ir_node *try_create_Immediate(ir_node *node, char immediate_constraint_type)
        }
 
        if(cnst != NULL) {
+               long val;
+
                offset = get_Const_tarval(cnst);
-               if(!tarval_is_long(offset)) {
+               if(tarval_is_long(offset)) {
+                       val = get_tarval_long(offset);
+               } else if(tarval_is_null(offset)) {
+                       val = 0;
+               } else {
                        ir_fprintf(stderr, "Optimisation Warning: tarval from %+F is not a "
                                   "long?\n", cnst);
                        return NULL;
                }
 
-               if(!check_immediate_constraint(offset, immediate_constraint_type))
+               if(!check_immediate_constraint(val, immediate_constraint_type))
                        return NULL;
        }
        if(symconst != NULL) {
@@ -2982,6 +2985,7 @@ static ir_node *gen_be_FrameLoad(ir_node *node) {
        set_ia32_op_type(new_op, ia32_AddrModeS);
        set_ia32_am_flavour(new_op, ia32_am_B);
        set_ia32_ls_mode(new_op, mode);
+       set_ia32_flags(new_op, get_ia32_flags(new_op) | arch_irn_flags_rematerializable);
 
        SET_IA32_ORIG_NODE(new_op, ia32_get_old_node_name(env_cg, node));