123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /* $Id$ */
- /*
- * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* 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>
- #include <em_reg.h>
- #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)
- {
- 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;
- }
- return FALSE;
- }
- static short map_value(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);
- }
- }
- return 0;
- }
- static short index_value(struct cond_tab tab[], short n, bool time)
- {
- 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)
- {
- cond_p m = (cond_p) 0;
- 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:
- if (use_any_as_pointer || totyp == reg_pointer)
- m = alocaddrtab[localtyp][totyp];
- break;
- case CONST:
- m = aconsttab;
- break;
- case DCONST:
- m = aconsttab;
- break;
- case GLOBL_ADDR:
- if (use_any_as_pointer || totyp == reg_pointer)
- m = aglobaltab;
- break;
- case PROC_ADDR:
- if (use_any_as_pointer || totyp == reg_pointer)
- m = aproctab;
- 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);
- */
- }
- static void opening_cost(short itemtyp, short localtyp, offset off,
- short *time_out, short *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));
- /*
- fprintf(stderr,"itemtyp = %d, localtyp = %d off = %ld\n",itemtyp,localtyp,off);
- fprintf(stderr,"OPEN_COST = (%d,%d)\n",*time_out,*space_out);
- */
- }
- void regsave_cost(short regs[], short *time_out, short *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);
- /*
- fprintf(stderr,"REGSAVE COST, n=%d, (%d,%d)\n",n,*time_out,*space_out);
- */
- }
- static short dyn_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)
- {
- /* 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.
- */
- 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;
- #ifdef __STRANGE__
- if (!alloc->al_isloop && nr_inits > 0) {
- /* might lead to increase of execution time */
- cnt = 0;
- } else
- #endif
- {
- 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) {
- maxsc = sc;
- alloc->al_regtype = rtyp;
- alloc->al_profits = sc;
- }
- if (rtyp == reg_any) break;
- }
- }
- }
|