236 lines
4.6 KiB
C
236 lines
4.6 KiB
C
|
/* 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;
|
||
|
}
|
||
|
}
|
||
|
}
|