1 /* src/vm/jit/allocator/simplereg.c - register allocator
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: Andreas Krall
35 $Id: simplereg.c 5414 2006-09-07 22:44:07Z edwin $
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "mm/memory.h"
51 #include "vm/method.h"
52 #include "vm/options.h"
53 #include "vm/resolve.h"
54 #include "vm/stringlocal.h"
55 #include "vm/jit/reg.h"
56 #include "vm/jit/allocator/simplereg.h"
59 /* function prototypes for this file ******************************************/
61 static void interface_regalloc(jitdata *jd);
62 static void local_regalloc(jitdata *jd);
63 static void new_allocate_scratch_registers(jitdata *jd);
64 static void allocate_scratch_registers(jitdata *jd);
67 /* regalloc ********************************************************************
69 Does a simple register allocation.
71 *******************************************************************************/
73 bool new_regalloc(jitdata *jd)
75 /* There is a problem with the use of unused float argument
76 registers in leafmethods for stackslots on c7 (2 * Dual Core
77 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
78 benchmark is heaviliy increased. This could be prevented by
79 setting rd->argfltreguse to FLT_ARG_CNT before calling
80 allocate_scratch_registers and setting it back to the original
81 value before calling local_regalloc. */
83 printf("------- rd->memuse bef %d\n",jd->rd->memuse);
85 interface_regalloc(jd);
86 printf("------- rd->memuse int %d\n",jd->rd->memuse);
87 new_allocate_scratch_registers(jd);
88 printf("------- rd->memuse scr %d\n",jd->rd->memuse);
90 printf("------- rd->memuse loc %d\n",jd->rd->memuse);
97 /* interface_regalloc **********************************************************
99 Allocates registers for all interface variables.
101 *******************************************************************************/
103 static void interface_regalloc(jitdata *jd)
110 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
111 /* in case more vars are packed into this interface slot */
113 int intregsneeded = 0;
115 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
116 /* on HAS_4BYTE_STACKSLOT architectures */
117 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
119 /* get required compiler data */
125 /* rd->memuse was already set in stack.c to allocate stack space
126 for passing arguments to called methods. */
128 #if defined(__I386__)
129 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
130 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
136 if (jd->isleafmethod) {
137 /* Reserve argument register, which will be used for Locals acting */
139 if (rd->argintreguse < m->parseddesc->argintreguse)
140 rd->argintreguse = m->parseddesc->argintreguse;
141 if (rd->argfltreguse < m->parseddesc->argfltreguse)
142 rd->argfltreguse = m->parseddesc->argfltreguse;
143 #ifdef HAS_ADDRESS_REGISTER_FILE
144 if (rd->argadrreguse < m->parseddesc->argadrreguse)
145 rd->argadrreguse = m->parseddesc->argadrreguse;
150 for (s = 0; s < cd->maxstack; s++) {
151 intalloc = -1; fltalloc = -1;
155 for (tt = 0; tt <=4; tt++) {
156 if ((t = jd->interface_map[s * 5 + TYPE_INT]) != UNUSED) {
157 saved |= (jd->var[t].flags & SAVEDVAR);
161 for (tt = 0; tt <= 4; tt++) {
163 if (jd->interface_map[s * 5 + t] == UNUSED)
166 v = &(jd->var[jd->interface_map[s * 5 + t]]);
167 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
168 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
170 #if defined(HAS_4BYTE_STACKSLOT)
171 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
174 #if defined(HAS_ADDRESS_REGISTER_FILE)
175 if (IS_ADR_TYPE(t)) {
176 if (!jd->isleafmethod
177 &&(rd->argadrreguse < ADR_ARG_CNT)) {
178 v->regoff = rd->argadrregs[rd->argadrreguse++];
179 } else if (rd->tmpadrreguse > 0) {
180 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
181 } else if (rd->savadrreguse > 0) {
182 v->regoff = rd->savadrregs[--rd->savadrreguse];
184 v->flags |= INMEMORY;
185 v->regoff = rd->memuse++;
187 } else /* !IS_ADR_TYPE */
188 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
190 if (IS_FLT_DBL_TYPE(t)) {
192 /* Reuse memory slot(s)/register(s) for shared interface slots */
193 v->flags |= jd->var[fltalloc].flags & INMEMORY;
194 v->regoff = jd->var[fltalloc].regoff;
195 } else if (rd->argfltreguse < FLT_ARG_CNT) {
196 v->regoff = rd->argfltregs[rd->argfltreguse++];
197 } else if (rd->tmpfltreguse > 0) {
198 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
199 } else if (rd->savfltreguse > 0) {
200 v->regoff = rd->savfltregs[--rd->savfltreguse];
202 v->flags |= INMEMORY;
203 #if defined(ALIGN_DOUBLES_IN_MEMORY)
204 /* Align doubles in Memory */
205 if ( (memneeded) && (rd->memuse & 1))
208 v->regoff = rd->memuse;
209 rd->memuse += memneeded + 1;
211 fltalloc = jd->interface_map[s * 5 + t];
212 } else { /* !IS_FLT_DBL_TYPE(t) */
213 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
215 * for i386 put all longs in memory
217 if (IS_2_WORD_TYPE(t)) {
218 v->flags |= INMEMORY;
219 #if defined(ALIGN_LONGS_IN_MEMORY)
220 /* Align longs in Memory */
224 v->regoff = rd->memuse;
225 rd->memuse += memneeded + 1;
227 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
229 /* Reuse memory slot(s)/register(s) for shared interface slots */
230 v->flags |= jd->var[intalloc].flags
232 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
233 if (!(v->flags & INMEMORY)
234 && IS_2_WORD_TYPE(jd->var[intalloc].type))
235 v->regoff = GET_LOW_REG(
236 jd->var[intalloc].regoff);
240 jd->var[intalloc].regoff;
242 if (rd->argintreguse + intregsneeded
244 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
247 rd->argintregs[rd->argintreguse],
248 rd->argintregs[rd->argintreguse + 1]);
252 rd->argintregs[rd->argintreguse];
253 rd->argintreguse += intregsneeded + 1;
255 else if (rd->tmpintreguse > intregsneeded) {
256 rd->tmpintreguse -= intregsneeded + 1;
257 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
260 rd->tmpintregs[rd->tmpintreguse],
261 rd->tmpintregs[rd->tmpintreguse + 1]);
265 rd->tmpintregs[rd->tmpintreguse];
267 else if (rd->savintreguse > intregsneeded) {
268 rd->savintreguse -= intregsneeded + 1;
270 rd->savintregs[rd->savintreguse];
271 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
274 rd->savintregs[rd->savintreguse],
275 rd->savintregs[rd->savintreguse + 1]);
279 rd->savintregs[rd->savintreguse];
282 v->flags |= INMEMORY;
283 #if defined(ALIGN_LONGS_IN_MEMORY)
284 /* Align longs in Memory */
285 if ( (memneeded) && (rd->memuse & 1))
288 v->regoff = rd->memuse;
289 rd->memuse += memneeded + 1;
292 intalloc = jd->interface_map[s * 5 + t];
293 } /* if (IS_FLT_DBL_TYPE(t)) */
295 } else { /* (saved) */
296 /* now the same like above, but without a chance to take a temporary register */
297 #ifdef HAS_ADDRESS_REGISTER_FILE
298 if (IS_ADR_TYPE(t)) {
299 if (rd->savadrreguse > 0) {
300 v->regoff = rd->savadrregs[--rd->savadrreguse];
303 v->flags |= INMEMORY;
304 v->regoff = rd->memuse++;
309 if (IS_FLT_DBL_TYPE(t)) {
311 v->flags |= jd->var[fltalloc].flags & INMEMORY;
312 v->regoff = jd->var[fltalloc].regoff;
314 if (rd->savfltreguse > 0) {
316 rd->savfltregs[--rd->savfltreguse];
319 v->flags |= INMEMORY;
320 #if defined(ALIGN_DOUBLES_IN_MEMORY)
321 /* Align doubles in Memory */
322 if ( (memneeded) && (rd->memuse & 1))
325 v->regoff = rd->memuse;
326 rd->memuse += memneeded + 1;
328 fltalloc = jd->interface_map[s * 5 + t];
330 else { /* IS_INT_LNG */
331 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
333 * for i386 put all longs in memory
335 if (IS_2_WORD_TYPE(t)) {
336 v->flags |= INMEMORY;
337 #if defined(ALIGN_LONGS_IN_MEMORY)
338 /* Align longs in Memory */
342 v->regoff = rd->memuse;
343 rd->memuse += memneeded + 1;
348 v->flags |= jd->var[intalloc].flags
350 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
351 if (!(v->flags & INMEMORY)
352 && IS_2_WORD_TYPE(jd->var[intalloc].type))
355 jd->var[intalloc].regoff);
359 jd->var[intalloc].regoff;
361 if (rd->savintreguse > intregsneeded) {
362 rd->savintreguse -= intregsneeded + 1;
363 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
365 v->regoff = PACK_REGS(
366 rd->savintregs[rd->savintreguse],
367 rd->savintregs[rd->savintreguse + 1]);
371 rd->savintregs[rd->savintreguse];
373 v->flags |= INMEMORY;
374 #if defined(ALIGN_LONGS_IN_MEMORY)
375 /* Align longs in Memory */
376 if ( (memneeded) && (rd->memuse & 1))
379 v->regoff = rd->memuse;
380 rd->memuse += memneeded + 1;
385 } /* if (IS_FLT_DBL_TYPE(t) else */
386 } /* if (IS_ADR_TYPE(t)) else */
387 } /* if (saved) else */
395 /* local_regalloc **************************************************************
397 Allocates registers for all local variables.
399 *******************************************************************************/
401 static void local_regalloc(jitdata *jd)
408 int intalloc, fltalloc;
410 int intregsneeded = 0;
412 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
413 int fargcnt, iargcnt;
414 #ifdef HAS_ADDRESS_REGISTER_FILE
418 /* get required compiler data */
424 if (jd->isleafmethod) {
425 methoddesc *md = m->parseddesc;
427 iargcnt = rd->argintreguse;
428 fargcnt = rd->argfltreguse;
429 #ifdef HAS_ADDRESS_REGISTER_FILE
430 aargcnt = rd->argadrreguse;
432 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
433 intalloc = -1; fltalloc = -1;
434 for (tt = 0; tt <= 4; tt++) {
436 lm = jd->local_map[s * 5 + t];
442 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
443 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
445 #if defined(HAS_4BYTE_STACKSLOT)
446 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
452 * #ifdef HAS_ADDRESS_REGISTER_FILE
459 * } else { / int & lng
463 * must not to be changed!
466 #ifdef HAS_ADDRESS_REGISTER_FILE
467 if (IS_ADR_TYPE(t)) {
468 if ((p < md->paramcount) && !md->params[p].inmemory) {
470 v->regoff = rd->argadrregs[md->params[p].regoff];
472 else if (rd->tmpadrreguse > 0) {
474 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
476 /* use unused argument registers as local registers */
477 else if ((p >= md->paramcount) &&
478 (aargcnt < ADR_ARG_CNT)) {
480 v->regoff = rd->argadrregs[aargcnt++];
482 else if (rd->savadrreguse > 0) {
484 v->regoff = rd->savadrregs[--rd->savadrreguse];
487 v->flags |= INMEMORY;
488 v->regoff = rd->memuse++;
492 if (IS_FLT_DBL_TYPE(t)) {
494 v->flags = jd->var[fltalloc].flags;
495 v->regoff = jd->var[fltalloc].regoff;
497 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
498 /* We can only use float arguments as local variables,
499 * if we do not pass them in integer registers. */
500 else if ((p < md->paramcount) &&
501 !md->params[p].inmemory) {
503 v->regoff = rd->argfltregs[md->params[p].regoff];
506 else if (rd->tmpfltreguse > 0) {
508 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
510 /* use unused argument registers as local registers */
511 else if ((p >= md->paramcount) &&
512 (fargcnt < FLT_ARG_CNT)) {
514 v->regoff = rd->argfltregs[fargcnt];
517 else if (rd->savfltreguse > 0) {
519 v->regoff = rd->savfltregs[--rd->savfltreguse];
523 #if defined(ALIGN_DOUBLES_IN_MEMORY)
524 /* Align doubles in Memory */
525 if ( (memneeded) && (rd->memuse & 1))
528 v->regoff = rd->memuse;
529 rd->memuse += memneeded + 1;
531 fltalloc = jd->local_map[s * 5 + t];
534 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
536 * for i386 put all longs in memory
538 if (IS_2_WORD_TYPE(t)) {
540 #if defined(ALIGN_LONGS_IN_MEMORY)
541 /* Align longs in Memory */
545 v->regoff = rd->memuse;
546 rd->memuse += memneeded + 1;
551 v->flags = jd->var[intalloc].flags;
552 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
553 if (!(v->flags & INMEMORY)
554 && IS_2_WORD_TYPE(jd->var[intalloc].type))
555 v->regoff = GET_LOW_REG(
556 jd->var[intalloc].regoff);
559 v->regoff = jd->var[intalloc].regoff;
561 else if ((p < md->paramcount) &&
562 !md->params[p].inmemory) {
564 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
565 if (IS_2_WORD_TYPE(t))
566 v->regoff = PACK_REGS(
567 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
568 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
572 rd->argintregs[md->params[p].regoff];
574 else if (rd->tmpintreguse > intregsneeded) {
575 rd->tmpintreguse -= intregsneeded + 1;
577 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
579 v->regoff = PACK_REGS(
580 rd->tmpintregs[rd->tmpintreguse],
581 rd->tmpintregs[rd->tmpintreguse + 1]);
585 rd->tmpintregs[rd->tmpintreguse];
588 * use unused argument registers as local registers
590 else if ((p >= m->parseddesc->paramcount) &&
591 (iargcnt + intregsneeded < INT_ARG_CNT)) {
593 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
596 rd->argintregs[iargcnt],
597 rd->argintregs[iargcnt + 1]);
600 v->regoff = rd->argintregs[iargcnt];
601 iargcnt += intregsneeded + 1;
603 else if (rd->savintreguse > intregsneeded) {
604 rd->savintreguse -= intregsneeded + 1;
606 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
608 v->regoff = PACK_REGS(
609 rd->savintregs[rd->savintreguse],
610 rd->savintregs[rd->savintreguse + 1]);
613 v->regoff =rd->savintregs[rd->savintreguse];
617 #if defined(ALIGN_LONGS_IN_MEMORY)
618 /* Align longs in Memory */
619 if ( (memneeded) && (rd->memuse & 1))
622 v->regoff = rd->memuse;
623 rd->memuse += memneeded + 1;
626 intalloc = jd->local_map[s * 5 + t];
628 #ifdef HAS_ADDRESS_REGISTER_FILE
631 } /* for (tt=0;...) */
633 /* If the current parameter is a 2-word type, the next local slot */
636 if (p < md->paramcount)
637 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
643 for (s = 0; s < cd->maxlocals; s++) {
644 intalloc = -1; fltalloc = -1;
645 for (tt=0; tt<=4; tt++) {
648 lm = jd->local_map[s * 5 + t];
654 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
655 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
657 #if defined(HAS_4BYTE_STACKSLOT)
658 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
660 #ifdef HAS_ADDRESS_REGISTER_FILE
661 if ( IS_ADR_TYPE(t) ) {
662 if (rd->savadrreguse > 0) {
664 v->regoff = rd->savadrregs[--rd->savadrreguse];
668 v->regoff = rd->memuse++;
672 if (IS_FLT_DBL_TYPE(t)) {
674 v->flags = jd->var[fltalloc].flags;
675 v->regoff = jd->var[fltalloc].regoff;
677 else if (rd->savfltreguse > 0) {
679 v->regoff = rd->savfltregs[--rd->savfltreguse];
683 #if defined(ALIGN_DOUBLES_IN_MEMORY)
684 /* Align doubles in Memory */
685 if ( (memneeded) && (rd->memuse & 1))
688 v->regoff = rd->memuse;
689 rd->memuse += memneeded + 1;
691 fltalloc = jd->local_map[s * 5 + t];
694 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
696 * for i386 put all longs in memory
698 if (IS_2_WORD_TYPE(t)) {
700 #if defined(ALIGN_LONGS_IN_MEMORY)
701 /* Align longs in Memory */
705 v->regoff = rd->memuse;
706 rd->memuse += memneeded + 1;
710 v->flags = jd->var[intalloc].flags;
711 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
712 if (!(v->flags & INMEMORY)
713 && IS_2_WORD_TYPE(jd->var[intalloc].type))
714 v->regoff = GET_LOW_REG(
715 jd->var[intalloc].regoff);
718 v->regoff = jd->var[intalloc].regoff;
720 else if (rd->savintreguse > intregsneeded) {
721 rd->savintreguse -= intregsneeded+1;
723 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
725 v->regoff = PACK_REGS(
726 rd->savintregs[rd->savintreguse],
727 rd->savintregs[rd->savintreguse + 1]);
730 v->regoff =rd->savintregs[rd->savintreguse];
734 #if defined(ALIGN_LONGS_IN_MEMORY)
735 /* Align longs in Memory */
736 if ( (memneeded) && (rd->memuse & 1))
739 v->regoff = rd->memuse;
740 rd->memuse += memneeded + 1;
742 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
745 intalloc = jd->local_map[s * 5 + t];
747 #ifdef HAS_ADDRESS_REGISTER_FILE
756 static void reg_init_temp(methodinfo *m, registerdata *rd)
759 #if defined(HAS_4BYTE_STACKSLOT)
760 rd->freememtop_2 = 0;
763 rd->freetmpinttop = 0;
764 rd->freesavinttop = 0;
765 rd->freetmpflttop = 0;
766 rd->freesavflttop = 0;
767 #ifdef HAS_ADDRESS_REGISTER_FILE
768 rd->freetmpadrtop = 0;
769 rd->freesavadrtop = 0;
772 rd->freearginttop = 0;
773 rd->freeargflttop = 0;
774 #ifdef HAS_ADDRESS_REGISTER_FILE
775 rd->freeargadrtop = 0;
780 #define reg_new_temp(jd,index) \
781 if ( (index >= jd->localcount) \
782 && (!(jd->var[index].flags & OUTVAR)) \
783 && (!(jd->var[index].flags & PREALLOC)) ) \
784 reg_new_temp_func(jd, index)
786 static void reg_new_temp_func(jitdata *jd, s4 index)
795 v = &(jd->var[index]);
797 /* Try to allocate a saved register if there is no temporary one */
798 /* available. This is what happens during the second run. */
799 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
801 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
802 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
806 #if defined(HAS_4BYTE_STACKSLOT)
807 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
812 for(; tryagain; --tryagain) {
814 if (!(v->flags & SAVEDVAR))
815 v->flags |= SAVEDTMP;
816 #ifdef HAS_ADDRESS_REGISTER_FILE
817 if (IS_ADR_TYPE(v->type)) {
818 if (rd->freesavadrtop > 0) {
819 v->regoff = rd->freesavadrregs[--rd->freesavadrtop];
821 } else if (rd->savadrreguse > 0) {
822 v->regoff = rd->savadrregs[--rd->savadrreguse];
828 if (IS_FLT_DBL_TYPE(v->type)) {
829 if (rd->freesavflttop > 0) {
830 v->regoff = rd->freesavfltregs[--rd->freesavflttop];
832 } else if (rd->savfltreguse > 0) {
833 v->regoff = rd->savfltregs[--rd->savfltreguse];
837 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
839 * for i386 put all longs in memory
841 if (!IS_2_WORD_TYPE(v->type))
844 if (rd->freesavinttop > intregsneeded) {
845 rd->freesavinttop -= intregsneeded + 1;
846 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
848 v->regoff = PACK_REGS(
849 rd->freesavintregs[rd->freesavinttop],
850 rd->freesavintregs[rd->freesavinttop + 1]);
854 rd->freesavintregs[rd->freesavinttop];
856 } else if (rd->savintreguse > intregsneeded) {
857 rd->savintreguse -= intregsneeded + 1;
858 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
860 v->regoff = PACK_REGS(
861 rd->savintregs[rd->savintreguse],
862 rd->savintregs[rd->savintreguse + 1]);
865 v->regoff = rd->savintregs[rd->savintreguse];
871 } else { /* tryagain == 2 */
872 #ifdef HAS_ADDRESS_REGISTER_FILE
873 if (IS_ADR_TYPE(v->type)) {
874 if (rd->freetmpadrtop > 0) {
875 v->regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
877 } else if (rd->tmpadrreguse > 0) {
878 v->regoff = rd->tmpadrregs[--rd->tmpadrreguse];
884 if (IS_FLT_DBL_TYPE(v->type)) {
885 if (rd->freeargflttop > 0) {
886 v->regoff = rd->freeargfltregs[--rd->freeargflttop];
889 } else if (rd->argfltreguse < FLT_ARG_CNT) {
890 v->regoff = rd->argfltregs[rd->argfltreguse++];
893 } else if (rd->freetmpflttop > 0) {
894 v->regoff = rd->freetmpfltregs[--rd->freetmpflttop];
896 } else if (rd->tmpfltreguse > 0) {
897 v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
902 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
904 * for i386 put all longs in memory
906 if (!IS_2_WORD_TYPE(v->type))
909 if (rd->freearginttop > intregsneeded) {
910 rd->freearginttop -= intregsneeded + 1;
912 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
914 v->regoff = PACK_REGS(
915 rd->freeargintregs[rd->freearginttop],
916 rd->freeargintregs[rd->freearginttop + 1]);
920 rd->freeargintregs[rd->freearginttop];
922 } else if (rd->argintreguse
923 < INT_ARG_CNT - intregsneeded) {
924 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
926 v->regoff = PACK_REGS(
927 rd->argintregs[rd->argintreguse],
928 rd->argintregs[rd->argintreguse + 1]);
931 v->regoff = rd->argintregs[rd->argintreguse];
933 rd->argintreguse += intregsneeded + 1;
935 } else if (rd->freetmpinttop > intregsneeded) {
936 rd->freetmpinttop -= intregsneeded + 1;
937 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
939 v->regoff = PACK_REGS(
940 rd->freetmpintregs[rd->freetmpinttop],
941 rd->freetmpintregs[rd->freetmpinttop + 1]);
944 v->regoff = rd->freetmpintregs[rd->freetmpinttop];
946 } else if (rd->tmpintreguse > intregsneeded) {
947 rd->tmpintreguse -= intregsneeded + 1;
948 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
950 v->regoff = PACK_REGS(
951 rd->tmpintregs[rd->tmpintreguse],
952 rd->tmpintregs[rd->tmpintreguse + 1]);
955 v->regoff = rd->tmpintregs[rd->tmpintreguse];
958 } /* if (!IS_2_WORD_TYPE(s->type)) */
959 } /* if (IS_FLT_DBL_TYPE(s->type)) */
960 } /* if (IS_ADR_TYPE(s->type)) */
961 } /* if (tryagain == 1) else */
962 } /* for(; tryagain; --tryagain) */
964 #if defined(HAS_4BYTE_STACKSLOT)
965 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
967 v->regoff = rd->freemem_2[rd->freememtop_2];
969 #endif /*defined(HAS_4BYTE_STACKSLOT) */
970 if ((memneeded == 0) && (rd->freememtop > 0)) {
972 v->regoff = rd->freemem[rd->freememtop];
974 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
975 /* align 2 Word Types */
976 if ((memneeded) && ((rd->memuse & 1) == 1)) {
977 /* Put patched memory slot on freemem */
978 rd->freemem[rd->freememtop++] = rd->memuse;
981 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
982 v->regoff = rd->memuse;
983 rd->memuse += memneeded + 1;
985 v->flags |= INMEMORY;
989 #define reg_free_temp(jd,index) \
990 if ((index > jd->localcount) \
991 && (!(jd->var[index].flags & OUTVAR)) \
992 && (!(jd->var[index].flags & STCOPY)) \
993 && (!(jd->var[index].flags & PREALLOC)) ) \
994 reg_free_temp_func(jd, index)
996 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
997 /* alive using this reg/memory location */
999 static void reg_free_temp_func(jitdata *jd, s4 index)
1007 v = &(jd->var[index]);
1010 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1011 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1016 #if defined(HAS_4BYTE_STACKSLOT)
1017 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1022 if (v->flags & INMEMORY) {
1023 #if defined(HAS_4BYTE_STACKSLOT)
1024 if (memneeded > 0) {
1025 rd->freemem_2[rd->freememtop_2] = v->regoff;
1030 rd->freemem[rd->freememtop] = v->regoff;
1034 #ifdef HAS_ADDRESS_REGISTER_FILE
1035 } else if (IS_ADR_TYPE(v->type)) {
1036 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1037 /* v->flags &= ~SAVEDTMP; */
1038 rd->freesavadrregs[rd->freesavadrtop++] = v->regoff;
1040 rd->freetmpadrregs[rd->freetmpadrtop++] = v->regoff;
1042 } else if (IS_FLT_DBL_TYPE(v->type)) {
1043 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1044 /* v->flags &= ~SAVEDTMP; */
1045 rd->freesavfltregs[rd->freesavflttop++] = v->regoff;
1046 } else if (v->flags & TMPARG) {
1047 /* v->flags &= ~TMPARG; */
1048 rd->freeargfltregs[rd->freeargflttop++] = v->regoff;
1050 rd->freetmpfltregs[rd->freetmpflttop++] = v->regoff;
1051 } else { /* IS_INT_LNG_TYPE */
1052 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1053 /* v->flags &= ~SAVEDTMP; */
1054 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1055 if (intregsneeded) {
1056 rd->freesavintregs[rd->freesavinttop] =
1057 GET_LOW_REG(v->regoff);
1058 rd->freesavintregs[rd->freesavinttop + 1] =
1059 GET_HIGH_REG(v->regoff);
1062 rd->freesavintregs[rd->freesavinttop] = v->regoff;
1063 rd->freesavinttop += intregsneeded + 1;
1065 } else if (v->flags & TMPARG) {
1066 /* s->flags &= ~TMPARG; */
1067 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1068 if (intregsneeded) {
1069 rd->freeargintregs[rd->freearginttop] =
1070 GET_LOW_REG(v->regoff);
1071 rd->freeargintregs[rd->freearginttop + 1] =
1072 GET_HIGH_REG(v->regoff);
1075 rd->freeargintregs[rd->freearginttop] = v->regoff;
1076 rd->freearginttop += intregsneeded + 1;
1078 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1079 if (intregsneeded) {
1080 rd->freetmpintregs[rd->freetmpinttop] =
1081 GET_LOW_REG(s->regoff);
1082 rd->freetmpintregs[rd->freetmpinttop + 1] =
1083 GET_HIGH_REG(s->regoff);
1086 rd->freetmpintregs[rd->freetmpinttop] = v->regoff;
1087 rd->freetmpinttop += intregsneeded + 1;
1093 /* allocate_scratch_registers **************************************************
1095 Allocate temporary (non-interface, non-local) registers.
1097 *******************************************************************************/
1099 static void new_allocate_scratch_registers(jitdata *jd)
1107 builtintable_entry *bte;
1111 /* get required compiler data */
1116 /* initialize temp registers */
1118 reg_init_temp(m, rd);
1120 bptr = jd->new_basicblocks;
1122 while (bptr != NULL) {
1123 if (bptr->flags >= BBREACHED) {
1124 iptr = bptr->iinstr;
1127 while (--len >= 0) {
1128 switch (iptr->opc) {
1133 case ICMD_CHECKNULL:
1139 case ICMD_PUTSTATICCONST:
1140 case ICMD_INLINE_START:
1141 case ICMD_INLINE_END:
1142 case ICMD_INLINE_GOTO:
1145 /* pop 0 push 1 const */
1153 /* pop 0 push 1 load */
1160 reg_new_temp(jd, iptr->dst.varindex);
1174 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1175 reg_free_temp(jd, iptr->s1.varindex);
1176 reg_new_temp(jd, iptr->dst.varindex);
1190 reg_free_temp(jd, iptr->sx.s23.s3.varindex);
1191 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1192 reg_free_temp(jd, iptr->s1.varindex);
1195 /* pop 1 push 0 store */
1215 case ICMD_PUTSTATIC:
1216 case ICMD_PUTFIELDCONST:
1218 /* pop 1 push 0 branch */
1221 case ICMD_IFNONNULL:
1237 /* pop 1 push 0 table branch */
1239 case ICMD_TABLESWITCH:
1240 case ICMD_LOOKUPSWITCH:
1242 case ICMD_MONITORENTER:
1243 case ICMD_MONITOREXIT:
1244 reg_free_temp(jd, iptr->s1.varindex);
1247 /* pop 2 push 0 branch */
1249 case ICMD_IF_ICMPEQ:
1250 case ICMD_IF_ICMPNE:
1251 case ICMD_IF_ICMPLT:
1252 case ICMD_IF_ICMPGE:
1253 case ICMD_IF_ICMPGT:
1254 case ICMD_IF_ICMPLE:
1256 case ICMD_IF_LCMPEQ:
1257 case ICMD_IF_LCMPNE:
1258 case ICMD_IF_LCMPLT:
1259 case ICMD_IF_LCMPGE:
1260 case ICMD_IF_LCMPGT:
1261 case ICMD_IF_LCMPLE:
1263 case ICMD_IF_FCMPEQ:
1264 case ICMD_IF_FCMPNE:
1266 case ICMD_IF_FCMPL_LT:
1267 case ICMD_IF_FCMPL_GE:
1268 case ICMD_IF_FCMPL_GT:
1269 case ICMD_IF_FCMPL_LE:
1271 case ICMD_IF_FCMPG_LT:
1272 case ICMD_IF_FCMPG_GE:
1273 case ICMD_IF_FCMPG_GT:
1274 case ICMD_IF_FCMPG_LE:
1276 case ICMD_IF_DCMPEQ:
1277 case ICMD_IF_DCMPNE:
1279 case ICMD_IF_DCMPL_LT:
1280 case ICMD_IF_DCMPL_GE:
1281 case ICMD_IF_DCMPL_GT:
1282 case ICMD_IF_DCMPL_LE:
1284 case ICMD_IF_DCMPG_LT:
1285 case ICMD_IF_DCMPG_GE:
1286 case ICMD_IF_DCMPG_GT:
1287 case ICMD_IF_DCMPG_LE:
1289 case ICMD_IF_ACMPEQ:
1290 case ICMD_IF_ACMPNE:
1298 case ICMD_IASTORECONST:
1299 case ICMD_LASTORECONST:
1300 case ICMD_AASTORECONST:
1301 case ICMD_BASTORECONST:
1302 case ICMD_CASTORECONST:
1303 case ICMD_SASTORECONST:
1304 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1305 reg_free_temp(jd, iptr->s1.varindex);
1308 /* pop 0 push 1 dup */
1311 /* src === dst->prev (identical Stackslot Element) */
1312 /* src --> dst (copied value, take same reg/mem) */
1314 /* if (!reg_alloc_dup(iptr->s1.varindex, iptr->dst.varindex)) { */
1315 reg_new_temp(jd, iptr->dst.varindex);
1317 /* iptr->dst.varindex->flags |= STCOPY; */
1321 /* pop 0 push 2 dup */
1324 /* src->prev === dst->prev->prev->prev (identical Stackslot Element) */
1325 /* src === dst->prev->prev (identical Stackslot Element) */
1326 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1327 /* src --> dst (copied value, take same reg/mem) */
1329 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0])) */
1330 reg_new_temp(jd, iptr->dst.dupslots[2+0]);
1331 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1])) */
1332 reg_new_temp(jd, iptr->dst.dupslots[2+1]);
1333 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2); */
1336 /* pop 2 push 3 dup */
1339 /* src->prev --> dst->prev (copied value, take same reg/mem) */
1340 /* src --> dst (copied value, take same reg/mem) */
1341 /* src --> dst->prev->prev (copied value, take same reg/mem) */
1343 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0])) */
1344 reg_new_temp(jd, iptr->dst.dupslots[2+0]);
1345 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2])) */
1346 reg_new_temp(jd, iptr->dst.dupslots[2+2]);
1347 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1])) */
1348 reg_new_temp(jd, iptr->dst.dupslots[2+1]);
1349 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0); */
1352 /* pop 3 push 4 dup */
1355 /* src->prev->prev --> dst->prev->prev */
1356 /* src->prev --> dst->prev */
1358 /* src --> dst->prev->prev->prev */
1360 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0])) */
1361 reg_new_temp(jd, iptr->dst.dupslots[3+0]);
1362 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3])) */
1363 reg_new_temp(jd, iptr->dst.dupslots[3+3]);
1364 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2])) */
1365 reg_new_temp(jd, iptr->dst.dupslots[3+2]);
1366 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1])) */
1367 reg_new_temp(jd, iptr->dst.dupslots[3+1]);
1368 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0); */
1371 /* pop 3 push 5 dup */
1374 /* src->prev->prev --> dst->prev->prev */
1375 /* src->prev --> dst->prev */
1377 /* src->prev --> dst->prev->prev->prev->prev */
1378 /* src --> dst->prev->prev->prev */
1380 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1])) */
1381 reg_new_temp(jd, iptr->dst.dupslots[3+1]);
1382 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4])) */
1383 reg_new_temp(jd, iptr->dst.dupslots[3+4]);
1384 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0])) */
1385 reg_new_temp(jd, iptr->dst.dupslots[3+0]);
1386 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3])) */
1387 reg_new_temp(jd, iptr->dst.dupslots[3+3]);
1388 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2])) */
1389 reg_new_temp(jd, iptr->dst.dupslots[3+2]);
1390 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0); */
1393 /* pop 4 push 6 dup */
1396 /* src->prev->prev->prev --> dst->prev->prev->prev */
1397 /* src->prev->prev --> dst->prev->prev */
1398 /* src->prev --> dst->prev */
1400 /* src->prev --> dst->prev->prev->prev->prev->prev */
1401 /* src --> dst->prev->prev->prev->prev */
1403 /* if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1])) */
1404 reg_new_temp(jd, iptr->dst.dupslots[4+1]);
1405 /* if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5])) */
1406 reg_new_temp(jd, iptr->dst.dupslots[4+5]);
1407 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0])) */
1408 reg_new_temp(jd, iptr->dst.dupslots[4+0]);
1409 /* if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4])) */
1410 reg_new_temp(jd, iptr->dst.dupslots[4+4]);
1411 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3])) */
1412 reg_new_temp(jd, iptr->dst.dupslots[4+3]);
1413 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2])) */
1414 reg_new_temp(jd, iptr->dst.dupslots[4+2]);
1415 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0); */
1418 /* pop 2 push 2 swap */
1421 /* src --> dst->prev (copy) */
1422 /* src->prev --> dst (copy) */
1424 /* if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0])) */
1425 reg_new_temp(jd, iptr->dst.dupslots[2+0]);
1426 /* if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1])) */
1427 reg_new_temp(jd, iptr->dst.dupslots[2+1]);
1428 /* new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0); */
1477 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1478 reg_free_temp(jd, iptr->s1.varindex);
1479 reg_new_temp(jd, iptr->dst.varindex);
1484 case ICMD_IADDCONST:
1485 case ICMD_ISUBCONST:
1486 case ICMD_IMULCONST:
1490 case ICMD_IANDCONST:
1492 case ICMD_IXORCONST:
1493 case ICMD_ISHLCONST:
1494 case ICMD_ISHRCONST:
1495 case ICMD_IUSHRCONST:
1497 case ICMD_LADDCONST:
1498 case ICMD_LSUBCONST:
1499 case ICMD_LMULCONST:
1503 case ICMD_LANDCONST:
1505 case ICMD_LXORCONST:
1506 case ICMD_LSHLCONST:
1507 case ICMD_LSHRCONST:
1508 case ICMD_LUSHRCONST:
1513 case ICMD_INT2SHORT:
1531 case ICMD_CHECKCAST:
1533 case ICMD_ARRAYLENGTH:
1534 case ICMD_INSTANCEOF:
1537 case ICMD_ANEWARRAY:
1540 reg_free_temp(jd, iptr->s1.varindex);
1541 reg_new_temp(jd, iptr->dst.varindex);
1546 case ICMD_GETSTATIC:
1549 reg_new_temp(jd, iptr->dst.varindex);
1552 /* pop many push any */
1554 case ICMD_INVOKESTATIC:
1555 case ICMD_INVOKESPECIAL:
1556 case ICMD_INVOKEVIRTUAL:
1557 case ICMD_INVOKEINTERFACE:
1558 INSTRUCTION_GET_METHODDESC(iptr,md);
1560 argp = iptr->sx.s23.s2.args;
1562 reg_free_temp(jd, *argp);
1565 if (md->returntype.type != TYPE_VOID)
1566 reg_new_temp(jd, iptr->dst.varindex);
1570 bte = iptr->sx.s23.s3.bte;
1573 argp = iptr->sx.s23.s2.args;
1575 reg_free_temp(jd, *argp);
1578 if (md->returntype.type != TYPE_VOID)
1579 reg_new_temp(jd, iptr->dst.varindex);
1582 case ICMD_MULTIANEWARRAY:
1583 i = iptr->s1.argcount;
1584 argp = iptr->sx.s23.s2.args;
1586 reg_free_temp(jd, *argp);
1589 reg_new_temp(jd, iptr->dst.varindex);
1594 new_internalerror("Unknown ICMD %d during register allocation",
1599 } /* while instructions */
1602 } /* while blocks */
1606 #if defined(ENABLE_STATISTICS)
1607 void reg_make_statistics(jitdata *jd)
1614 stackptr src, src_old;
1618 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1621 /* get required compiler data */
1631 /* count how many local variables are held in memory or register */
1632 for(i=0; i < cd->maxlocals; i++)
1633 for (type=0; type <=4; type++)
1634 if (rd->locals[i][type].type != -1) { /* valid local */
1635 if (rd->locals[i][type].flags & INMEMORY) {
1636 count_locals_spilled++;
1640 count_locals_register++;
1643 /* count how many stack slots are held in memory or register */
1645 bptr = jd->new_basicblocks;
1647 while (bptr != NULL) {
1648 if (bptr->flags >= BBREACHED) {
1650 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1653 /* check for memory moves from interface to BB instack */
1654 dst = bptr->instack;
1655 len = bptr->indepth;
1657 if (len > size_interface) size_interface = len;
1659 while (dst != NULL) {
1661 if (dst->varkind != STACKVAR) {
1662 if ( (dst->flags & INMEMORY) ||
1663 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1664 ( (dst->flags & INMEMORY) &&
1665 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1666 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1668 /* one in memory or both inmemory at different offsets */
1669 count_mem_move_bb++;
1677 /* check for memory moves from BB outstack to interface */
1678 dst = bptr->outstack;
1679 len = bptr->outdepth;
1680 if (len > size_interface) size_interface = len;
1684 if (dst->varkind != STACKVAR) {
1685 if ( (dst->flags & INMEMORY) || \
1686 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1687 ( (dst->flags & INMEMORY) && \
1688 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1689 (dst->regoff != rd->interfaces[len][dst->type].regoff) ))
1691 /* one in memory or both inmemory at different offsets */
1692 count_mem_move_bb++;
1699 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1704 dst = bptr->instack;
1705 iptr = bptr->iinstr;
1709 while (--len >= 0) {
1711 dst = iptr->dst.var;
1713 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1714 switch (src->varkind) {
1717 if (!(src->flags & INMEMORY))
1718 count_ss_register++;
1724 /* case LOCALVAR: */
1725 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1726 /* count_ss_register++; */
1728 /* count_ss_spilled++; */
1731 if (!(src->flags & INMEMORY))
1732 count_argument_mem_ss++;
1734 count_argument_reg_ss++;
1738 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1739 /* if (src->varnum < FLT_ARG_CNT) { */
1740 /* count_ss_register++; */
1744 /* #if defined(__POWERPC__) */
1745 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1747 /* if (src->varnum < INT_ARG_CNT) { */
1749 /* count_ss_register++; */
1753 /* count_ss_spilled++; */
1760 } /* while instructions */
1763 } /* while blocks */
1764 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1765 if (in_register) count_method_in_register++;
1767 printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1770 #endif /* defined(ENABLE_STATISTICS) */
1774 * These are local overrides for various environment variables in Emacs.
1775 * Please do not remove this and leave it at the end of the file, where
1776 * Emacs will automagically detect them.
1777 * ---------------------------------------------------------------------
1780 * indent-tabs-mode: t
1784 * vim:noexpandtab:sw=4:ts=4: