Pristine Ack-5.5
[Ack-5.5.git] / util / ego / ra / ra_profits.c
1 /* $Id: ra_profits.c,v 1.12 1994/06/24 10:28:03 ceriel Exp $ */
2 /*
3  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
4  * See the copyright notice in the ACK home directory, in the file "Copyright".
5  */
6 /*  R E G I S T E R   A L L O C A T I O N
7  *
8  *  R A _ P R O F I T S . C
9  */
10
11 #include <stdio.h>
12 #include <em_reg.h>
13 #include "../share/types.h"
14 #include "../share/debug.h"
15 #include "../share/lset.h"
16 #include "../share/global.h"
17 #include "ra.h"
18 #include "ra_aux.h"
19 #include "ra_profits.h"
20
21 STATIC bool test_cond(cond,val)
22         short cond;
23         offset val;
24 {
25         switch(cond) {
26                 case DEFAULT:
27                         return TRUE;
28                 case FITBYTE:
29                         return val >= -128 && val < 128;
30                 case IN_0_63:
31                         return val >= 0 && val <= 63;
32                 case IN_0_8:
33                         return val >= 0 && val <= 8;
34         }
35 }
36
37 STATIC short map_value(tab,val,time)
38         struct cond_tab tab[];
39         offset val;
40         bool time;
41 {
42         cond_p p;
43
44         for (p = &tab[0]; ; p++) {
45                 if (test_cond(p->mc_cond,val)) {
46                         return (time ? p->mc_tval : p->mc_sval);
47                 }
48         }
49 }
50
51
52 STATIC short index_value(tab,n,time)
53         struct cond_tab tab[];
54         short n;
55         bool time;
56 {
57         cond_p p;
58
59         p = &tab[n]; 
60         return (time ? p->mc_tval : p->mc_sval);
61 }
62
63
64 allocscore(itemtyp,localtyp,size,off,totyp,time_out,space_out) 
65         short itemtyp, localtyp,totyp,size;
66         offset off;
67         short *time_out, *space_out;
68 {
69         cond_p m = (cond_p) 0;
70
71         if (localtyp == reg_loop) localtyp = reg_any;
72         if (size == ws || size ==ps && totyp == reg_pointer) {
73                 switch(itemtyp) {
74                    case LOCALVAR:
75                         m = alocaltab[localtyp][totyp];
76                         break;
77                    case LOCAL_ADDR:
78                         if (use_any_as_pointer || totyp == reg_pointer)
79                                 m = alocaddrtab[localtyp][totyp];
80                         break;
81                    case CONST:
82                         m = aconsttab;
83                         break;
84                    case DCONST:
85                         m = aconsttab;
86                         break;
87                    case GLOBL_ADDR:
88                         if (use_any_as_pointer || totyp == reg_pointer)
89                                 m = aglobaltab;
90                         break;
91                    case PROC_ADDR:
92                         if (use_any_as_pointer || totyp == reg_pointer)
93                                 m = aproctab;
94                         break;
95                 }
96         }
97         *time_out = (m == (cond_p) 0 ? -1 : map_value(m,off,TRUE));
98         *space_out = (m == (cond_p) 0 ? -1 : map_value(m,off,FALSE));
99         /*
100         fprintf(stderr,"itemtyp = %d, localtyp = %d off = %ld\n",itemtyp,localtyp,off);
101         fprintf(stderr,"ALLOCSCORE = (%d,%d)\n",*time_out,*space_out);
102         */
103 }
104
105 opening_cost(itemtyp,localtyp,off,time_out,space_out) 
106         short itemtyp, localtyp;
107         offset off;
108         short *time_out, *space_out;
109 {
110         cond_p m;
111
112         if (localtyp == reg_loop) localtyp = reg_any;
113         switch(itemtyp) {
114            case LOCALVAR:
115                 m = olocaltab[localtyp];
116                 break;
117            case LOCAL_ADDR:
118                 m = olocaddrtab[localtyp];
119                 break;
120            case CONST:
121                 m = oconsttab;
122                 break;
123            case DCONST:
124                 m = oconsttab;
125                 break;
126            case GLOBL_ADDR:
127                 m = oglobaltab;
128                 break;
129            case PROC_ADDR:
130                 m = oproctab;
131                 break;
132         }
133         *time_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,TRUE));
134         *space_out = (m == (cond_p) 0 ? 1000 : map_value(m,off,FALSE));
135         /*
136         fprintf(stderr,"itemtyp = %d, localtyp = %d off = %ld\n",itemtyp,localtyp,off);
137         fprintf(stderr,"OPEN_COST = (%d,%d)\n",*time_out,*space_out);
138         */
139 }
140
141
142
143
144 regsave_cost(regs,time_out,space_out)
145         short regs[], *time_out, *space_out;
146 {
147         /* Estimate the costs of saving and restoring the registers
148          * The array regs contains the number of registers of every
149          * possible type.
150          */
151
152         short n = regs[reg_any] + regs[reg_pointer] + regs[reg_float]; 
153         /* #registers */
154
155         *time_out = index_value(regsav_cost,n,TRUE);
156         *space_out = index_value(regsav_cost,n,FALSE);
157         /*
158         fprintf(stderr,"REGSAVE COST, n=%d, (%d,%d)\n",n,*time_out,*space_out);
159         */
160 }
161
162
163
164 STATIC short dyn_inits(inits)
165         lset inits;
166 {
167         Lindex i;
168         short sum = 0;
169         bblock_p b;
170
171         for (i = Lfirst(inits); i != (Lindex) 0; i = Lnext(i,inits)) {
172                 b = (bblock_p) Lelem(i);
173                 sum += loop_scale(Lnrelems(b->b_loops));
174         }
175         return sum;
176 }
177
178
179
180 compute_profits(alloclist,time_opt)
181         alloc_p alloclist;
182         bool time_opt;
183 {
184         /* Compute the profits attribute of every allocation.
185          * If the item of an allocation may be put in several types
186          * of register, we choose only the most advanteagous one.
187          */
188
189         register alloc_p alloc;
190         short s,t,rtyp,maxsc;
191         item_p item;
192         short time,space,sc;
193         short otime,ospace;
194         offset off;
195         short cnt,nr_inits;
196
197         for (alloc = alloclist; alloc != (alloc_p) 0; alloc = alloc->al_next) {
198                 maxsc = 0;
199                 item = alloc->al_item;
200                 switch(item->it_type) {
201                         case LOCALVAR:
202                         case LOCAL_ADDR:
203                         case CONST:
204                         case DCONST:
205                                 off = item->i_t.it_off;
206                                 break;
207                         default:
208                                 off = 0;
209                 }
210                 for (rtyp = item->it_regtype; ; rtyp = reg_any) {
211                         allocscore(     item->it_type,
212                                         item->it_regtype,
213                                         item->it_size,
214                                         off,
215                                         rtyp,
216                                         &time,
217                                         &space);
218                         opening_cost(   item->it_type,
219                                         item->it_regtype,
220                                         off,
221                                         &otime,
222                                         &ospace);
223                         nr_inits = Lnrelems(alloc->al_inits);
224                         s = alloc->al_susecount * space - 
225                                 nr_inits*ospace;
226 #ifdef __STRANGE__
227                         if (!alloc->al_isloop && nr_inits > 0) {
228                                 /* might lead to increase of execution time */
229                                 cnt = 0;
230                         } else
231 #endif
232                         {
233                                 cnt = alloc->al_dusecount;
234                         }
235                         t = cnt * time - dyn_inits(alloc->al_inits) * otime;
236                         sc = (time_opt ? t : s);
237                         /*
238                         fprintf(stderr, "cnt: %d time: %d otime: %d t: %d s: %d score: %d\n", cnt, time, otime, t, s, sc);
239                         */
240                         if (sc > maxsc) {
241                                 maxsc = sc;
242                                 alloc->al_regtype = rtyp;
243                                 alloc->al_profits = sc;
244                         }
245                         if (rtyp == reg_any) break;
246                 }
247         }
248 }