Initial revision
[cacao.git] / comp / var.c
1 /****************************** comp/var.c *************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         verwaltet die Pseudoregister (die ich manchmal auch einfach nur
8         'Variablen'  nenne, daher der Namen des Programmteiles)
9
10         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
11
12         Last Change: 1996/11/14
13
14 *******************************************************************************/
15
16
17 s4 varnum;                /* Anzahl der bereits vergebenen Variablen 
18                              (eigentlich nur, um den Variablen forlaufende
19                              Nummern zu geben, damit man sie beim Debuggen
20                              eindeutig kennzeichnen kann) */
21
22 list copiedvars;          /* Liste aller Variablen die nur eine Kopie einer 
23                              anderen Variablen sind (w"ahrend der 
24                              Parse-Phase notwendig) */
25 list activevars;          /* Liste aller gerade aktiven Variablen 
26                                                      (f"ur die Registerbelegungs-phase notwendig) */
27                                                       
28 list vars;                /* Liste aller Variablen, die nicht in einer der
29                              obigen Listen sind */
30
31
32 /********************** Funktion: var_init ************************************
33
34         initialisiert die Listen und den Variablen-Index-Z"ahler
35
36 ******************************************************************************/
37
38 static void var_init ()
39 {
40         varnum = maxlocals;
41         list_init (&vars, OFFSET (varinfo, linkage) );
42         list_init (&copiedvars, OFFSET (varinfo, linkage) );
43         list_init (&activevars, OFFSET (varinfo, linkage) );
44 }
45
46
47 /********************* Funktion: var_type *************************************
48
49         Liefert den JavaVM-Grundtyp einer Variablen
50
51 ******************************************************************************/
52
53 static u2 var_type (varid v)
54 {
55         return v->type;
56 }
57
58
59 /********************* Funktion: var_create ***********************************
60
61         Erzeugt eine neue Variable des gew"unschten Typs
62         
63 ******************************************************************************/
64
65 static varid var_create (u2 type)
66 {
67         varinfo *v = DNEW (varinfo);
68
69         list_addlast (&vars, v);
70         
71         list_init (&(v -> copies), OFFSET (varinfo, copylink) );
72         v -> original = v;
73         
74         v -> type = type;
75         v -> number = varnum++;
76         v -> active = false;
77         v -> globalscope = false;
78         v -> saved = false;
79
80         v -> reg = NULL;
81         
82         return v;
83 }
84
85
86 /***************** Funktion: var_createwithspecialnumber **********************
87
88         Erzeugt eine neue Variable des gew"unschten Typs, dabei wird aber als
89         Kennzeichnungsnummer eine vorgegebene Zahl verwendet (das brauche ich
90         um die lokalen Java-Variablen mit der Nummer des ihres Slots zu 
91         kennzeichnen).
92         
93 ******************************************************************************/
94
95 static varid var_createwithspecialnumber(u2 type, u4 num)
96 {
97         varinfo *v = var_create (type);
98         varnum--;
99         v -> number = num;
100         return v;
101 }
102
103
104 /*************** Funktion: var_makesaved **************************************
105
106         Kennzeichnet eine Variable daf"ur, dass sie bei Methodenaufrufen nicht
107         zerst"ort werden darf.
108         
109 ******************************************************************************/
110
111 static void var_makesaved (varid v)
112 {
113         v -> saved = true;
114         v -> reg = NULL;
115 }
116
117
118 /*************** Funktion: var_proposereg *************************************
119
120         Macht dem Regiserallokator einen Vorschlag, mit welchem Register
121         eine Variable belegt werden sollte (bei Methodenaufrufen k"onnen so
122         viele Umlade-Befehle in die Argumentregister vermieden werden).
123         Aber: Die Anforderung, dass ein Register gesichert sein soll, hat auf
124                 jeden Fall Priorit"at "uber so einen Vorschlag.
125         
126 ******************************************************************************/
127
128 static void var_proposereg (varid v, reginfo *r)
129 {
130         if (v -> saved) return;
131         
132         v -> reg = r;
133 }
134
135
136 /******************** Funktion: var_makecopy **********************************
137
138         kennzeichnet eine Variable daf"ur, dass sie nur eine Kopie einer anderen
139         Variable enth"alt. 
140
141 ******************************************************************************/
142
143 static void var_makecopy (varid original, varid copy)
144 {
145         list_addlast (&(original->copies), copy);
146         copy -> original = original;
147         
148         list_remove (&vars, copy);
149         list_addlast (&copiedvars, copy);
150 }
151
152
153 /******************** Funktion: var_unlinkcopy ********************************
154
155         eine Variable, die bis jetzt in der Liste der Kopien eingetragen
156         war, wird wieder auf normalen Zustand gebracht.
157         
158 ******************************************************************************/
159
160 static void var_unlinkcopy (varid copy)
161 {
162         list_remove (&(copy->original->copies), copy);
163         copy -> original = copy;
164         
165         list_remove (&copiedvars, copy);
166         list_addlast (&vars, copy);
167 }
168
169
170 /******************* Funktion: var_isoriginal *********************************
171
172         Liefert true, wenn die Variable selber das Original ist, und keine
173         Kopie einer anderen Variablen (das heisst, wenn sie nicht in der Liste
174         der Kopien eingetragen ist)
175         
176 ******************************************************************************/
177
178 static bool var_isoriginal (varid copy)
179 {
180         return (copy -> original == copy) ? true : false;
181 }
182
183
184 /******************* Funktion: var_findoriginal *******************************
185
186         Sucht zu einer Variablen das Original (wenn die Variable eine Kopie ist),
187         oder gibt die Variable selbst zur"uck (im anderen Fall).
188         
189 ******************************************************************************/
190
191 static varid var_findoriginal (varid v)
192 {
193         return v->original;
194 }
195
196
197 /******************* Funktion: var_nextcopy ***********************************
198
199         Gibt die erste noch eingetragene Kopie einer Variablen zur"uck.
200         (oder NILL, wenn die Variable keine Kopien hat)
201         
202 ******************************************************************************/
203
204 static varid var_nextcopy (varid original) 
205 {
206         return list_first (&original->copies);
207 }
208
209
210 /******************* Funktion: var_nextcopiedvar ******************************
211
212         Gibt die erste "uberhaupt noch vorhandene Variable zu"uck, die eine
213         Kopie irgendeiner anderen Variablen ist.
214         
215 ******************************************************************************/
216
217 static varid var_nextcopiedvar ()
218 {
219         return list_first (&copiedvars);
220 }
221
222
223
224 /*********************** Funktion: var_isactive *******************************
225
226         Lieftert true, wenn die Variable gerade aktiviert ist (d.h., wenn 
227         irgendwann vorher 'var_activate' aufgerufen wurde) 
228
229 ******************************************************************************/
230
231 static bool var_isactive (varinfo *v)
232 {
233         return v->active;
234 }
235
236
237 /******************** Funktion: var_activate **********************************
238
239         Aktiviert eine Variable, d.h. sie wird in die Liste der aktiven
240         Variablen eingetragen.
241         
242 ******************************************************************************/
243         
244 static void var_activate (varinfo *v)
245 {
246         list_remove (&vars, v);
247         list_addlast (&activevars, v);  
248         v -> active = true;
249 }
250
251
252 /******************** Funktion: var_deactivate ********************************
253
254         Deaktiviert eine Variable (Gegenst"uck zu var_activate)
255         
256 ******************************************************************************/
257
258 static void var_deactivate (varinfo *v)
259 {
260         list_remove (&activevars, v);
261         list_addlast (&vars, v);
262         v -> active = false;
263 }
264
265
266 /****************** Funktion: var_nextactive **********************************
267
268         Liefert die erste noch aktivierte Variable 
269
270 ******************************************************************************/
271
272 static varinfo *var_nextactive ()
273 {
274         return list_first (&activevars);
275 }
276
277
278
279 /**************************** Funktion: var_display **************************
280
281         Gibt eine abdruckbare Darstellung einer Variablen aus.
282         (nur zu Debug-Zwecken)
283         
284 *****************************************************************************/
285
286 static void var_display (varinfo *v)
287 {
288         if (v==NOVAR) {
289                 printf ("_ ");
290                 return;
291                 }
292                 
293         switch (v->type) {
294         case TYPE_INT: printf ("I"); break;
295         case TYPE_LONG: printf ("L"); break;
296         case TYPE_FLOAT: printf ("F"); break;
297         case TYPE_DOUBLE: printf ("D"); break;
298         case TYPE_ADDRESS: printf ("A"); break;
299         default: printf ("?");
300         }
301         printf ("%d", v->number);
302
303         if (v->reg) {
304                 printf ("(="); 
305                 reg_display (v->reg);
306                 printf (")");
307                 }
308         printf (" ");
309 }
310
311
312 /************************ Funktion: var_displayall **************************
313
314         Gibt eine abdruckbare Darstellung aller Variablen aus.
315         (nur zu Debug-Zwecken)
316         
317 *****************************************************************************/
318
319 void var_displayall ()
320 {
321         varid v;
322         int num=0;
323         varid *sorted = DMNEW (varid, varnum);
324
325         printf ("\n   Types of all pseudo-variables:\n");
326         
327         for (num=0; num<varnum; num++) sorted[num] = NULL;
328         v = list_first (&vars);
329         while (v) {
330                 if (sorted[v->number]) {
331                         printf ("  Local variable overlay:  "); 
332                         if (v->saved) printf ("* ");
333                                else   printf ("  ");
334                         
335                         var_display (v);
336                         printf ("\n");
337                         } 
338                 else sorted[v->number] = v;
339                 
340                 v = list_next (&vars, v);
341                 }
342
343         
344         for (num=0; num<varnum; num++) {
345                 v = sorted[num];
346                 if (v) {
347                         if (v->saved) printf ("* ");
348                                else   printf ("  ");
349
350                         var_display (v);
351                         if (!v->reg) printf ("   ");
352                         
353                         if ( (num%5) == 4 ) printf ("\n");
354                         else printf ("\t");
355                         }
356                 }
357         
358         printf ("\n");
359 }
360
361