X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeschedrss.c;h=f8d54ed3a136761e37ea13c273253256c5d0a049;hb=80a6158fdd766f42ee6c508a773bc114ff1b61f3;hp=205cdc57115a596f315ae5dcd57306704228a3ef;hpb=90e4186c66fbee4ce0cd2c29d184ee8b9430ec91;p=libfirm diff --git a/ir/be/beschedrss.c b/ir/be/beschedrss.c index 205cdc571..f8d54ed3a 100644 --- a/ir/be/beschedrss.c +++ b/ir/be/beschedrss.c @@ -34,6 +34,7 @@ #include "height.h" #include "beabi.h" +#include "bemodule.h" #include "benode_t.h" #include "besched_t.h" @@ -94,31 +95,18 @@ typedef struct _rss_irn { ir_node **consumer; /**< Sorted consumer array (needed for faster access) */ plist_t *parent_list; /**< List of parents */ - ir_node **parents; /**< Sorted parent array (needed for faster access) */ + plist_t *pkiller_list; /**< List of potential killers */ plist_t *descendant_list; /**< List of descendants */ ir_node **descendants; /**< Sorted descendant array (needed for faster access) */ - plist_t *pkiller_list; /**< List of potential killers */ - ir_node **pkillers; /**< Sorted pkiller array (needed for faster access) */ - -#if 0 - plist_t *dvg_desc_list; /**< List of all descendants in the DVG */ - ir_node **dvg_desc; /**< Sorted dvg descendant array (needed for faster access) */ - - plist_t *dvg_pkiller_list; /**< List of potential killers in the DVG */ - ir_node **dvg_pkiller; /**< Sorted dvg pkiller array (needed for faster access) */ - - plist_t *dvg_user_list; /**< List of users in the disjoint value DAG DVG */ -#endif - plist_t *kill_value_list; /**< List of values getting potentially killed by this node */ - ir_node *killer; /**< The selected unique killer */ ir_node *irn; /**< The corresponding firm node to this rss_irn */ chain_t *chain; /**< The chain, this node is associated to */ unsigned desc_walk; /**< visited flag for collecting descendants */ + unsigned kill_count; /**< number of nodes killed by this one */ unsigned live_out : 1; /**< irn has consumers outside of it's block */ unsigned visited : 1; /**< visited flag for bipartite decomposition */ @@ -149,6 +137,8 @@ typedef struct _rss { int *idx_map; /**< Mapping irn indices to per block indices */ 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 */ const arch_register_class_t *cls; /**< The current register class */ DEBUG_ONLY(firm_dbg_module_t *dbg); } rss_t; @@ -203,7 +193,7 @@ static lc_opt_enum_int_var_t dump_var = { }; static const lc_opt_table_entry_t rss_option_table[] = { - LC_OPT_ENT_ENUM_MASK("dump", "dump phases (none, cbc, pkg, kill, dvg, maxac, all)", &dump_var), + LC_OPT_ENT_ENUM_MASK("dump", "dump phases", &dump_var), { NULL } }; #endif /* WITH_LIBCORE */ @@ -308,12 +298,14 @@ static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack * *****************************************************/ +#ifdef DEBUG_libfirm static void dump_nodeset(nodeset *ns, const char *prefix) { ir_node *irn; foreach_nodeset(ns, irn) { ir_fprintf(stderr, "%s%+F\n", prefix, irn); } } +#endif static void build_file_name(rss_t *rss, const char *suffix, size_t suf_len, char *buf, size_t len) { const char *irg_name; @@ -376,11 +368,13 @@ static void debug_vcg_dump_kill(rss_t *rss) { fprintf(f, "layoutalgorithm: mindepth\n"); fprintf(f, "manhattan_edges: yes\n\n"); - /* first: reset dumped flag of all nodes */ - foreach_plist(rss->nodes, el) { - ir_node *irn = plist_element_get_value(el); - rss_irn_t *rirn = get_rss_irn(rss, irn); - rirn->dumped = 0; + { + /* reset dump_flag */ + ir_node *irn; + foreach_phase_irn(&rss->ph, irn) { + rss_irn_t *node = get_rss_irn(rss, irn); + node->dumped = 0; + } } /* dump all nodes and their killers */ @@ -431,6 +425,15 @@ static void debug_vcg_dump_pkg(rss_t *rss, nodeset *max_ac, int iteration) { fprintf(f, "layoutalgorithm: mindepth\n"); fprintf(f, "manhattan_edges: yes\n\n"); + { + /* reset dump_flag */ + ir_node *irn; + foreach_phase_irn(&rss->ph, irn) { + rss_irn_t *node = get_rss_irn(rss, irn); + node->dumped = 0; + } + } + foreach_plist(rss->nodes, el) { ir_node *irn = plist_element_get_value(el); rss_irn_t *rirn = get_rss_irn(rss, irn); @@ -441,11 +444,13 @@ static void debug_vcg_dump_pkg(rss_t *rss, nodeset *max_ac, int iteration) { if (max_ac && nodeset_find(max_ac, irn)) c1 = "color:yellow"; - if (rirn->chain) - ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F c%d\" %s }\n", get_irn_node_nr(irn), irn, rirn->chain->nr, c1); - else - ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" %s }\n", get_irn_node_nr(irn), irn, c1); - rirn->dumped = 1; + if (! rirn->dumped) { + if (rirn->chain) + ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F c%d\" %s }\n", get_irn_node_nr(irn), irn, rirn->chain->nr, c1); + else + ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" %s }\n", get_irn_node_nr(irn), irn, c1); + rirn->dumped = 1; + } foreach_plist(rirn->pkiller_list, k_el) { ir_node *pkiller = plist_element_get_value(k_el); @@ -493,9 +498,6 @@ static void debug_vcg_dump_dvg(rss_t *rss, dvg_t *dvg) { /* dump all edges */ foreach_pset(dvg->edges, edge) { - rss_irn_t *src = get_rss_irn(rss, edge->src); - rss_irn_t *tgt = get_rss_irn(rss, edge->tgt); - ir_fprintf(f, "edge: { sourcename: \"n%d\" targetname: \"n%d\" }\n", get_irn_node_nr(edge->src), get_irn_node_nr(edge->tgt)); } @@ -547,35 +549,27 @@ static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg) { static void *init_rss_irn(phase_t *ph, ir_node *irn, void *old) { rss_irn_t *res = old ? old : phase_alloc(ph, sizeof(res[0])); - res->descendant_list = plist_obstack_new(phase_obst(ph)); - res->descendants = NULL; - - res->consumer_list = plist_obstack_new(phase_obst(ph)); - res->consumer = NULL; + res->descendant_list = plist_obstack_new(phase_obst(ph)); + res->descendants = NULL; - res->pkiller_list = plist_obstack_new(phase_obst(ph)); - res->pkillers = NULL; + res->consumer_list = plist_obstack_new(phase_obst(ph)); + res->consumer = NULL; - res->parent_list = plist_obstack_new(phase_obst(ph)); - res->parents = NULL; + res->pkiller_list = plist_obstack_new(phase_obst(ph)); - //res->dvg_desc_list = plist_obstack_new(phase_obst(ph)); - //res->dvg_desc = NULL; + res->parent_list = plist_obstack_new(phase_obst(ph)); - res->kill_value_list = plist_obstack_new(phase_obst(ph)); - //res->dvg_user_list = plist_obstack_new(phase_obst(ph)); - //res->dvg_pkiller_list = plist_obstack_new(phase_obst(ph)); + res->killer = NULL; + res->irn = irn; + res->chain = NULL; - res->killer = NULL; - res->irn = irn; - res->chain = NULL; - - res->desc_walk = 0; - res->live_out = 0; - res->visited = 0; - res->handled = 0; - res->dumped = 0; - res->havecons = 0; + res->kill_count = 0; + res->desc_walk = 0; + res->live_out = 0; + res->visited = 0; + res->handled = 0; + res->dumped = 0; + res->havecons = 0; return res; } @@ -594,8 +588,8 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * return; cur_node->desc_walk = cur_desc_walk; - /* Stop at Barriers and Keeps */ - if (be_is_Barrier(irn) || be_is_Keep(irn)) + /* Stop at Barriers */ + if (be_is_Barrier(irn)) return; /* loop over normal and dependency edges */ @@ -607,8 +601,20 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * if (arch_irn_is(rss->arch_env, user, ignore)) continue; + /* + (a) mode_X means Jump -> out_edge + (b) Phi as user of a normal node -> out-edge + */ + if (get_irn_mode(user) == mode_X || is_Phi(user)) { + if (! *got_sink) + goto force_sink; + else + continue; + } + if (is_Proj(user)) { - if (get_irn_mode(user) != mode_X && arch_get_irn_reg_class(rss->arch_env, user, -1) == rss->cls) + + //if (arch_get_irn_reg_class(rss->arch_env, user, -1) == rss->cls) collect_descendants(rss, rirn, user, got_sink, cur_desc_walk); } else { @@ -621,6 +627,7 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * collect_descendants(rss, rirn, user, got_sink, cur_desc_walk); } else if (! *got_sink) { +force_sink: /* user lives out of block: add sink as descendant if not already done */ plist_insert_back(rirn->descendant_list, _sink); *got_sink = 1; @@ -635,13 +642,12 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * * Handles a single consumer. */ static void collect_single_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *consumer, int *got_sink) { - ir_node *block = rss->block; - ir_edge_kind_t ekind[2] = { EDGE_KIND_NORMAL, EDGE_KIND_DEP }; + ir_node *block = rss->block; assert(! is_Proj(consumer) && "Cannot handle Projs"); - if (get_nodes_block(consumer) == block) { - if (! arch_irn_is(rss->arch_env, consumer, ignore)) { + if (! is_Phi(consumer) && ! is_Block(consumer) && get_nodes_block(consumer) == block) { + if (! arch_irn_is(rss->arch_env, consumer, ignore) && ! plist_has_value(rss_irn->consumer_list, consumer)) { plist_insert_back(rss_irn->consumer_list, consumer); DBG((rss->dbg, LEVEL_2, "\t\tconsumer %+F\n", consumer)); } @@ -676,7 +682,7 @@ static void collect_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *irn, int * ir_node *consumer = get_edge_src_irn(edge); if (is_Proj(consumer)) { - if (arch_get_irn_reg_class(rss->arch_env, consumer, -1) == rss->cls) + //if (arch_get_irn_reg_class(rss->arch_env, consumer, -1) == rss->cls) collect_consumer(rss, rss_irn, consumer, got_sink); } else @@ -685,52 +691,6 @@ static void collect_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *irn, int * } } -#if 0 -/** - * We need to build the consumer and descendant list for _source. - */ -static void collect_node_info_source(rss_t *rss) { - const ir_edge_t *edge; - rss_irn_t *rirn = get_rss_irn(rss, _source); - ir_node *block = rss->block; - - if (rirn->handled) - return; - - foreach_out_edge(block, edge) { - ir_node *irn = get_edge_src_irn(edge); - int i; - - for (i = get_irn_arity(n) - 1; i >= 0; --i) { - - } - } -} - -static void reset_node_info(rss_irn_t *rss_irn) { - /* Beware: array data resides on phase obstack, so it gets removed automatically */ - - plist_clear(rss_irn->consumer_list); - rss_irn->consumer = NULL; - - plist_clear(rss_irn->parent_list); - rss_irn->parents = NULL; - - plist_clear(rss_irn->descendant_list); - rss_irn->descendants = NULL; - - plist_clear(rss_irn->pkiller_list); - rss_irn->pkillers = NULL; - - plist_clear(rss_irn->kill_value_list); - - rss_irn->killer = NULL; - rss_irn->live_out = 0; - rss_irn->visited = 0; - rss_irn->handled = 0; -} -#endif /* if 0 */ - /** * Collects all consumer and descendant of a irn. */ @@ -743,7 +703,8 @@ static void collect_node_info(rss_t *rss, ir_node *irn) { /* check if node info is already available */ if (rss_irn->handled) - phase_reinit_single_irn_data(&rss->ph, irn); + return; + //phase_reinit_single_irn_data(&rss->ph, irn); DBG((rss->dbg, LEVEL_1, "\tcomputing consumers of %+F:\n", irn)); @@ -834,16 +795,6 @@ static void update_node_info(rss_t *rss, ir_node *irn, ir_node *pk_irn) { node->descendants = build_sorted_array_from_list(node->descendant_list, phase_obst(&rss->ph)); } -#if 0 - /* check, if pkiller is a potential killer of irn */ - if (is_potential_killer(rss, pkiller, node)) { - if (! plist_has_value(node->pkiller_list, pk_irn)) - plist_insert_back(node->pkiller_list, pk_irn); - if (! plist_has_value(pkiller->kill_value_list, irn)) - plist_insert_back(pkiller->kill_value_list, irn); - DBG((rss->dbg, LEVEL_1, "\tpotential killer %+F added to %+F\n", pk_irn, irn)); - } -#endif } /** @@ -867,8 +818,7 @@ static void compute_pkill_set(rss_t *rss) { if (is_potential_killer(rss, v, u)) { if (! plist_has_value(u->pkiller_list, v_irn)) plist_insert_back(u->pkiller_list, v_irn); - if (! plist_has_value(v->kill_value_list, u_irn)) - plist_insert_back(v->kill_value_list, u_irn); + v->kill_count++; DBG((rss->dbg, LEVEL_2, "\t\tpotential killer %+F\n", v_irn)); } } @@ -907,6 +857,7 @@ static void build_kill_edges(rss_t *rss, pset *epk) { } } +#ifdef DEBUG_libfirm /* print the given cbc for debugging purpose */ static void debug_print_cbc(firm_dbg_module_t *mod, cbc_t *cbc) { ir_node *n; @@ -925,6 +876,7 @@ static void debug_print_cbc(firm_dbg_module_t *mod, cbc_t *cbc) { DBG((mod, LEVEL_3, "\t\t\t%+F -> %+F\n", ke->src, ke->tgt)); } } +#endif /** * Construct the bipartite decomposition. @@ -946,6 +898,7 @@ static void compute_bipartite_decomposition(rss_t *rss) { rss_irn_t *u = get_rss_irn(rss, u_irn); int p_change = 1; int c_change = 1; + int vrfy_ok = 1; cbc_t *cbc; plist_element_t *el2; @@ -988,32 +941,26 @@ static void compute_bipartite_decomposition(rss_t *rss) { /* accumulate parents */ foreach_nodeset(cbc->children, t_irn) { - rss_irn_t *t = get_rss_irn(rss, t_irn); - plist_element_t *kvl_el; - foreach_pset(epk, k_edge) { ir_node *val = k_edge->src; - if (k_edge->tgt == t_irn && ! nodeset_find(cbc->parents, k_edge->src)) { + if (k_edge->tgt == t_irn && ! nodeset_find(cbc->parents, val)) { nodeset_insert(cbc->parents, val); p_change = 1; - DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents\n", val)); + DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents (killed by %+F)\n", val, t_irn)); } } } /* accumulate children */ foreach_nodeset(cbc->parents, s_irn) { - rss_irn_t *s = get_rss_irn(rss, s_irn); - plist_element_t *pkl_el; - - foreach_plist(s->pkiller_list, pkl_el) { - ir_node *val = plist_element_get_value(pkl_el); + foreach_pset(epk, k_edge) { + ir_node *val = k_edge->tgt; - if (! nodeset_find(cbc->children, val)) { + if (k_edge->src == s_irn && ! nodeset_find(cbc->children, val)) { nodeset_insert(cbc->children, val); c_change = 1; - DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children\n", val)); + DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children (kills %+F)\n", val, s_irn)); } } } @@ -1024,10 +971,12 @@ static void compute_bipartite_decomposition(rss_t *rss) { rss_irn_t *s = get_rss_irn(rss, s_irn); s->visited = 1; /* assure bipartite property */ +#if 0 if (nodeset_find(cbc->children, s_irn)) { nodeset_remove(cbc->children, s_irn); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F removed from to children\n", s_irn)); } +#endif } /* update edges */ @@ -1048,6 +997,25 @@ static void compute_bipartite_decomposition(rss_t *rss) { pset_remove(epk, kedge_root, HASH_RSS_EDGE(kedge_root)); } + /* verify the cbc */ + foreach_nodeset(cbc->parents, s_irn) { + int is_killed = 0; + + foreach_pset(cbc->kill_edges, k_edge) { + if (k_edge->src == s_irn) { + is_killed = 1; + pset_break(cbc->kill_edges); + break; + } + } + + if (! is_killed) { + vrfy_ok = 0; + ir_fprintf(stderr, "Warning: parent %+F is not killed in current cbc\n", s_irn); + } + } + assert(vrfy_ok && "Verification of CBC failed"); + /* add the connected bipartite component */ if (nodeset_count(cbc->parents) > 0 && nodeset_count(cbc->children) > 0 && pset_count(cbc->kill_edges) > 0) pset_insert(rss->cbc_set, cbc, (unsigned)cbc->nr); @@ -1231,26 +1199,33 @@ static void compute_killing_function(rss_t *rss) { * Adds the edge src -> tgt to the dvg. Checks if reverse edge is already there (asserts). */ static INLINE void add_dvg_edge(rss_t *rss, dvg_t *dvg, ir_node *src, ir_node *tgt, int have_source) { - rss_edge_t *dvg_edge = obstack_alloc(phase_obst(&rss->ph), sizeof(*dvg_edge)); + rss_edge_t *dvg_edge; rss_edge_t key; if (! have_source) nodeset_insert(dvg->nodes, src); + else + assert(nodeset_find(dvg->nodes, src) != NULL && "Wrong assumption"); nodeset_insert(dvg->nodes, tgt); - /* add an edge to our killer */ - dvg_edge->src = src; - dvg_edge->tgt = tgt; - dvg_edge->next = NULL; - key.src = tgt; key.tgt = src; assert(pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key)) == NULL && "DVG must be acyclic!"); - /* add the edge to the DVG */ - DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", src, tgt)); - pset_insert(dvg->edges, dvg_edge, HASH_RSS_EDGE(dvg_edge)); + key.src = src; + key.tgt = tgt; + if (NULL != pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) { + /* add the edge to the DVG */ + dvg_edge = obstack_alloc(phase_obst(&rss->ph), sizeof(*dvg_edge)); + + dvg_edge->src = src; + dvg_edge->tgt = tgt; + dvg_edge->next = NULL; + + DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", src, tgt)); + pset_insert(dvg->edges, dvg_edge, HASH_RSS_EDGE(dvg_edge)); + } } /** @@ -1324,13 +1299,37 @@ static void compute_dvg(rss_t *rss, dvg_t *dvg) { * Updates the dvg structure when a serialization edge from src -> tgt is added. */ static void update_dvg(rss_t *rss, dvg_t *dvg, rss_irn_t *src, rss_irn_t *tgt) { - int i; + int i, j, idx; + rss_edge_t *edge; + rss_edge_t **arr = alloca(pset_count(dvg->edges) * sizeof(arr[0])); - add_dvg_edge(rss, dvg, tgt->irn, src->irn, 1); + /* + Add an edge from serialization target to serialization src: + src cannot be alive with target + */ + add_dvg_edge(rss, dvg, tgt->irn, src->irn, 0); + /* Add edges to src's descendants as well, they also getting serialized. */ for (i = ARR_LEN_SAFE(src->descendants) - 1; i >= 0; --i) { add_dvg_edge(rss, dvg, tgt->irn, src->descendants[i], 1); } + + /* We also have to add edges from targets predecessors in dvg */ + idx = 0; + /* We cannot insert elements into set over which we iterate ... */ + foreach_pset(dvg->edges, edge) { + if (edge->tgt == tgt->irn) { + arr[idx++] = edge; + } + } + + for (i = 0; i < idx; ++i) { + edge = arr[i]; + add_dvg_edge(rss, dvg, edge->src, src->irn, 1); + for (j = ARR_LEN_SAFE(src->descendants) - 1; j >= 0; --j) { + add_dvg_edge(rss, dvg, edge->src, src->descendants[j], 1); + } + } } #if 0 @@ -1629,7 +1628,7 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) assert(el && "Missing element in chain!"); /* If u has predecessor in chain: insert the predecessor */ - if (el = plist_element_get_prev(el)) { + if (el == plist_element_get_prev(el)) { nodeset_insert(values, plist_element_get_value(el)); DBG((rss->dbg, LEVEL_3, "\t\t\tadding %+F to values\n", plist_element_get_value(el))); } @@ -1676,8 +1675,8 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese ir_node *irn; rss_edge_t min_benefit_edge; rss_edge_t min_omega20_edge; - rss_irn_t *ser_u_omega1, *ser_v_omega1; - rss_irn_t *ser_u_omega20, *ser_v_omega20; + rss_irn_t *ser_u_omega1 = NULL, *ser_v_omega1 = NULL; + rss_irn_t *ser_u_omega20 = NULL, *ser_v_omega20 = NULL; DBG((rss->dbg, LEVEL_1, "\tcomputing admissible serializations:\n")); @@ -1707,15 +1706,20 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese In this case there is no serialization which could reduce the registerpressure */ -#define IS_UNSERIALIZABLE_NODE(rss_node) \ - ((plist_count(rss_node->pkiller_list) == 1) && \ - is_Sink(rss_node->killer) && \ - (plist_count(rss_node->kill_value_list) == 0)) +#define IS_UNSERIALIZABLE_NODE(rss_node) \ + ( \ + ( \ + (plist_count(rss_node->pkiller_list) == 1) && \ + is_Sink(rss_node->killer) && \ + (rss_node->kill_count == 0) \ + ) || \ + be_is_Barrier(rss_node->irn) || \ + be_is_Keep(rss_node->irn) \ + ) /* for all u in sat_vals */ for (i = 0; i < n; ++i) { - rss_irn_t *u = get_rss_irn(rss, val_arr[i]); - int u_height = get_irn_height(rss->h, val_arr[i]); + rss_irn_t *u = get_rss_irn(rss, val_arr[i]); plist_element_t *el; /* ignore nodes where serialization does not help */ @@ -1772,7 +1776,7 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese ir_node *vv_irn = plist_element_get_value(el); int add_edge; - if (is_Sink(vv_irn)) + if (is_Sink(vv_irn) || is_cfop(vv_irn)) continue; if (is_pkiller) @@ -1900,7 +1904,9 @@ static void perform_value_serialization_heuristic(rss_t *rss) { arch_put_non_ignore_regs(rss->arch_env, rss->cls, arch_nonign_bs); be_abi_put_ignore_regs(rss->abi, rss->cls, abi_ign_bs); bitset_andnot(arch_nonign_bs, abi_ign_bs); - available_regs = bitset_popcnt(arch_nonign_bs); + available_regs = bitset_popcnt(arch_nonign_bs); + //num_live = pset_count(rss->live_block); + //available_regs -= num_live < available_regs ? num_live : 0; DBG((rss->dbg, LEVEL_1, "\n\t#available regs: %d\n\n", available_regs)); @@ -1924,7 +1930,6 @@ static void perform_value_serialization_heuristic(rss_t *rss) { while (sat_vals && (nodeset_count(sat_vals) > available_regs)) { serialization_t *ser, best_ser; rss_edge_t *edge = obstack_alloc(phase_obst(&rss->ph), sizeof(*edge)); - rss_irn_t *tgt, *src; ir_node *dep_src, *dep_tgt; best_ser.edge = edge; @@ -2002,13 +2007,18 @@ static void process_block(ir_node *block, void *env) { rss->cls = cls; 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); + /* reset the list of interesting nodes */ plist_clear(rss->nodes); plist_insert_back(rss->nodes, _sink); /* collect all nodes having a certain register class */ foreach_out_edge(block, edge) { - ir_node *irn = get_edge_src_irn(edge); + ir_node *irn = get_edge_src_irn(edge); + ir_mode *mode = get_irn_mode(irn); /* We skip: @@ -2017,7 +2027,7 @@ static void process_block(ir_node *block, void *env) { - Keeps (they are always immediately scheduled) - Phi (same as Keep) */ - if (get_irn_mode(irn) == mode_T || be_is_Keep(irn) || is_Phi(irn)) + if (mode == mode_T || mode == mode_X || is_Phi(irn)) continue; /* @@ -2032,12 +2042,16 @@ static void process_block(ir_node *block, void *env) { continue; } + /* calculate the descendants and consumer for each node in the block */ + collect_node_info(rss, skip_Proj(irn)); + + if (be_is_Keep(irn)) + continue; + if (! arch_irn_is(rss->arch_env, irn, ignore) && arch_get_irn_reg_class(rss->arch_env, irn, -1) == cls) { plist_insert_back(rss->nodes, skip_Proj(irn)); - - /* calculate the descendants and consumer for each node in the block */ - collect_node_info(rss, skip_Proj(irn)); } + //} } /* compute the potential killing set PK(G) */ @@ -2051,6 +2065,8 @@ static void process_block(ir_node *block, void *env) { add the necessary dependencies to the irg. */ perform_value_serialization_heuristic(rss); + + del_pset(rss->live_block); } phase_free(&rss->ph); @@ -2060,17 +2076,15 @@ static void process_block(ir_node *block, void *env) { /** * Register the options. */ -void rss_register_options(lc_opt_entry_t *grp) { - static int run_once = 0; - lc_opt_entry_t *rss_grp; +void be_init_schedrss(void) { + lc_opt_entry_t *be_grp = lc_opt_get_grp(firm_opt_get_root(), "be"); + lc_opt_entry_t *sched_grp = lc_opt_get_grp(be_grp, "sched"); + lc_opt_entry_t *rss_grp = lc_opt_get_grp(sched_grp, "rss"); - if (! run_once) { - run_once = 1; - rss_grp = lc_opt_get_grp(grp, "rss"); - - lc_opt_add_table(rss_grp, rss_option_table); - } + lc_opt_add_table(rss_grp, rss_option_table); } + +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_schedrss); #endif /* WITH_LIBCORE */ /** @@ -2091,9 +2105,11 @@ void rss_schedule_preparation(const be_irg_t *birg) { rss.h = heights_new(birg->irg); rss.nodes = plist_new(); rss.opts = &rss_options; + rss.liveness = be_liveness(birg->irg); irg_block_walk_graph(birg->irg, NULL, process_block, &rss); heights_free(rss.h); plist_free(rss.nodes); + be_liveness_free(rss.liveness); if (birg->main_env->options->dump_flags & DUMP_SCHED) be_dump(rss.irg, "-rss", dump_ir_block_graph);