1 /* vm/jit/schedule/schedule.c - architecture independent instruction scheduler
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Christian Thalinger
31 $Id: schedule.c 1973 2005-03-02 16:27:05Z twisti $
40 #include "mm/memory.h"
41 #include "vm/jit/schedule/schedule.h"
44 scheduledata *schedule_init(registerdata *rd)
48 sd = DNEW(scheduledata);
50 /* XXX quick hack: just use a fix number of instructions */
51 sd->mi = DMNEW(minstruction, 100);
55 sd->intregs_define_dep = DMNEW(s4, rd->intregsnum);
56 sd->fltregs_define_dep = DMNEW(s4, rd->fltregsnum);
58 sd->intregs_use_dep = DMNEW(nodelink*, rd->intregsnum);
59 sd->fltregs_use_dep = DMNEW(nodelink*, rd->fltregsnum);
61 /* clear all pointers */
63 MSET(sd->intregs_define_dep, 0, s4, rd->intregsnum);
64 MSET(sd->fltregs_define_dep, 0, s4, rd->fltregsnum);
66 MSET(sd->intregs_use_dep, 0, nodelink*, rd->intregsnum);
67 MSET(sd->fltregs_use_dep, 0, nodelink*, rd->fltregsnum);
69 sd->memory_define_dep = NULL;
70 sd->memory_use_dep = NULL;
76 /* schedule_calc_priority ******************************************************
78 Calculates the current node's priority by getting highest priority
79 of the dependency nodes, adding this nodes latency plus 1 (for the
82 *******************************************************************************/
84 void schedule_calc_priority(minstruction *mi)
89 /* check all dependencies for their priority */
93 for (i = 0; i < 3; i++) {
94 /* if (mi->opdep[i]) { */
95 /* if (mi->opdep[i]->priority > pathpriority) */
96 /* pathpriority = mi->opdep[i]->priority; */
100 mi->priority = pathpriority + mi->latency + 1;
104 void schedule_add_int_define_dep(scheduledata *sd, s4 reg)
115 /* get current machine instruction */
117 minode = sd->micount;
118 mi = &sd->mi[minode - 1];
120 /* get current use dependency nodes, if non-null use them... */
122 if ((usenl = sd->intregs_use_dep[reg])) {
123 /* add a dependency link node to all use dependency nodes */
128 /* don't add to the current machine instruction */
130 if (usenl->minode != minode) {
131 /* some edges to current machine instruction -> no leader */
135 /* get use machine instruction */
137 usemi = &sd->mi[usenl->minode - 1];
139 /* nl = DNEW(nodelink); */
140 /* nl->minode = sd->micount; */
141 /* nl->next = usemi->deps; */
142 /* usemi->deps = nl; */
144 usenl->minode = minode;
145 usenl->next = usemi->deps;
153 /* ...otherwise use last define dependency, if non-null */
155 if ((defnode = sd->intregs_define_dep[reg]) > 0) {
156 /* some edges to current machine instruction -> no leader */
160 /* get last define machine instruction */
162 defmi = &sd->mi[defnode - 1];
165 nl->minode = sd->micount;
166 nl->next = defmi->deps;
171 /* Set current instruction as new define dependency and clear use */
174 sd->intregs_define_dep[reg] = sd->micount;
175 sd->intregs_use_dep[reg] = NULL;
179 void schedule_add_int_use_dep(scheduledata *sd, s4 reg)
186 /* get current machine instruction */
188 mi = &sd->mi[sd->micount - 1];
190 /* get current define dependency instruction */
192 if ((defnode = sd->intregs_define_dep[reg]) > 0) {
193 /* some edges to current machine instruction -> no leader */
197 /* add node to dependency list of current define node */
199 defmi = &sd->mi[defnode - 1];
202 nl->minode = sd->micount;
203 nl->next = defmi->deps;
207 /* add node to list of current use nodes */
210 nl->minode = sd->micount;
211 nl->next = sd->intregs_use_dep[reg];
212 sd->intregs_use_dep[reg] = nl;
216 void schedule_add_flt_define_dep(scheduledata *sd, s4 reg)
225 /* get current machine instruction */
227 mi = &sd->mi[sd->micount - 1];
229 /* get current use dependency nodes, if non-null use them... */
231 if ((usenl = sd->fltregs_use_dep[reg])) {
232 /* add a dependency link node to all use dependency nodes */
235 /* don't add to the current machine instruction */
237 if (usenl->minode != sd->micount) {
238 /* some edges to current machine instruction -> no leader */
242 /* get use machine instruction */
244 usemi = &sd->mi[usenl->minode - 1];
247 nl->minode = sd->micount;
248 nl->next = usemi->deps;
256 /* ...otherwise use last define dependency, if non-null */
258 if ((defnode = sd->fltregs_define_dep[reg]) > 0) {
259 /* some edges to current machine instruction -> no leader */
263 /* get last define machine instruction */
265 defmi = &sd->mi[defnode - 1];
268 nl->minode = sd->micount;
269 nl->next = defmi->deps;
274 /* Set current instruction as new define dependency and clear use */
277 sd->fltregs_define_dep[reg] = sd->micount;
278 sd->fltregs_use_dep[reg] = NULL;
282 void schedule_add_flt_use_dep(scheduledata *sd, s4 reg)
289 /* get current machine instruction */
291 mi = &sd->mi[sd->micount - 1];
293 /* get current define dependency instruction */
295 if ((defnode = sd->fltregs_define_dep[reg]) > 0) {
296 /* some edges to current machine instruction -> no leader */
300 /* add node to dependency list of current define node */
302 defmi = &sd->mi[defnode - 1];
305 nl->minode = sd->micount;
306 nl->next = defmi->deps;
310 /* add node to list of current use nodes */
313 nl->minode = sd->micount;
314 nl->next = sd->fltregs_use_dep[reg];
315 sd->fltregs_use_dep[reg] = nl;
319 void schedule_add_memory_define_dep(scheduledata *sd)
324 void schedule_add_memory_use_dep(scheduledata *sd)
329 /* schedule_do_schedule ********************************************************
333 *******************************************************************************/
335 void schedule_do_schedule(scheduledata *sd)
341 printf("bb start ---\n");
343 for (i = 1, mi = sd->mi; i <= sd->micount; i++, mi++) {
344 disassinstr(&mi->instr);
346 printf("\t--> #%d, %d, %d, %d, ", i, mi->latency, mi->priority, mi->leader);
351 printf("%d ", nl->minode);
357 printf("bb end ---\n\n");
362 * These are local overrides for various environment variables in Emacs.
363 * Please do not remove this and leave it at the end of the file, where
364 * Emacs will automagically detect them.
365 * ---------------------------------------------------------------------
368 * indent-tabs-mode: t