Whatever.
[cacao.git] / src / vm / jit / schedule / schedule.c
1 /* vm/jit/schedule/schedule.c - architecture independent instruction scheduler
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: schedule.c 1965 2005-02-24 19:52:00Z twisti $
32
33 */
34
35
36 #include <stdio.h>
37
38 #include "disass.h"
39
40 #include "mm/memory.h"
41 #include "vm/jit/schedule/schedule.h"
42
43
44 scheduledata *schedule_init(registerdata *rd)
45 {
46         scheduledata *sd;
47
48         sd = DNEW(scheduledata);
49
50         /* XXX quick hack: just use a fix number of instructions */
51         sd->mi = DMNEW(minstruction, 100);
52
53         sd->intregs_read_dep = DMNEW(minstruction*, rd->intregsnum);
54         sd->intregs_write_dep = DMNEW(minstruction*, rd->intregsnum);
55
56         sd->fltregs_read_dep = DMNEW(minstruction*, rd->fltregsnum);
57         sd->fltregs_write_dep = DMNEW(minstruction*, rd->fltregsnum);
58
59         /* XXX: memory is currently only one cell */
60 /*      sd->memory_write_dep; */
61
62         /* clear all pointers */
63
64         MSET(sd->intregs_read_dep, 0, minstruction*, rd->intregsnum);
65         MSET(sd->intregs_write_dep, 0, minstruction*, rd->intregsnum);
66
67         MSET(sd->fltregs_read_dep, 0, minstruction*, rd->fltregsnum);
68         MSET(sd->fltregs_write_dep, 0, minstruction*, rd->fltregsnum);
69
70         sd->memory_write_dep = NULL;
71
72         return sd;
73 }
74
75
76 minstruction *schedule_prepend_minstruction(minstruction *mi)
77 {
78         minstruction *tmpmi;
79
80         /* add new instruction in front of the list */
81
82         tmpmi = DNEW(minstruction);
83
84         tmpmi->latency = 0;
85         tmpmi->priority = 0;
86         tmpmi->opdep[0] = NULL;
87         tmpmi->opdep[1] = NULL;
88         tmpmi->opdep[2] = NULL;
89         tmpmi->issinknode = true;           /* initially all nodes are sink nodes */
90
91         tmpmi->next = mi;                   /* link to next instruction           */
92
93         return tmpmi;
94 }
95
96
97 /* schedule_calc_priority ******************************************************
98
99    Calculates the current node's priority by getting highest priority
100    of the dependency nodes, adding this nodes latency plus 1 (for the
101    instruction itself).
102
103 *******************************************************************************/
104
105 void schedule_calc_priority(minstruction *mi)
106 {
107         s4 i;
108         s4 pathpriority;
109
110         /* check all dependencies for their priority */
111
112         pathpriority = 0;
113
114         for (i = 0; i < 3; i++) {
115                 if (mi->opdep[i]) {
116                         if (mi->opdep[i]->priority > pathpriority)
117                                 pathpriority = mi->opdep[i]->priority;
118
119                         /* dependent node is non-sink node */
120
121                         mi->opdep[i]->issinknode = false;
122                 }
123         }
124
125         mi->priority = pathpriority + mi->latency + 1;
126 }
127
128
129 /* schedule_do_schedule ********************************************************
130
131    XXX
132
133 *******************************************************************************/
134
135 void schedule_do_schedule(minstruction *mi)
136 {
137         minstruction *rootmi;
138         sinknode     *rootsn;
139         sinknode     *sn;
140         s4            i;
141         s4            icount;               /* number of basic block instruction  */
142
143         /* initialize variables */
144
145         rootmi = mi;
146         rootsn = NULL;
147         icount = 0;
148
149         /* find all sink nodes */
150
151         while (mi) {
152                 icount++;
153
154                 /* if current node is a sink node, add it to the sink node list */
155
156                 if (mi->issinknode) {
157                         sn = DNEW(sinknode);
158                         sn->mi = mi;
159                         sn->next = rootsn;
160                         rootsn = sn;
161                 }
162
163                 mi = mi->next;
164         }
165
166
167         /* walk through the instructions and do the actual scheduling */
168
169         for (i = 0; i < icount; i++) {
170                 sn = rootsn;
171
172                 /* first, find the highest priority path */
173
174                 while (sn)
175                         sn = sn->next;
176         }
177
178
179         printf("bb start ---\n");
180
181         mi = rootmi;
182
183         while (mi) {
184                 printf("%p: ", mi);
185
186 /*              disassinstr(&tmpmi->instr); */
187                 printf("%05x", mi->instr);
188
189                 printf("   --> %d, %d, %d:   op1=%p, op2=%p, op3=%p\n", mi->issinknode, mi->latency, mi->priority, mi->opdep[0], mi->opdep[1], mi->opdep[2]);
190
191                 mi = mi->next;
192         }
193         printf("bb end ---\n\n");
194 }
195
196
197 minstruction *schedule_append_minstruction(minstruction *mi)
198 {
199         minstruction *tmpmi;
200
201         /* add new instruction to the list */
202
203         tmpmi = DNEW(minstruction);
204         tmpmi->opdep[0] = NULL;
205         tmpmi->opdep[1] = NULL;
206         tmpmi->opdep[2] = NULL;
207         tmpmi->next = NULL;
208         mi->next = tmpmi;
209
210         return tmpmi;
211 }
212
213
214 /*
215  * These are local overrides for various environment variables in Emacs.
216  * Please do not remove this and leave it at the end of the file, where
217  * Emacs will automagically detect them.
218  * ---------------------------------------------------------------------
219  * Local variables:
220  * mode: c
221  * indent-tabs-mode: t
222  * c-basic-offset: 4
223  * tab-width: 4
224  * End:
225  */