/* update bb and life_info after spilling * this saves 4 costy routines * NOTE {lhs_,}use_count are not set again, this is save, when no * further optimization pass follows * */ static void update_life(Parrot_Interp interpreter, IMC_Unit * unit, Instruction *ins, SymReg *r, int needs_fetch, int needs_store, int add) { Life_range *l; int i; Instruction *ins2; Basic_block **bb_list = unit->bb_list; #if IMC_TRACE fprintf(stderr, "reg_alloc.c: update_life(%s)\n", r->name); #endif for (i = 0, ins2 = unit->instructions; ins2; ins2 = ins2->next) { ins2->index = i++; } /* add this sym to reglist, if not there */ if (add) { unit->reglist = realloc(unit->reglist, (n_symbols + 1) * sizeof(SymReg *)); unit->reglist[n_symbols++] = r; } r->first_ins = r->last_ins = ins; if (needs_fetch) { /* prev instructions is a fetch then and the first usage of this reg */ r->first_ins = ins->prev; /* if this ins was the first of a BB, then the fetch is the * first ins then */ if (ins == bb_list[ins->bbindex]->start) bb_list[ins->bbindex]->start = ins->prev; } if (needs_store) { /* next ins is a store then, and ends life of this reg */ r->last_ins = ins->next; if (ins == bb_list[ins->bbindex]->end) bb_list[ins->bbindex]->end = ins->next; } /* now set life_info */ free_life_info(unit, r); r->life_info = calloc(unit->n_basic_blocks, sizeof(Life_range*)); for (i=0; i < unit->n_basic_blocks; i++) make_life_range(r, i); l = r->life_info[ins->bbindex]; l->first_ins = r->first_ins; l->last_ins = r->last_ins; if (IMCC_INFO(interpreter)->debug & DEBUG_IMC) { dump_instructions(unit); dump_symreg(unit); } }
void backend_shader::dump_instructions() { dump_instructions(NULL); }
/* imc_reg_alloc is the main loop of the allocation algorithm. It operates * on a single compilation unit at a time. */ void imc_reg_alloc(struct Parrot_Interp *interpreter, IMC_Unit * unit) { int to_spill; int todo, first; if (!unit) return; if (!optimizer_level && pasm_file) return; init_tables(interpreter); allocated = 0; #if IMC_TRACE fprintf(stderr, "reg_alloc.c: imc_reg_alloc\n"); if (unit->instructions->r[1] && unit->instructions->r[1]->pcc_sub) { fprintf(stderr, "img_reg_alloc: pcc_sub (nargs = %d)\n", unit->instructions->r[1]->pcc_sub->nargs); } #endif debug(interpreter, DEBUG_IMC, "\n------------------------\n"); debug(interpreter, DEBUG_IMC, "processing sub %s\n", function); debug(interpreter, DEBUG_IMC, "------------------------\n\n"); if (IMCC_INFO(interpreter)->verbose || (IMCC_INFO(interpreter)->debug & DEBUG_IMC)) imc_stat_init(unit); /* consecutive labels, if_branch, unused_labels ... */ pre_optimize(interpreter, unit); if (optimizer_level == OPT_PRE && pasm_file) return; nodeStack = imcstack_new(); unit->n_spilled = 0; todo = first = 1; while (todo) { find_basic_blocks(interpreter, unit, first); build_cfg(interpreter, unit); if (first && (IMCC_INFO(interpreter)->debug & DEBUG_CFG)) dump_cfg(unit); first = 0; todo = cfg_optimize(interpreter, unit); } todo = first = 1; while (todo) { if (!first) { find_basic_blocks(interpreter, unit, 0); build_cfg(interpreter, unit); } first = 0; compute_dominators(interpreter, unit); find_loops(interpreter, unit); build_reglist(interpreter, unit); life_analysis(interpreter, unit); /* optimize, as long as there is something to do */ if (dont_optimize) todo = 0; else { todo = optimize(interpreter, unit); if (todo) pre_optimize(interpreter, unit); } } todo = 1; #if !DOIT_AGAIN_SAM build_interference_graph(interpreter, unit); #endif while (todo) { #if DOIT_AGAIN_SAM build_interference_graph(interpreter, unit); #endif if (optimizer_level & OPT_SUB) allocate_wanted_regs(unit); compute_spilling_costs(interpreter, unit); #ifdef DO_SIMPLIFY /* simplify until no changes can be made */ while (simplify(unit)) {} #endif order_spilling(unit); /* put the remaining items on stack */ to_spill = try_allocate(interpreter, unit); allocated = 1; if ( to_spill >= 0 ) { allocated = 0; spill(interpreter, unit, to_spill); /* * build the new cfg/reglist on the fly in spill() and * do life analysis there for only the involved regs */ #if DOIT_AGAIN_SAM find_basic_blocks(interpreter, unit, 0); build_cfg(interpreter, unit); build_reglist(interpreter, unit); life_analysis(interpreter); #endif } else { /* the process is finished */ todo = 0; } } if (optimizer_level & OPT_SUB) sub_optimize(interpreter, unit); if (IMCC_INFO(interpreter)->debug & DEBUG_IMC) dump_instructions(unit); if (IMCC_INFO(interpreter)->verbose || (IMCC_INFO(interpreter)->debug & DEBUG_IMC)) print_stat(interpreter, unit); imcstack_free(nodeStack); }