Initial revision
[cacao.git] / comp / regalloc.c
1 /************************** comp/regalloc.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         The register-allocator.
8
9         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
10
11         Last Change: 1997/03/05
12
13 *******************************************************************************/
14
15
16 /******************** Funktion: regalloc_doalloc ******************************
17
18         versucht f"ur ein Pseudoregister ein tats"achliches CPU-Register zu 
19         belegen.
20         Wenn noch keine Belegung stattgefunden hat, dann wird ein passendes
21         gerade freies Register angefordert.
22         Wenn das Pseudoregsiter bereits vorher schon einmal ein Belegung
23         hatte, dann wird versucht, das selbe CPU-Register wie vorher wieder
24         anzufordern. Wenn es nicht gelingt (weil es schon wieder anderwertig
25         verwendet wird), wann wird eben ein ganz neues Register angefordert.
26         
27 ******************************************************************************/
28
29 static void regalloc_doalloc (varinfo *v)
30 {
31         if (v->reg) {
32                 if (! reg_reallocate (v->reg)) {
33                         v->reg = reg_allocate (v->type, v->saved, true);
34                         }
35                 }
36         else {
37                 v->reg = reg_allocate (v->type, v->saved, false);
38                 }
39 }
40
41
42
43 /********************* Funktion: regalloc_activate ****************************
44
45         setzt ein Pseudoregister auf aktiv (wenn es nicht schon 
46         bereits aktiv ist), und fordert gegebenenfalls gleich ein passendes
47         CPU-Register an
48         Diese Operation wird aber nur bei Variablen mit lokalen Scope
49         gemacht.
50         
51 ******************************************************************************/
52
53 static void regalloc_activate (varinfo *v)
54 {
55         if (! v->globalscope) {
56                 if (! var_isactive(v) ) {
57                         regalloc_doalloc (v);
58                         var_activate (v);
59                         }
60                 }
61 }
62
63
64 /******************** Funktion: regalloc_deactivate ***************************
65
66         setzt ein Pseudoregister auf inaktiv (wenn es nicht schon inaktiv war)
67
68 ******************************************************************************/
69
70 static void regalloc_deactivate (varinfo *v)
71 {
72         if (! v->globalscope) {
73                 if (var_isactive(v) ) {
74                         var_deactivate (v);
75                         if (v->reg) reg_free (v->reg);
76                         }
77                 }
78 }
79
80
81 /******************** Funktion: regalloc_cmd **********************************
82
83         f"uhrt f"ur ein Pseudo-Command die Registerbelegung durch.
84         Wird von regalloc in einer Schleife aufgerufen.
85         
86 ******************************************************************************/ 
87         
88 static void regalloc_cmd (pcmd *c)
89 {
90         switch (c->tag) {
91                 case TAG_DROP:
92                         regalloc_deactivate (c->dest);
93                         break;
94                 case TAG_METHOD:
95                         if (c->u.method.exceptionvar) 
96                                 regalloc_activate (c->u.method.exceptionvar);
97                         if (c->dest) 
98                                 regalloc_activate (c->dest);
99                         break;
100                 default:
101                         if (c->dest) regalloc_activate (c->dest);
102                         break;
103                 }
104 }
105
106
107 /******************** Funktion: regalloc **************************************
108
109         f"uhrt f"ur einen ganzen Block die Registerbelegung durch.
110
111 ******************************************************************************/ 
112
113 static void regalloc (basicblock *b)
114 {
115         stackinfo *tos;
116         pcmd *c;
117         varinfo *v; 
118         
119                 /* alle Pseudoregister am Stack, die schon eine Belegung haben, 
120                    wieder aktivieren */
121         tos = b->stack;
122         while (tos) {
123                 if (tos -> var -> reg) regalloc_activate(tos->var);
124                 tos = tos->prev;
125                 }
126         
127                 /* alle anderen Pseudoregister am Stack belegen */
128         tos = b->stack;
129         while (tos) {
130                 regalloc_activate(tos->var);
131                 tos = tos->prev;
132                 }
133         
134         
135                 /* alle Befehle abarbeiten und Registerbelegung machen */
136         c = list_first (&b->pcmdlist);
137         while (c) {
138                 regalloc_cmd (c);
139                 c = list_next (&b->pcmdlist, c);                        
140                 } 
141
142
143                 /* alle noch aktiven Pseudoregister deaktivieren */
144         while ( (v = var_nextactive ()) != NULL) {
145                 regalloc_deactivate (v);
146                 }
147 }
148