X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fbe%2Fbeschednormal.c;h=842c332442124603991b10d41e217078545ce46e;hb=9eeb2b41dc3c1fe19973b57b5454d651f95424e6;hp=fb131a4ac3044d3d55989007949fe7a5c43ec57c;hpb=c64c36899c2f0d04e82ff1e2223ff41efe2efdfa;p=libfirm diff --git a/ir/be/beschednormal.c b/ir/be/beschednormal.c index fb131a4ac..842c33244 100644 --- a/ir/be/beschednormal.c +++ b/ir/be/beschednormal.c @@ -43,9 +43,8 @@ /** An instance of the normal scheduler. */ typedef struct instance_t { ir_graph* irg; /**< the IR graph of this instance */ - heights_t* heights; /**< height for the graph of this instance */ struct obstack obst; /**< obstack for temporary data */ - ir_node*** block_lists; /**< list of all block scheduling list */ + ir_node* curr_list; /**< current block schedule list */ } instance_t; static int must_be_scheduled(const ir_node* const irn) @@ -57,31 +56,30 @@ static int must_be_scheduled(const ir_node* const irn) static ir_node *normal_select(void *block_env, ir_nodeset_t *ready_set, ir_nodeset_t *live_set) { + instance_t* inst = block_env; + ir_node* irn; + ir_node* next; + ir_node* last = NULL; ir_nodeset_iterator_t iter; - ir_node* block; - ir_node* irn; - ir_node** sched; - int sched_count; - (void)block_env; (void)live_set; - ir_nodeset_iterator_init(&iter, ready_set); - irn = ir_nodeset_iterator_next(&iter); - block = get_nodes_block(irn); - sched = get_irn_link(block); - sched_count = ARR_LEN(sched); - for (; sched_count-- != 0; ++sched) { - ir_node* irn = *sched; - if (ir_nodeset_contains(ready_set, irn) && - !arch_irn_class_is(irn, branch)) { + for (irn = inst->curr_list; irn != NULL; last = irn, irn = next) { + next = get_irn_link(irn); + if (ir_nodeset_contains(ready_set, irn)) { #if defined NORMAL_DBG ir_fprintf(stderr, "scheduling %+F\n", irn); #endif + if (last == NULL) + inst->curr_list = next; + else + set_irn_link(last, next); return irn; } } + ir_nodeset_iterator_init(&iter, ready_set); + irn = ir_nodeset_iterator_next(&iter); return irn; } @@ -305,9 +303,8 @@ static int root_cmp(const void* a, const void* b) static void normal_sched_block(ir_node* block, void* env) { - instance_t* inst = env; ir_node** roots = get_irn_link(block); - heights_t* heights; + heights_t* heights = env; int root_count; irn_cost_pair* root_costs; int i; @@ -324,7 +321,6 @@ static void normal_sched_block(ir_node* block, void* env) return; } - heights = inst->heights; root_count = ARR_LEN(roots); NEW_ARR_A(irn_cost_pair, root_costs, root_count); for (i = 0; i < root_count; ++i) { @@ -354,9 +350,8 @@ static void normal_sched_block(ir_node* block, void* env) assert(must_be_scheduled(irn)); sched = sched_node(sched, irn); } - DEL_ARR_F(roots); set_irn_link(block, sched); - ARR_APP1(ir_node**, inst->block_lists, sched); + DEL_ARR_F(roots); #if defined NORMAL_DBG { @@ -376,8 +371,9 @@ static void normal_sched_block(ir_node* block, void* env) static void *normal_init_graph(const list_sched_selector_t *vtab, const be_irg_t *birg) { - instance_t *inst = XMALLOC(instance_t); - ir_graph *irg = be_get_birg_irg(birg); + instance_t* inst = XMALLOC(instance_t); + ir_graph* irg = be_get_birg_irg(birg); + heights_t* heights; (void)vtab; @@ -385,31 +381,49 @@ static void *normal_init_graph(const list_sched_selector_t *vtab, obstack_init(&inst->obst); inst->irg = irg; - inst->heights = heights_new(irg); - inst->block_lists = NEW_ARR_F(ir_node**, 0); + + heights = heights_new(irg); ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK); irg_walk_graph(irg, normal_cost_walker, NULL, inst); irg_walk_graph(irg, collect_roots, NULL, NULL); inc_irg_visited(irg); ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED); - irg_block_walk_graph(irg, normal_sched_block, NULL, inst); + irg_block_walk_graph(irg, normal_sched_block, NULL, heights); ir_free_resources(irg, IR_RESOURCE_IRN_VISITED); - heights_free(inst->heights); + heights_free(heights); + + return inst; +} +static void *normal_init_block(void *graph_env, ir_node *block) +{ + instance_t* inst = graph_env; + ir_node** sched = get_irn_link(block); + ir_node* first = NULL; + int i; + + /* turn into a list, so we can easily remove nodes. + The link field is used anyway. */ + for (i = ARR_LEN(sched) - 1; i >= 0; --i) { + ir_node* irn = sched[i]; + if (!arch_irn_class_is(irn, branch)) { + set_irn_link(irn, first); + first = irn; + } + } + /* note: we can free sched here, there should be no attempt to schedule + a block twice */ + DEL_ARR_F(sched); + set_irn_link(block, sched); + inst->curr_list = first; return inst; } void normal_finish_graph(void *env) { instance_t *inst = env; - int i; - - for (i = ARR_LEN(inst->block_lists) - 1; i >= 0; --i) { - DEL_ARR_F(inst->block_lists[i]); - } - DEL_ARR_F(inst->block_lists); /* block uses the link field to store the schedule */ ir_free_resources(inst->irg, IR_RESOURCE_IRN_LINK); @@ -419,7 +433,7 @@ void normal_finish_graph(void *env) const list_sched_selector_t normal_selector = { normal_init_graph, - NULL, /* init_block */ + normal_init_block, normal_select, NULL, /* to_appear_in_schedule */ NULL, /* node_ready */