ack/util/ego/ra/ra_profits.c

237 lines
5.1 KiB
C
Raw Normal View History

1994-06-24 11:31:16 +00:00
/* $Id$ */
1987-03-09 19:15:41 +00:00
/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
1984-11-26 14:35:32 +00:00
/* 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 <stdio.h>
1991-03-05 12:44:05 +00:00
#include <em_reg.h>
1984-11-26 14:35:32 +00:00
#include "../share/types.h"
#include "../share/debug.h"
#include "../share/lset.h"
#include "../share/global.h"
#include "ra.h"
#include "ra_aux.h"
#include "ra_profits.h"
STATIC bool test_cond(short cond, offset val)
1984-11-26 14:35:32 +00:00
{
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(struct cond_tab tab[], offset val, bool time)
1984-11-26 14:35:32 +00:00
{
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(struct cond_tab tab[], short n, bool time)
1984-11-26 14:35:32 +00:00
{
cond_p p;
p = &tab[n];
return (time ? p->mc_tval : p->mc_sval);
}
STATIC void
allocscore(short itemtyp, short localtyp, short size, offset off,
short totyp, short *time_out, short *space_out)
1984-11-26 14:35:32 +00:00
{
1989-03-07 10:24:32 +00:00
cond_p m = (cond_p) 0;
1984-11-26 14:35:32 +00:00
if (localtyp == reg_loop) localtyp = reg_any;
if (size == ws || (size == ps && totyp == reg_pointer) ||
(size == 2 * ws && totyp == reg_float)) {
1984-11-26 14:35:32 +00:00
switch(itemtyp) {
case LOCALVAR:
m = alocaltab[localtyp][totyp];
break;
case LOCAL_ADDR:
1989-03-07 10:24:32 +00:00
if (use_any_as_pointer || totyp == reg_pointer)
m = alocaddrtab[localtyp][totyp];
1984-11-26 14:35:32 +00:00
break;
case CONST:
m = aconsttab;
break;
case DCONST:
m = aconsttab;
break;
case GLOBL_ADDR:
1989-03-07 10:24:32 +00:00
if (use_any_as_pointer || totyp == reg_pointer)
m = aglobaltab;
1984-11-26 14:35:32 +00:00
break;
case PROC_ADDR:
1989-03-07 10:24:32 +00:00
if (use_any_as_pointer || totyp == reg_pointer)
m = aproctab;
1984-11-26 14:35:32 +00:00
break;
}
}
*time_out = (m == (cond_p) 0 ? -1 : map_value(m,off,TRUE));
*space_out = (m == (cond_p) 0 ? -1 : map_value(m,off,FALSE));
/*
fprintf(stderr,"itemtyp = %d, localtyp = %d off = %ld\n",itemtyp,localtyp,off);
fprintf(stderr,"ALLOCSCORE = (%d,%d)\n",*time_out,*space_out);
1984-11-26 14:35:32 +00:00
*/
}
STATIC void
opening_cost(short itemtyp, short localtyp, offset off,
short *time_out, short *space_out)
1984-11-26 14:35:32 +00:00
{
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));
/*
fprintf(stderr,"itemtyp = %d, localtyp = %d off = %ld\n",itemtyp,localtyp,off);
fprintf(stderr,"OPEN_COST = (%d,%d)\n",*time_out,*space_out);
1984-11-26 14:35:32 +00:00
*/
}
void regsave_cost(short regs[], short *time_out, short *space_out)
1984-11-26 14:35:32 +00:00
{
/* 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);
/*
fprintf(stderr,"REGSAVE COST, n=%d, (%d,%d)\n",n,*time_out,*space_out);
1984-11-26 14:35:32 +00:00
*/
}
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;
}
void compute_profits(alloc_p alloclist, bool time_opt)
1984-11-26 14:35:32 +00:00
{
/* 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;
1990-08-01 14:34:53 +00:00
#ifdef __STRANGE__
1984-11-26 14:35:32 +00:00
if (!alloc->al_isloop && nr_inits > 0) {
/* might lead to increase of execution time */
cnt = 0;
1990-08-01 14:34:53 +00:00
} else
#endif
{
1984-11-26 14:35:32 +00:00
cnt = alloc->al_dusecount;
}
t = cnt * time - dyn_inits(alloc->al_inits) * otime;
sc = (time_opt ? t : s);
/*
fprintf(stderr, "cnt: %d time: %d otime: %d t: %d s: %d score: %d\n", cnt, time, otime, t, s, sc);
*/
if (sc > maxsc) {
1984-11-26 14:35:32 +00:00
maxsc = sc;
alloc->al_regtype = rtyp;
alloc->al_profits = sc;
}
if (rtyp == reg_any) break;
}
}
}