/* R E G I S T E R A L L O C A T I O N * * R A _ P R O F I T S . C */ #include "../share/types.h" #include "../share/debug.h" #include "../share/lset.h" #include "../share/global.h" #include "../../../h/em_reg.h" #include "ra.h" #include "ra_aux.h" #include "ra_profits.h" STATIC bool test_cond(cond,val) short cond; offset val; { switch(cond) { case DEFAULT: return TRUE; case FITBYTE: return val >= -128 && val < 128; case IN_0_63: return val >= 0 && val <= 63; case IN_0_8: return val >= 0 && val <= 8; } } STATIC short map_value(tab,val,time) struct cond_tab tab[]; offset val; bool time; { cond_p p; for (p = &tab[0]; ; p++) { if (test_cond(p->mc_cond,val)) { return (time ? p->mc_tval : p->mc_sval); } } } STATIC short index_value(tab,n,time) struct cond_tab tab[]; short n; bool time; { cond_p p; p = &tab[n]; return (time ? p->mc_tval : p->mc_sval); } allocscore(itemtyp,localtyp,size,off,totyp,time_out,space_out) short itemtyp, localtyp,totyp,size; offset off; short *time_out, *space_out; { cond_p m; if (localtyp == reg_loop) localtyp = reg_any; if (size == ws || size ==ps && totyp == reg_pointer) { switch(itemtyp) { case LOCALVAR: m = alocaltab[localtyp][totyp]; break; case LOCAL_ADDR: m = alocaddrtab[localtyp][totyp]; break; case CONST: m = aconsttab; break; case DCONST: m = aconsttab; break; case GLOBL_ADDR: m = aglobaltab; break; case PROC_ADDR: m = aproctab; break; } } else { m = (cond_p) 0; } *time_out = (m == (cond_p) 0 ? -1 : map_value(m,off,TRUE)); *space_out = (m == (cond_p) 0 ? -1 : map_value(m,off,FALSE)); /* printf("itemtyp = %d, localtyp = %d off = %D\n",itemtyp,localtyp,off); printf("ALLOCSCORE = (%d,%d)\n",*time_out,*space_out); */ } opening_cost(itemtyp,localtyp,off,time_out,space_out) short itemtyp, localtyp; offset off; short *time_out, *space_out; { cond_p m; if (localtyp == reg_loop) localtyp = reg_any; switch(itemtyp) { case LOCALVAR: m = olocaltab[localtyp]; break; case LOCAL_ADDR: m = olocaddrtab[localtyp]; break; case CONST: m = oconsttab; break; case DCONST: m = oconsttab; break; case GLOBL_ADDR: m = oglobaltab; break; case PROC_ADDR: m = oproctab; break; } *time_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,TRUE)); *space_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,FALSE)); /* printf("itemtyp = %d, localtyp = %d off = %D\n",itemtyp,localtyp,off); printf("OPEN_COST = (%d,%d)\n",*time_out,*space_out); */ } short regsave_cost(regs,time_out,space_out) short regs[], *time_out, *space_out; { /* Estimate the costs of saving and restoring the registers * The array regs contains the number of registers of every * possible type. */ short n = regs[reg_any] + regs[reg_pointer] + regs[reg_float]; /* #registers */ *time_out = index_value(regsav_cost,n,TRUE); *space_out = index_value(regsav_cost,n,FALSE); /* printf("REGSAVE COST, n=%d, (%d,%d)\n",n,*time_out,*space_out); */ } STATIC short dyn_inits(inits) lset inits; { Lindex i; short sum = 0; bblock_p b; for (i = Lfirst(inits); i != (Lindex) 0; i = Lnext(i,inits)) { b = (bblock_p) Lelem(i); sum += loop_scale(Lnrelems(b->b_loops)); } return sum; } compute_profits(alloclist,time_opt) alloc_p alloclist; bool time_opt; { /* Compute the profits attribute of every allocation. * If the item of an allocation may be put in several types * of register, we choose only the most advanteagous one. */ register alloc_p alloc; short s,t,rtyp,maxsc; item_p item; short time,space,sc; short otime,ospace; offset off; short cnt,nr_inits; for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) { maxsc = 0; item = alloc->al_item; switch(item->it_type) { case LOCALVAR: case LOCAL_ADDR: case CONST: case DCONST: off = item->i_t.it_off; break; default: off = 0; } for (rtyp = item->it_regtype; ; rtyp = reg_any) { allocscore( item->it_type, item->it_regtype, item->it_size, off, rtyp, &time, &space); opening_cost( item->it_type, item->it_regtype, off, &otime, &ospace); nr_inits = Lnrelems(alloc->al_inits); s = alloc->al_susecount * space - nr_inits*ospace; if (!alloc->al_isloop && nr_inits > 0) { /* might lead to increase of execution time */ cnt = 0; } else { cnt = alloc->al_dusecount; } t = cnt * time - dyn_inits(alloc->al_inits) * otime; sc = (time_opt ? t : s); if (sc >= maxsc) { maxsc = sc; alloc->al_regtype = rtyp; alloc->al_profits = sc; } if (rtyp == reg_any) break; } } }