X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeschedrss.c;h=38503cee6cd59a163adc51186c0bf78fb12873a9;hb=8ce557f8a7ef7f24e2a4c405e1279a43380b24df;hp=9f5da52159894372292f397ae6e6ec584a609b1e;hpb=1b245d9dc2a23d2b422ee2beba8de6d16e8157f8;p=libfirm diff --git a/ir/be/beschedrss.c b/ir/be/beschedrss.c index 9f5da5215..38503cee6 100644 --- a/ir/be/beschedrss.c +++ b/ir/be/beschedrss.c @@ -1,16 +1,34 @@ +/* + * Copyright (C) 1995-2008 University of Karlsruhe. All right reserved. + * + * This file is part of libFirm. + * + * This file may be distributed and/or modified under the terms of the + * GNU General Public License version 2 as published by the Free Software + * Foundation and appearing in the file LICENSE.GPL included in the + * packaging of this file. + * + * Licensees holding valid libFirm Professional Edition licenses may use + * this file in accordance with the libFirm Commercial License. + * Agreement provided with the Software. + * + * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE + * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE. + */ + /** + * @file + * @brief Implementation of a register saturating list scheduler. + * @author Christian Wuerdig + * @date 29.08.2006 + * @version $Id$ + * * Implementation of a register saturating list scheduler * as described in: Sid-Ahmed-Ali Touati * Register Saturation in Superscalar and VLIW Codes - * - * @license This file protected by GPL - GNU GENERAL PUBLIC LICENSE. - * @author Christian Wuerdig - * @date 29.08.2006 - * @cvs-id $Id$ */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif #include @@ -30,17 +48,18 @@ #include "bipartite.h" #include "hungarian.h" #include "plist.h" +#include "array_t.h" #include "height.h" #include "beabi.h" +#include "bemodule.h" #include "benode_t.h" #include "besched_t.h" +#include "beirg_t.h" -#ifdef WITH_LIBCORE -#include -#include -#endif /* WITH_LIBCORE */ +#include "lc_opts.h" +#include "lc_opts_enum.h" #define ARR_LEN_SAFE(arr) ((arr) != NULL ? ARR_LEN((arr)) : 0) @@ -71,15 +90,15 @@ typedef struct _rss_edge { /* Represents a connected bipartite component. */ typedef struct _cbc { - nodeset *parents; /**< = S a set of value producers */ - nodeset *children; /**< = T a set of value consumers */ + ir_nodeset_t parents; /**< = S a set of value producers */ + ir_nodeset_t children; /**< = T a set of value consumers */ pset *kill_edges; /**< = E a set of edges (t in T, s in S) such as each s in S gets killed by at least one t in T */ int nr; /**< a deterministic index for set insertion (used as hash) */ } cbc_t; /* Represents a disjoint value DAG. */ typedef struct _dvg { - nodeset *nodes; + ir_nodeset_t nodes; pset *edges; } dvg_t; @@ -91,16 +110,16 @@ typedef struct _chain { typedef struct _rss_irn { plist_t *consumer_list; /**< List of consumers */ - ir_node **consumer; /**< Sorted consumer array (needed for faster access) */ + const ir_node **consumer; /**< Sorted consumer array (needed for faster access) */ plist_t *parent_list; /**< List of parents */ 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) */ + const ir_node **descendants; /**< Sorted descendant array (needed for faster access) */ - ir_node *killer; /**< The selected unique killer */ - ir_node *irn; /**< The corresponding firm node to this rss_irn */ + const ir_node *killer; /**< The selected unique killer */ + const ir_node *irn; /**< The corresponding firm node to this rss_irn */ chain_t *chain; /**< The chain, this node is associated to */ @@ -125,7 +144,7 @@ typedef struct _serialization { } serialization_t; typedef struct _rss { - phase_t ph; /**< Phase to hold some data */ + ir_phase ph; /**< Phase to hold some data */ heights_t *h; /**< The current height object */ ir_graph *irg; /**< The irg to preprocess */ plist_t *nodes; /**< The list of interesting nodes */ @@ -137,7 +156,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; @@ -148,14 +167,20 @@ typedef struct _rss { * We need some special nodes: * a source and a sink for all live-in and live-out values of a block */ - enum { iro_rss_Source, iro_rss_Sink, iro_rss_last }; +/** The opcode of the rss_Source node once allocated. */ +static ir_op *op_rss_Source; +/** The opcode of the rss_Sink node once allocated. */ +static ir_op *op_rss_Sink; + +/** The rss_Source node of the current graph. */ static ir_node *_source = NULL; +/** The rss_Sink node of the current graph. */ static ir_node *_sink = NULL; #define is_Source(irn) ((irn) == _source) @@ -175,7 +200,6 @@ static rss_opts_t rss_options = { RSS_DUMP_NONE, }; -#ifdef WITH_LIBCORE static const lc_opt_enum_int_items_t dump_items[] = { { "none", RSS_DUMP_NONE }, { "cbc", RSS_DUMP_CBC }, @@ -193,9 +217,8 @@ 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", &dump_var), - { NULL } + LC_OPT_LAST }; -#endif /* WITH_LIBCORE */ /****************************************************************************** * _ _ __ _ _ @@ -209,15 +232,19 @@ static const lc_opt_table_entry_t rss_option_table[] = { ******************************************************************************/ /** - * Acquire opcodes and create source and sink nodes. + * Acquire opcodes if needed and create source and sink nodes. */ static void init_rss_special_nodes(ir_graph *irg) { - ir_node *block = get_irg_start_block(irg); - int iro_rss_base = get_next_ir_opcodes(iro_rss_last); - ir_op *op_rss_Source = new_ir_op(iro_rss_base + iro_rss_Source, "rss_Source", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL); - ir_op *op_rss_Sink = new_ir_op(iro_rss_base + iro_rss_Sink, "rss_Sink", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL); - _source = new_ir_node(NULL, irg, block, op_rss_Source, mode_ANY, 0, NULL); - _sink = new_ir_node(NULL, irg, block, op_rss_Sink, mode_ANY, 0, NULL); + ir_node *block; + + if (op_rss_Source == NULL) { + int iro_rss_base = get_next_ir_opcodes(iro_rss_last); + op_rss_Source = new_ir_op(iro_rss_base + iro_rss_Source, "rss_Source", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL); + op_rss_Sink = new_ir_op(iro_rss_base + iro_rss_Sink, "rss_Sink", op_pin_state_pinned, irop_flag_none, oparity_zero, 0, 0, NULL); + } + block = get_irg_start_block(irg); + _source = new_ir_node(NULL, irg, block, op_rss_Source, mode_ANY, 0, NULL); + _sink = new_ir_node(NULL, irg, block, op_rss_Sink, mode_ANY, 0, NULL); } static int cmp_int(const void *a, const void *b) { @@ -268,11 +295,11 @@ static int bsearch_for_index(int key, int *arr, size_t len, int force) { return -1; } -static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack *obst) { +static const ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack *obst) { plist_element_t *el; - int i = 0; - int len = plist_count(irn_list); - ir_node **arr = NEW_ARR_D(ir_node *, obst, len); + int i = 0; + int len = plist_count(irn_list); + const ir_node **arr = (const ir_node**)NEW_ARR_D(ir_node*, obst, len); /* copy the list into the array */ foreach_plist(irn_list, el) { @@ -280,7 +307,8 @@ static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack } /* sort the array by node index */ - qsort(arr, len, sizeof(arr[0]), cmp_irn_idx); + /* HACK cast for MSVC */ + qsort((void*)arr, len, sizeof(arr[0]), cmp_irn_idx); return arr; } @@ -297,12 +325,17 @@ static ir_node **build_sorted_array_from_list(plist_t *irn_list, struct obstack * *****************************************************/ -static void dump_nodeset(nodeset *ns, const char *prefix) { +#ifdef DEBUG_libfirm +static void dump_nodeset(ir_nodeset_t *ns, const char *prefix) { + ir_nodeset_iterator_t iter; ir_node *irn; - foreach_nodeset(ns, irn) { + + ir_nodeset_iterator_init(&iter, ns); + while( (irn = ir_nodeset_iterator_next(&iter)) != NULL ) { 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; @@ -330,14 +363,15 @@ static void debug_vcg_dump_bipartite(rss_t *rss) { fprintf(f, "manhattan_edges: yes\n\n"); foreach_pset(rss->cbc_set, cbc) { + ir_nodeset_iterator_t iter; ir_node *n; rss_edge_t *ke; fprintf(f, "graph: { titel: \"cbc %d\" label: \"cbc %d\" status:clustered color:yellow\n", cbc->nr, cbc->nr); - foreach_nodeset(cbc->parents, n) { + foreach_ir_nodeset(&cbc->parents, n, iter) { ir_fprintf(f, "node: { title: \"n%d_%d\" label: \"%+F\" }\n", get_irn_node_nr(n), cbc->nr, n); } - foreach_nodeset(cbc->children, n) { + foreach_ir_nodeset(&cbc->children, n, iter) { ir_fprintf(f, "node: { title: \"n%d_%d\" label: \"%+F\" }\n", get_irn_node_nr(n), cbc->nr, n); } foreach_pset(cbc->kill_edges, ke) { @@ -399,19 +433,20 @@ static void debug_vcg_dump_kill(rss_t *rss) { } /* Dumps the potential killing DAG (PKG) as vcg. */ -static void debug_vcg_dump_pkg(rss_t *rss, nodeset *max_ac, int iteration) { +static void debug_vcg_dump_pkg(rss_t *rss, ir_nodeset_t *max_ac, int iteration) +{ FILE *f; char file_name[256]; - char *suffix = alloca(32); + char suffix[32]; static const char suffix1[] = "-RSS-PKG.vcg"; static const char suffix2[] = "-RSS-PKG-MAXAC.vcg"; plist_element_t *el; if (! max_ac) { - snprintf(suffix, 32, "%s", suffix1); + snprintf(suffix, sizeof(suffix), "%s", suffix1); } else { - snprintf(suffix, 32, "-%02d%s", iteration, suffix2); + snprintf(suffix, sizeof(suffix), "-%02d%s", iteration, suffix2); } build_file_name(rss, suffix, strlen(suffix) + 1, file_name, sizeof(file_name)); @@ -438,7 +473,7 @@ static void debug_vcg_dump_pkg(rss_t *rss, nodeset *max_ac, int iteration) { plist_element_t *k_el; /* dump selected saturating values in yellow */ - if (max_ac && nodeset_find(max_ac, irn)) + if (max_ac && ir_nodeset_contains(max_ac, irn)) c1 = "color:yellow"; if (! rirn->dumped) { @@ -454,7 +489,7 @@ static void debug_vcg_dump_pkg(rss_t *rss, nodeset *max_ac, int iteration) { rss_irn_t *pk_rirn = get_rss_irn(rss, pkiller); char *c2 = ""; - if (max_ac && nodeset_find(max_ac, pkiller)) + if (max_ac && ir_nodeset_contains(max_ac, pkiller)) c2 = "color:yellow"; if (! pk_rirn->dumped) { @@ -477,6 +512,7 @@ static void debug_vcg_dump_dvg(rss_t *rss, dvg_t *dvg) { static const char suffix[] = "-RSS-DVG.vcg"; FILE *f; char file_name[256]; + ir_nodeset_iterator_t iter; ir_node *irn; rss_edge_t *edge; @@ -489,7 +525,7 @@ static void debug_vcg_dump_dvg(rss_t *rss, dvg_t *dvg) { fprintf(f, "manhattan_edges: yes\n\n"); /* dump all nodes */ - foreach_nodeset(dvg->nodes, irn) { + foreach_ir_nodeset(&dvg->nodes, irn, iter) { ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(irn), irn); } @@ -509,6 +545,7 @@ static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg) { static const char suffix[] = "-RSS-DVG-PKG.vcg"; FILE *f; char file_name[256]; + ir_nodeset_iterator_t iter; ir_node *irn; build_file_name(rss, suffix, sizeof(suffix), file_name, sizeof(file_name)); @@ -520,12 +557,12 @@ static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg) { fprintf(f, "manhattan_edges: yes\n\n"); /* dump all nodes */ - foreach_nodeset(dvg->nodes, irn) { + foreach_ir_nodeset(&dvg->nodes, irn, iter) { ir_fprintf(f, "node: { title: \"n%d\" label: \"%+F\" }\n", get_irn_node_nr(irn), irn); } /* dump all edges */ - foreach_nodeset(dvg->nodes, irn) { + foreach_ir_nodeset(&dvg->nodes, irn, iter) { rss_irn_t *node = get_rss_irn(rss, irn); plist_element_t *el; @@ -543,7 +580,7 @@ static void debug_vcg_dump_dvg_pkiller(rss_t *rss, dvg_t *dvg) { /** * In case there is no rss information for irn, initialize it. */ -static void *init_rss_irn(phase_t *ph, ir_node *irn, void *old) { +static void *init_rss_irn(ir_phase *ph, const 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)); @@ -595,7 +632,7 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * ir_node *user = get_edge_src_irn(edge); /* skip ignore nodes as they do not really contribute to register pressure */ - if (arch_irn_is(rss->arch_env, user, ignore)) + if (arch_irn_is_ignore(user)) continue; /* @@ -610,8 +647,7 @@ static void collect_descendants(rss_t *rss, rss_irn_t *rirn, ir_node *irn, int * } if (is_Proj(user)) { - - //if (arch_get_irn_reg_class(rss->arch_env, user, -1) == rss->cls) + //if (arch_get_irn_reg_class_out(user) == rss->cls) collect_descendants(rss, rirn, user, got_sink, cur_desc_walk); } else { @@ -643,8 +679,9 @@ static void collect_single_consumer(rss_t *rss, rss_irn_t *rss_irn, ir_node *con assert(! is_Proj(consumer) && "Cannot handle Projs"); - if (! 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)) { + if (! is_Phi(consumer) && ! is_Block(consumer) && get_nodes_block(consumer) == block) { + if (!arch_irn_is_ignore(consumer) && + !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)); } @@ -679,7 +716,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_out(consumer) == rss->cls) collect_consumer(rss, rss_irn, consumer, got_sink); } else @@ -735,8 +772,9 @@ static void collect_node_info(rss_t *rss, ir_node *irn) { */ static int is_potential_killer(rss_t *rss, rss_irn_t *v, rss_irn_t *u) { plist_t *list; - ir_node **arr; + const ir_node **arr; plist_element_t *el; + (void) rss; assert(is_Sink(v->irn) || ((plist_count(v->descendant_list) > 0 && v->descendants) || 1)); assert(is_Sink(u->irn) || ((plist_count(u->consumer_list) > 0 && u->consumer) || 1)); @@ -854,17 +892,19 @@ 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_nodeset_iterator_t iter; ir_node *n; rss_edge_t *ke; DBG((mod, LEVEL_3, "\t\tS = set of parents:\n")); - foreach_nodeset(cbc->parents, n) { + foreach_ir_nodeset(&cbc->parents, n, iter) { DBG((mod, LEVEL_3, "\t\t\t%+F\n", n)); } DBG((mod, LEVEL_3, "\t\tT = set of children:\n")); - foreach_nodeset(cbc->children, n) { + foreach_ir_nodeset(&cbc->children, n, iter) { DBG((mod, LEVEL_3, "\t\t\t%+F\n", n)); } DBG((mod, LEVEL_3, "\t\tE = Edges from producers to consumers\n")); @@ -872,6 +912,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. @@ -900,6 +941,7 @@ static void compute_bipartite_decomposition(rss_t *rss) { rss_edge_t *k_edge; rss_edge_t *kedge_root = NULL; ir_node *t_irn, *s_irn; + ir_nodeset_iterator_t iter; if (u->visited || u_irn == _sink) continue; @@ -910,8 +952,8 @@ static void compute_bipartite_decomposition(rss_t *rss) { cbc->nr = cur_num++; /* initialize S_cb */ - cbc->parents = new_nodeset(5); - nodeset_insert(cbc->parents, u_irn); + ir_nodeset_init_size(&cbc->parents, 5); + ir_nodeset_insert(&cbc->parents, u_irn); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents (init)\n", u_irn)); /* E_cb = empty */ @@ -920,9 +962,9 @@ static void compute_bipartite_decomposition(rss_t *rss) { /* each parent gets killed by at least one value from children */ /* T_cb = PK_successors(u) */ - cbc->children = new_nodeset(5); + ir_nodeset_init_size(&cbc->children, 5); foreach_plist(u->pkiller_list, el2) { - nodeset_insert(cbc->children, plist_element_get_value(el2)); + ir_nodeset_insert(&cbc->children, plist_element_get_value(el2)); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children (init)\n", plist_element_get_value(el2))); } @@ -932,15 +974,16 @@ static void compute_bipartite_decomposition(rss_t *rss) { until the sets don't change any more */ while (p_change || c_change) { + ir_nodeset_iterator_t iter; p_change = c_change = 0; /* accumulate parents */ - foreach_nodeset(cbc->children, t_irn) { + foreach_ir_nodeset(&cbc->children, t_irn, iter) { foreach_pset(epk, k_edge) { ir_node *val = k_edge->src; - if (k_edge->tgt == t_irn && ! nodeset_find(cbc->parents, val)) { - nodeset_insert(cbc->parents, val); + if (k_edge->tgt == t_irn && ! ir_nodeset_contains(&cbc->parents, val)) { + ir_nodeset_insert(&cbc->parents, val); p_change = 1; DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to parents (killed by %+F)\n", val, t_irn)); } @@ -948,12 +991,12 @@ static void compute_bipartite_decomposition(rss_t *rss) { } /* accumulate children */ - foreach_nodeset(cbc->parents, s_irn) { + foreach_ir_nodeset(&cbc->parents, s_irn, iter) { foreach_pset(epk, k_edge) { ir_node *val = k_edge->tgt; - if (k_edge->src == s_irn && ! nodeset_find(cbc->children, val)) { - nodeset_insert(cbc->children, val); + if (k_edge->src == s_irn && ! ir_nodeset_contains(&cbc->children, val)) { + ir_nodeset_insert(&cbc->children, val); c_change = 1; DBG((rss->dbg, LEVEL_3, "\t\t\t%+F added to children (kills %+F)\n", val, s_irn)); } @@ -962,13 +1005,13 @@ static void compute_bipartite_decomposition(rss_t *rss) { } /* mark all parent values as visited */ - foreach_nodeset(cbc->parents, s_irn) { + foreach_ir_nodeset(&cbc->parents, s_irn, iter) { 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); + if (ir_nodeset_contains(&cbc->children, s_irn)) { + ir_nodeset_remove(&cbc->children, s_irn); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F removed from to children\n", s_irn)); } #endif @@ -976,7 +1019,8 @@ static void compute_bipartite_decomposition(rss_t *rss) { /* update edges */ foreach_pset(epk, k_edge) { - if (nodeset_find(cbc->parents, k_edge->src) && nodeset_find(cbc->children, k_edge->tgt)) { + if (ir_nodeset_contains(&cbc->parents, k_edge->src) && + ir_nodeset_contains(&cbc->children, k_edge->tgt)) { pset_insert(cbc->kill_edges, k_edge, HASH_RSS_EDGE(k_edge)); /* Link all k_edges which are about to be removed together. @@ -993,7 +1037,7 @@ static void compute_bipartite_decomposition(rss_t *rss) { } /* verify the cbc */ - foreach_nodeset(cbc->parents, s_irn) { + foreach_ir_nodeset(&cbc->parents, s_irn, iter) { int is_killed = 0; foreach_pset(cbc->kill_edges, k_edge) { @@ -1012,7 +1056,9 @@ static void compute_bipartite_decomposition(rss_t *rss) { 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) + if (ir_nodeset_size(&cbc->parents) > 0 && + ir_nodeset_size(&cbc->children) > 0 && + pset_count(cbc->kill_edges) > 0) pset_insert(rss->cbc_set, cbc, (unsigned)cbc->nr); DBG((rss->dbg, LEVEL_2, "\tbipartite component %d inserted:\n", cbc->nr)); DEBUG_ONLY( @@ -1030,13 +1076,14 @@ static void compute_bipartite_decomposition(rss_t *rss) { /** * Select the child with the maximum cost. */ -static child_t *select_child_max_cost(rss_t *rss, nodeset *x, nodeset *y, child_t *t, cbc_t *cbc) { +static child_t *select_child_max_cost(rss_t *rss, ir_nodeset_t *x, ir_nodeset_t *y, child_t *t, cbc_t *cbc) { ir_node *child; + ir_nodeset_iterator_t iter; float max_cost = -1.0f; DBG((rss->dbg, LEVEL_2, "\t\tcomputing children costs:\n")); - foreach_nodeset(cbc->children, child) { + foreach_ir_nodeset(&cbc->children, child, iter) { rss_irn_t *r_child = get_rss_irn(rss, child); int num_unkilled_parents = 0; int num_descendants; @@ -1045,13 +1092,13 @@ static child_t *select_child_max_cost(rss_t *rss, nodeset *x, nodeset *y, child_ /* get the number of unkilled parents */ foreach_pset(cbc->kill_edges, k_edge) { - if (k_edge->tgt == child && nodeset_find(x, k_edge->src)) + if (k_edge->tgt == child && ir_nodeset_contains(x, k_edge->src)) ++num_unkilled_parents; } cost = (float)num_unkilled_parents; - num_descendants = plist_count(r_child->descendant_list) + nodeset_count(y); + num_descendants = plist_count(r_child->descendant_list) + ir_nodeset_size(y); if (num_descendants > 0) cost /= (float)num_descendants; @@ -1071,29 +1118,29 @@ static child_t *select_child_max_cost(rss_t *rss, nodeset *x, nodeset *y, child_ /** * Remove all parents from x which are killed by t_irn. */ -static void remove_covered_parents(rss_t *rss, nodeset *x, ir_node *t_irn, cbc_t *cbc) { +static void remove_covered_parents(rss_t *rss, ir_nodeset_t *x, ir_node *t_irn, cbc_t *cbc) { rss_irn_t *t = get_rss_irn(rss, t_irn); rss_edge_t *k_edge; DBG((rss->dbg, LEVEL_2, "\t\tremoving parents covered by %+F:\n", t_irn)); foreach_pset(cbc->kill_edges, k_edge) { - if (k_edge->tgt == t_irn && nodeset_find(x, k_edge->src)) { - nodeset_remove(x, k_edge->src); + if (k_edge->tgt == t_irn && ir_nodeset_contains(x, k_edge->src)) { + ir_nodeset_remove(x, k_edge->src); plist_insert_back(t->parent_list, k_edge->src); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", k_edge->src)); } } } -static void update_cumulated_descendent_values(rss_t *rss, nodeset *y, ir_node *t_irn) { +static void update_cumulated_descendent_values(rss_t *rss, ir_nodeset_t *y, ir_node *t_irn) { rss_irn_t *t = get_rss_irn(rss, t_irn); plist_element_t *el; DBG((rss->dbg, LEVEL_2, "\t\tupdating cumulated descendant value of %+F:\n", t_irn)); foreach_plist(t->descendant_list, el) { - nodeset_insert(y, plist_element_get_value(el)); + ir_nodeset_insert(y, plist_element_get_value(el)); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", plist_element_get_value(el))); } } @@ -1113,28 +1160,32 @@ static void compute_killing_function(rss_t *rss) { /* for all bipartite components do: */ foreach_pset(rss->cbc_set, cbc) { ir_node *p; - nodeset *x = new_nodeset(10); - nodeset *y = new_nodeset(10); + ir_nodeset_t x; + ir_nodeset_t y; + ir_nodeset_iterator_t iter; child_t **sks = NEW_ARR_F(child_t *, 20); int cur_len = 0; int cur_size = 20; int i; + ir_nodeset_init_size(&x, 10); + ir_nodeset_init_size(&y, 10); + DBG((rss->dbg, LEVEL_1, "\tcomputing SKS for cbc %d:\n", cbc->nr)); DBG((rss->dbg, LEVEL_2, "\t\tinitializing parents X:\n")); /* X = S_cb (all parents are initially uncovered) */ - foreach_nodeset(cbc->parents, p) { - nodeset_insert(x, p); + foreach_ir_nodeset(&cbc->parents, p, iter) { + ir_nodeset_insert(&x, p); DBG((rss->dbg, LEVEL_3, "\t\t\t%+F\n", p)); } /* while X not empty */ - while (nodeset_count(x) > 0) { + while (ir_nodeset_size(&x) > 0) { child_t *t = obstack_alloc(&obst, sizeof(*t)); memset(t, 0, sizeof(*t)); - t = select_child_max_cost(rss, x, y, t, cbc); + t = select_child_max_cost(rss, &x, &y, t, cbc); if (cur_len >= cur_size) { ARR_EXTO(child_t *, sks, cur_size * 2); @@ -1144,8 +1195,8 @@ static void compute_killing_function(rss_t *rss) { DBG((rss->dbg, LEVEL_2, "\t\tinsert child %+F (%.3f) into SKS at pos %d\n", t->irn, t->cost, cur_len)); sks[cur_len++] = t; - remove_covered_parents(rss, x, t->irn, cbc); - update_cumulated_descendent_values(rss, y, t->irn); + remove_covered_parents(rss, &x, t->irn, cbc); + update_cumulated_descendent_values(rss, &y, t->irn); } ARR_SHRINKLEN(sks, cur_len); @@ -1178,8 +1229,8 @@ static void compute_killing_function(rss_t *rss) { } } - del_nodeset(x); - del_nodeset(y); + ir_nodeset_destroy(&x); + ir_nodeset_destroy(&y); DEL_ARR_F(sks); } @@ -1193,29 +1244,29 @@ 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) { +static inline void add_dvg_edge(rss_t *rss, dvg_t *dvg, const ir_node *src, const ir_node *tgt, int have_source) { rss_edge_t *dvg_edge; rss_edge_t key; if (! have_source) - nodeset_insert(dvg->nodes, src); + ir_nodeset_insert(&dvg->nodes, (ir_node *) src); else - assert(nodeset_find(dvg->nodes, src) != NULL && "Wrong assumption"); + assert(ir_nodeset_contains(&dvg->nodes, src) && "Wrong assumption"); - nodeset_insert(dvg->nodes, tgt); + ir_nodeset_insert(&dvg->nodes, (ir_node *) tgt); - key.src = tgt; - key.tgt = src; + key.src = (ir_node *) tgt; + key.tgt = (ir_node *) src; assert(pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key)) == NULL && "DVG must be acyclic!"); - key.src = src; - key.tgt = tgt; + key.src = (ir_node *) src; + key.tgt = (ir_node *) 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->src = (ir_node *) src; + dvg_edge->tgt = (ir_node *) tgt; dvg_edge->next = NULL; DBG((rss->dbg, LEVEL_3, "\t\tadd edge %+F -> %+F\n", src, tgt)); @@ -1265,7 +1316,7 @@ static void compute_dvg(rss_t *rss, dvg_t *dvg) { rss_edge_t key; /* insert the user into the DVG and append it to the user list of u */ - nodeset_insert(dvg->nodes, v_irn); + ir_nodeset_insert(&dvg->nodes, v_irn); if (! plist_has_value(u->dvg_user_list, v_irn)) plist_insert_back(u->dvg_user_list, v_irn); @@ -1296,7 +1347,7 @@ static void compute_dvg(rss_t *rss, dvg_t *dvg) { static void update_dvg(rss_t *rss, dvg_t *dvg, rss_irn_t *src, rss_irn_t *tgt) { int i, j, idx; rss_edge_t *edge; - rss_edge_t **arr = alloca(pset_count(dvg->edges) * sizeof(arr[0])); + rss_edge_t **arr = ALLOCAN(rss_edge_t*, pset_count(dvg->edges)); /* Add an edge from serialization target to serialization src: @@ -1357,9 +1408,10 @@ static void accumulate_dvg_descendant_values(rss_t *rss, rss_irn_t *root, plist_ * Needs the descendant list for all user as sorted array. */ static void build_dvg_pkiller_list(rss_t *rss, dvg_t *dvg) { + ir_nodeset_iterator_t iter; ir_node *irn; - foreach_nodeset(dvg->nodes, irn) { + foreach_nodeset(&dvg->nodes, irn, iter) { rss_irn_t *node = get_rss_irn(rss, irn); plist_element_t *el, *el2; @@ -1400,13 +1452,14 @@ static void build_dvg_pkiller_list(rss_t *rss, dvg_t *dvg) { * This is a reimplementation of the MAXIMAL_ANTI_CHAIN function * from the DDG library 1.1 (DAG.cpp). */ -static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) { - int n = nodeset_count(dvg->nodes); - int *assignment = alloca(n * sizeof(assignment[0])); - int *assignment_rev = alloca(n * sizeof(assignment_rev[0])); - int *idx_map = alloca(n * sizeof(idx_map[0])); +static ir_nodeset_t *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) { + int n = ir_nodeset_size(&dvg->nodes); + int *assignment = ALLOCAN(int, n); + int *assignment_rev = ALLOCAN(int, n); + int *idx_map = ALLOCAN(int, n); hungarian_problem_t *bp; - nodeset *values, *temp; + ir_nodeset_t *values, *temp; + ir_nodeset_iterator_t iter; ir_node *u_irn; int i, j, cost, cur_chain, res; rss_edge_t *dvg_edge; @@ -1426,7 +1479,7 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) and build a sorted index map for their irn indices. */ i = 0; - foreach_nodeset(dvg->nodes, u_irn) { + foreach_ir_nodeset(&dvg->nodes, u_irn, iter) { idx_map[i++] = get_irn_idx(u_irn); } qsort(idx_map, n, sizeof(idx_map[0]), cmp_int); @@ -1446,7 +1499,7 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) path in the DVG from u to v, ie. connect all descendants(v) to v. desc_dvg(v) = accumulated descendants of all z in dvg_user_list(v) */ - foreach_nodeset(dvg->nodes, u_irn) { + foreach_ir_nodeset(&dvg->nodes, u_irn, iter) { rss_irn_t *u = get_rss_irn(rss, u_irn); int idx_u_irn = MAP_IDX(u_irn); @@ -1514,7 +1567,8 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) DBG((rss->dbg, LEVEL_3, "\t\t\t%3d -> %3d %3d -> %3d\n", i, assignment[i], i, assignment_rev[i])); } - values = new_nodeset(10); + values = XMALLOC(ir_nodeset_t); + ir_nodeset_init_size(values, 10); cur_chain = 0; /* Construction of the minimal chain partition */ for (j = 0; j < n; ++j) { @@ -1527,7 +1581,7 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) int source; /* there was no source for j -> we have a source of a new chain */ - nodeset_insert(values, xj_irn); + ir_nodeset_insert(values, xj_irn); c->elements = plist_obstack_new(phase_obst(&rss->ph)); c->nr = cur_chain++; @@ -1577,18 +1631,22 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) We need an explicit array for the values as we cannot iterate multiple times over the same set at the same time. :-((((( + TODO Matze: now we can, so rewrite this... */ - int n = nodeset_count(values); + int n = ir_nodeset_size(values); int i = 0; ir_node **val_arr = NEW_ARR_F(ir_node *, n); - foreach_nodeset(values, u_irn) + foreach_ir_nodeset(values, u_irn, iter) val_arr[i++] = u_irn; - if (temp) - del_nodeset(temp); + if (temp) { + ir_nodeset_destroy(temp); + free(temp); + } - temp = new_nodeset(10); + temp = XMALLOC(ir_nodeset_t); + ir_nodeset_init_size(temp, 10); /* Select all nodes from current value set, having another node in the set as descendant. */ for (i = 0; i < n; ++i) { @@ -1603,8 +1661,8 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) if (pset_find(dvg->edges, &key, HASH_RSS_EDGE(&key))) { /* v[j] is descendant of u -> remove u and break */ - nodeset_insert(temp, u->irn); - nodeset_remove(values, u->irn); + ir_nodeset_insert(temp, (ir_node *) u->irn); + ir_nodeset_remove(values, u->irn); DBG((rss->dbg, LEVEL_3, "\t\t\tremoving %+F from values, adding it to temp\n", u->irn)); @@ -1615,7 +1673,7 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) } /* Try to insert the chain predecessor of all selected u's */ - foreach_nodeset(temp, u_irn) { + foreach_ir_nodeset(temp, u_irn, iter) { rss_irn_t *u = get_rss_irn(rss, u_irn); chain_t *c = u->chain; plist_element_t *el = plist_find_value(c->elements, u_irn); @@ -1624,14 +1682,14 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) /* If u has predecessor in chain: insert the predecessor */ if (el == plist_element_get_prev(el)) { - nodeset_insert(values, plist_element_get_value(el)); + ir_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))); } } DEL_ARR_F(val_arr); - } while (nodeset_count(temp) > 0); + } while (ir_nodeset_size(temp) > 0); DBG((rss->dbg, LEVEL_2, "\t\tfinal set:\n")); DEBUG_ONLY( @@ -1643,7 +1701,10 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) if (rss->opts->dump_flags & RSS_DUMP_MAXAC) debug_vcg_dump_pkg(rss, values, iteration); - del_nodeset(temp); + if(temp != NULL) { + ir_nodeset_destroy(temp); + free(temp); + } return values; @@ -1653,11 +1714,11 @@ static nodeset *compute_maximal_antichain(rss_t *rss, dvg_t *dvg, int iteration) /** * Computes the best serialization between two nodes of sat_vals. */ -static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodeset *sat_vals, serialization_t *ser, int num_regs) { - int n = nodeset_count(sat_vals); +static serialization_t *compute_best_admissible_serialization(rss_t *rss, ir_nodeset_t *sat_vals, serialization_t *ser, int num_regs) { + int n = ir_nodeset_size(sat_vals); int n_idx = ARR_LEN_SAFE(rss->idx_map); int i = 0; - ir_node **val_arr = alloca(n * sizeof(val_arr[0])); + ir_node **val_arr = ALLOCAN(ir_node*, n); bitset_t *bs_sv = bitset_alloca(n_idx); bitset_t *bs_vdesc = bitset_alloca(n_idx); bitset_t *bs_tmp = bitset_alloca(n_idx); @@ -1668,10 +1729,11 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese int has_omega1 = 0; int j, k; 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; + ir_nodeset_iterator_t iter; + rss_edge_t min_benefit_edge = {NULL, NULL, NULL}; + rss_edge_t min_omega20_edge = {NULL, NULL, NULL}; + 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")); @@ -1681,7 +1743,7 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese set at the same time. :-((((( */ - foreach_nodeset(sat_vals, irn) { + foreach_ir_nodeset(sat_vals, irn, iter) { val_arr[i++] = irn; bitset_set(bs_sv, BLOCK_IDX_MAP(rss, irn)); } @@ -1750,8 +1812,10 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese /* v cannot be serialized with itself * ignore nodes where serialization does not help */ if (i == j || IS_UNSERIALIZABLE_NODE(v)) { +#ifdef DEBUG_libfirm if (i != j) DBG((rss->dbg, LEVEL_3, "\t\t\t%+F considered unserializable\n", v->irn)); +#endif continue; } @@ -1785,8 +1849,9 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese */ if (add_edge) { - int vv_height = get_irn_height(rss->h, vv_irn); - int mu1, mu2, critical_path_cost; + unsigned vv_height = get_irn_height(rss->h, vv_irn); + unsigned critical_path_cost; + unsigned mu1, mu2; /* mu1 = | descendants(v) cut sat_vals | @@ -1890,17 +1955,17 @@ static serialization_t *compute_best_admissible_serialization(rss_t *rss, nodese static void perform_value_serialization_heuristic(rss_t *rss) { bitset_t *arch_nonign_bs = bitset_alloca(arch_register_class_n_regs(rss->cls)); bitset_t *abi_ign_bs = bitset_alloca(arch_register_class_n_regs(rss->cls)); - int available_regs, iteration, num_live; + unsigned available_regs, iteration; dvg_t dvg; - nodeset *sat_vals; + ir_nodeset_t *sat_vals; pset *ser_set = new_pset(cmp_rss_edges, 20); /* available_regs = R = |arch_non_ignore_regs cut ~abi_ignore_regs| */ - arch_put_non_ignore_regs(rss->arch_env, rss->cls, arch_nonign_bs); + arch_put_non_ignore_regs(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); - //um_live = pset_count(rss->live_block); + //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)); @@ -1910,7 +1975,7 @@ static void perform_value_serialization_heuristic(rss_t *rss) { V = set of all nodes we are currently interested in E_dv = there is an edge from u to v iff v is a descendant of killer(u), forall u, v in V */ - dvg.nodes = new_nodeset(plist_count(rss->nodes)); + ir_nodeset_init_size(&dvg.nodes, plist_count(rss->nodes)); dvg.edges = new_pset(cmp_rss_edges, plist_count(rss->nodes) * 5); compute_dvg(rss, &dvg); @@ -1922,7 +1987,7 @@ static void perform_value_serialization_heuristic(rss_t *rss) { DBG((rss->dbg, LEVEL_1, "\tcomputing maximal antichain:\n")); iteration = 0; sat_vals = compute_maximal_antichain(rss, &dvg, iteration++); - while (sat_vals && (nodeset_count(sat_vals) > available_regs)) { + while (sat_vals && (ir_nodeset_size(sat_vals) > available_regs)) { serialization_t *ser, best_ser; rss_edge_t *edge = obstack_alloc(phase_obst(&rss->ph), sizeof(*edge)); ir_node *dep_src, *dep_tgt; @@ -1930,7 +1995,7 @@ static void perform_value_serialization_heuristic(rss_t *rss) { best_ser.edge = edge; ser = compute_best_admissible_serialization(rss, sat_vals, &best_ser, available_regs); - DBG((rss->dbg, LEVEL_1, "\tcurrent register saturation %d, target %d\n", nodeset_count(sat_vals), available_regs)); + DBG((rss->dbg, LEVEL_1, "\tcurrent register saturation %d, target %d\n", ir_nodeset_size(sat_vals), available_regs)); if (! ser) { DBG((rss->dbg, LEVEL_1, "\tno RS improving serialization found, breaking at iteration %d\n", iteration)); @@ -1950,7 +2015,10 @@ static void perform_value_serialization_heuristic(rss_t *rss) { /* update the dvg */ update_dvg(rss, &dvg, ser->v, ser->u); update_dvg(rss, &dvg, get_rss_irn(rss, ser->edge->src), get_rss_irn(rss, ser->edge->tgt)); - del_nodeset(sat_vals); + if(sat_vals != NULL) { + ir_nodeset_destroy(sat_vals); + free(sat_vals); + } dep_src = skip_Proj(ser->edge->src); dep_tgt = ser->edge->tgt; @@ -1967,7 +2035,7 @@ static void perform_value_serialization_heuristic(rss_t *rss) { sat_vals = compute_maximal_antichain(rss, &dvg, iteration++); } - del_nodeset(dvg.nodes); + ir_nodeset_destroy(&dvg.nodes); del_pset(dvg.edges); } @@ -1979,7 +2047,7 @@ static void process_block(ir_node *block, void *env) { int i, n; const ir_edge_t *edge; - phase_init(&rss->ph, "rss block preprocessor", rss->irg, PHASE_DEFAULT_GROWTH, init_rss_irn); + phase_init(&rss->ph, "rss block preprocessor", rss->irg, PHASE_DEFAULT_GROWTH, init_rss_irn, NULL); DBG((rss->dbg, LEVEL_1, "preprocessing block %+F\n", block)); rss->block = block; @@ -1996,15 +2064,15 @@ static void process_block(ir_node *block, void *env) { rss->max_height = heights_recompute_block(rss->h, block); /* loop over all register classes */ - for (i = arch_isa_get_n_reg_class(rss->arch_env->isa) - 1; i >= 0; --i) { - const arch_register_class_t *cls = arch_isa_get_reg_class(rss->arch_env->isa, i); + for (i = arch_env_get_n_reg_class(rss->arch_env) - 1; i >= 0; --i) { + const arch_register_class_t *cls = arch_env_get_reg_class(rss->arch_env, i); 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); + ir_nodeset_init(&rss->live_block); + be_liveness_end_of_block(rss->liveness, rss->cls, rss->block, &rss->live_block); /* reset the list of interesting nodes */ plist_clear(rss->nodes); @@ -2043,7 +2111,8 @@ static void process_block(ir_node *block, void *env) { 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) { + if (!arch_irn_is_ignore(irn) && + arch_get_irn_reg_class_out(irn) == cls) { plist_insert_back(rss->nodes, skip_Proj(irn)); } //} @@ -2061,49 +2130,47 @@ 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); } -#ifdef WITH_LIBCORE /** * 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); } -#endif /* WITH_LIBCORE */ + +BE_REGISTER_MODULE_CONSTRUCTOR(be_init_schedrss); /** * Preprocess the irg for scheduling. */ -void rss_schedule_preparation(const be_irg_t *birg) { +void rss_schedule_preparation(be_irg_t *birg) { + ir_graph *irg = be_get_birg_irg(birg); rss_t rss; FIRM_DBG_REGISTER(rss.dbg, "firm.be.sched.rss"); //firm_dbg_set_mask(rss.dbg, LEVEL_1 | LEVEL_2 | LEVEL_3); - init_rss_special_nodes(birg->irg); + init_rss_special_nodes(irg); - rss.irg = birg->irg; - rss.arch_env = birg->main_env->arch_env; + rss.irg = irg; + rss.arch_env = be_get_birg_arch_env(birg); rss.abi = birg->abi; - rss.h = heights_new(birg->irg); + rss.h = heights_new(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); + rss.liveness = be_liveness(irg); + be_liveness_assure_sets(rss.liveness); + irg_block_walk_graph(irg, NULL, process_block, &rss); heights_free(rss.h); plist_free(rss.nodes); be_liveness_free(rss.liveness);