1 /* src/vm/jit/allocator/simplereg.c - register allocator
3 Copyright (C) 1996-2005, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
36 #include "mm/memory.h"
38 #include "vm/jit/builtin.hpp"
39 #include "vm/exceptions.hpp"
40 #include "vm/method.h"
41 #include "vm/options.h"
42 #include "vm/resolve.h"
43 #include "vm/string.hpp"
45 #include "vm/jit/abi.h"
46 #include "vm/jit/reg.h"
47 #include "vm/jit/show.hpp"
48 #include "vm/jit/allocator/simplereg.h"
52 # define LOG(args) printf args
58 /* function prototypes for this file ******************************************/
60 static void simplereg_allocate_interfaces(jitdata *jd);
61 static void simplereg_allocate_locals(jitdata *jd);
62 static void simplereg_allocate_temporaries(jitdata *jd);
65 /* size of a stackslot used by the internal ABI */
67 #define SIZE_OF_STACKSLOT 8
70 /* total number of registers */
72 #if defined(HAS_ADDRESS_REGISTER_FILE)
73 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
75 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
79 /* macros for handling register stacks ****************************************/
81 #define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
82 #define AVAIL_BACK(cnt) ((cnt) > 0)
84 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
85 #define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
86 #define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
88 #define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
89 #define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
92 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
93 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
94 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
95 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
97 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
98 #define POP_FRONT_INT(stk, cnt, reg) \
100 if (intregsneeded) { \
101 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
105 POP_FRONT(stk, cnt, reg); \
108 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
111 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
112 #define POP_BACK_INT(stk, cnt, reg) \
114 if (intregsneeded) { \
116 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
119 POP_BACK(stk, cnt, reg); \
122 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
125 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
126 #define PUSH_BACK_INT(stk, cnt, reg) \
128 if (intregsneeded) { \
129 stk[cnt] = GET_LOW_REG(reg); \
130 stk[cnt + 1] = GET_HIGH_REG(reg); \
134 PUSH_BACK(stk, cnt, reg); \
137 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
140 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
141 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
142 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
144 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
145 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
146 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
148 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
149 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
150 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
152 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
153 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
154 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
156 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
157 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
158 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
160 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
161 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
162 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
164 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
165 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
166 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
168 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
169 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
170 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
172 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
173 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
174 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
176 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
177 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
178 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
180 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
181 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
182 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
184 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
185 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
186 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
188 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
189 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
190 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
192 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
193 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
194 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
196 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
197 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
198 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
201 /* macros for allocating memory slots ****************************************/
203 #define NEW_MEM_SLOT(r) \
205 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
209 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
210 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
211 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
214 /* macros for creating/freeing temporary variables ***************************/
216 #define NEW_TEMP_REG(index) \
217 if ( ((index) >= jd->localcount) \
218 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
219 simplereg_new_temp(jd, (index))
222 #define FREE_TEMP_REG(index) \
223 if (((index) > jd->localcount) \
224 && (!(VAR(index)->flags & (PREALLOC)))) \
225 simplereg_free_temp(jd, (index))
228 /* macro for getting a unique register index *********************************/
230 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
231 #define REG_INDEX_NON_ADR(regoff, type) \
232 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
234 #define REG_INDEX_NON_ADR(regoff, type) \
235 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
238 #if defined(HAS_ADDRESS_REGISTER_FILE)
239 #define REG_INDEX(regoff, type) \
240 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
242 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
246 /* regalloc ********************************************************************
248 Does a simple register allocation.
250 *******************************************************************************/
252 bool regalloc(jitdata *jd)
254 /* There is a problem with the use of unused float argument
255 registers in leafmethods for stackslots on c7 (2 * Dual Core
256 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
257 benchmark is heaviliy increased. This could be prevented by
258 setting rd->argfltreguse to FLT_ARG_CNT before calling
259 simplereg_allocate_temporaries and setting it back to the original
260 value before calling simplereg_allocate_locals. */
262 simplereg_allocate_interfaces(jd);
263 simplereg_allocate_temporaries(jd);
264 simplereg_allocate_locals(jd);
272 /* simplereg_allocate_interfaces ***********************************************
274 Allocates registers for all interface variables.
276 *******************************************************************************/
278 static void simplereg_allocate_interfaces(jitdata *jd)
286 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
287 /* in case more vars are packed into this interface slot */
288 /* Allocate LNG and DBL types first to ensure 2 registers */
289 /* on some architectures. */
290 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
292 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
296 /* get required compiler data */
303 /* rd->memuse was already set in stack.c to allocate stack space
304 for passing arguments to called methods. */
306 #if defined(__I386__)
307 if (checksync && code_is_synchronized(code)) {
308 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
314 if (code_is_leafmethod(code)) {
315 /* Reserve argument register, which will be used for Locals acting */
317 if (rd->argintreguse < m->parseddesc->argintreguse)
318 rd->argintreguse = m->parseddesc->argintreguse;
319 if (rd->argfltreguse < m->parseddesc->argfltreguse)
320 rd->argfltreguse = m->parseddesc->argfltreguse;
321 #ifdef HAS_ADDRESS_REGISTER_FILE
322 if (rd->argadrreguse < m->parseddesc->argadrreguse)
323 rd->argadrreguse = m->parseddesc->argadrreguse;
327 for (s = 0; s < jd->maxinterfaces; s++) {
328 intalloc = -1; fltalloc = -1;
330 /* check if the interface at this stack depth must be a SAVEDVAR */
334 for (tt = 0; tt <=4; tt++) {
335 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
336 saved |= t & SAVEDVAR;
340 /* allocate reg/mem for each type the interface is used as */
342 for (tt = 0; tt <= 4; tt++) {
344 if (jd->interface_map[s * 5 + t].flags == UNUSED)
348 regoff = -1; /* initialize to invalid value */
350 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
351 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
355 #if defined(HAS_ADDRESS_REGISTER_FILE)
356 if (IS_ADR_TYPE(t)) {
357 if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
359 TAKE_ARG_ADR(regoff);
361 else if (AVAIL_TMP_ADR) {
362 TAKE_TMP_ADR(regoff);
364 else if (AVAIL_SAV_ADR) {
366 TAKE_SAV_ADR(regoff);
370 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
373 else /* !IS_ADR_TYPE */
374 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
376 if (IS_FLT_DBL_TYPE(t)) {
378 /* Reuse memory slot(s)/register(s) for shared interface slots */
379 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
380 regoff = jd->interface_map[fltalloc].regoff;
382 else if (AVAIL_ARG_FLT) {
384 TAKE_ARG_FLT(regoff);
386 else if (AVAIL_TMP_FLT) {
387 TAKE_TMP_FLT(regoff);
389 else if (AVAIL_SAV_FLT) {
391 TAKE_SAV_FLT(regoff);
395 NEW_MEM_SLOT_FLT_DBL(regoff);
397 fltalloc = s * 5 + t;
399 else { /* !IS_FLT_DBL_TYPE(t) */
400 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
402 * for i386 put all longs in memory
404 if (IS_2_WORD_TYPE(t)) {
406 NEW_MEM_SLOT_INT_LNG(regoff);
411 /* Reuse memory slot(s)/register(s) for shared interface slots */
412 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
413 regoff = jd->interface_map[intalloc].regoff;
414 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
415 /* reuse lower half */
416 if (!(flags & INMEMORY)
417 && IS_2_WORD_TYPE(intalloc % 5))
418 regoff = GET_LOW_REG(regoff);
424 TAKE_ARG_INT(regoff);
426 else if (AVAIL_TMP_INT) {
427 TAKE_TMP_INT(regoff);
429 else if (AVAIL_SAV_INT) {
431 TAKE_SAV_INT(regoff);
435 NEW_MEM_SLOT_INT_LNG(regoff);
439 intalloc = s * 5 + t;
440 } /* if (IS_FLT_DBL_TYPE(t)) */
444 /* now the same like above, but without a chance to take a temporary register */
445 #ifdef HAS_ADDRESS_REGISTER_FILE
446 if (IS_ADR_TYPE(t)) {
448 TAKE_SAV_ADR(regoff);
452 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
458 if (IS_FLT_DBL_TYPE(t)) {
460 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
461 regoff = jd->interface_map[fltalloc].regoff;
465 TAKE_SAV_FLT(regoff);
469 NEW_MEM_SLOT_FLT_DBL(regoff);
472 fltalloc = s * 5 + t;
474 else { /* IS_INT_LNG */
475 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
477 * for i386 put all longs in memory
479 if (IS_2_WORD_TYPE(t)) {
481 NEW_MEM_SLOT_INT_LNG(regoff);
487 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
488 regoff = jd->interface_map[intalloc].regoff;
489 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
490 /* reuse lower half */
491 if (!(flags & INMEMORY)
492 && IS_2_WORD_TYPE(intalloc % 5))
493 regoff = GET_LOW_REG(regoff);
498 TAKE_SAV_INT(regoff);
502 NEW_MEM_SLOT_INT_LNG(regoff);
507 } /* if (IS_FLT_DBL_TYPE(t) else */
508 } /* if (IS_ADR_TYPE(t)) else */
509 } /* if (saved) else */
513 jd->interface_map[5*s + t].flags = flags | INOUT;
514 jd->interface_map[5*s + t].regoff = regoff;
520 /* simplereg_allocate_locals_leafmethod ****************************************
522 Allocates registers for all local variables of a leafmethod.
524 *******************************************************************************/
526 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
533 int p, s, t, tt, varindex;
534 int intalloc, fltalloc;
536 int intregsneeded = 0;
537 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
538 int fargcnt, iargcnt;
539 #ifdef HAS_ADDRESS_REGISTER_FILE
543 /* get required compiler data */
551 iargcnt = rd->argintreguse;
552 fargcnt = rd->argfltreguse;
553 #ifdef HAS_ADDRESS_REGISTER_FILE
554 aargcnt = rd->argadrreguse;
556 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
557 intalloc = -1; fltalloc = -1;
558 for (tt = 0; tt <= 4; tt++) {
560 varindex = jd->local_map[s * 5 + t];
561 if (varindex == UNUSED)
566 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
567 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
573 * #ifdef HAS_ADDRESS_REGISTER_FILE
580 * } else { / int & lng
584 * must not to be changed!
587 #ifdef HAS_ADDRESS_REGISTER_FILE
588 if (IS_ADR_TYPE(t)) {
589 if ((p < md->paramcount) && !md->params[p].inmemory) {
591 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
593 else if (AVAIL_TMP_ADR) {
595 TAKE_TMP_ADR(v->vv.regoff);
597 /* use unused argument registers as local registers */
598 else if ((p >= md->paramcount) &&
599 (aargcnt < ADR_ARG_CNT))
602 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
604 else if (AVAIL_SAV_ADR) {
606 TAKE_SAV_ADR(v->vv.regoff);
609 v->flags |= INMEMORY;
610 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
615 if (IS_FLT_DBL_TYPE(t)) {
617 v->flags = VAR(fltalloc)->flags;
618 v->vv.regoff = VAR(fltalloc)->vv.regoff;
620 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
621 /* We can only use float arguments as local variables,
622 * if we do not pass them in integer registers. */
623 else if ((p < md->paramcount) && !md->params[p].inmemory) {
625 v->vv.regoff = md->params[p].regoff;
628 else if (AVAIL_TMP_FLT) {
630 TAKE_TMP_FLT(v->vv.regoff);
632 /* use unused argument registers as local registers */
633 else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
635 POP_FRONT(abi_registers_float_argument,
636 fargcnt, v->vv.regoff);
638 else if (AVAIL_SAV_FLT) {
640 TAKE_SAV_FLT(v->vv.regoff);
644 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
646 fltalloc = jd->local_map[s * 5 + t];
650 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
652 * for i386 put all longs in memory
654 if (IS_2_WORD_TYPE(t)) {
656 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
662 v->flags = VAR(intalloc)->flags;
663 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
664 if (!(v->flags & INMEMORY)
665 && IS_2_WORD_TYPE(VAR(intalloc)->type))
666 v->vv.regoff = GET_LOW_REG(
667 VAR(intalloc)->vv.regoff);
670 v->vv.regoff = VAR(intalloc)->vv.regoff;
672 else if ((p < md->paramcount) &&
673 !md->params[p].inmemory)
676 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
677 if (IS_2_WORD_TYPE(t))
679 PACK_REGS(GET_LOW_REG(md->params[p].regoff),
680 GET_HIGH_REG(md->params[p].regoff));
683 v->vv.regoff = md->params[p].regoff;
685 else if (AVAIL_TMP_INT) {
687 TAKE_TMP_INT(v->vv.regoff);
690 * use unused argument registers as local registers
692 else if ((p >= m->parseddesc->paramcount) &&
693 (iargcnt + intregsneeded < INT_ARG_CNT))
696 POP_FRONT_INT(abi_registers_integer_argument,
697 iargcnt, v->vv.regoff);
699 else if (AVAIL_SAV_INT) {
701 TAKE_SAV_INT(v->vv.regoff);
705 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
708 intalloc = jd->local_map[s * 5 + t];
710 #ifdef HAS_ADDRESS_REGISTER_FILE
713 } /* for (tt=0;...) */
715 /* If the current parameter is a 2-word type, the next local slot */
718 if (p < md->paramcount)
719 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
724 /* simplereg_allocate_locals ***************************************************
726 Allocates registers for all local variables.
728 *******************************************************************************/
730 static void simplereg_allocate_locals(jitdata *jd)
736 int s, t, tt, varindex;
737 int intalloc, fltalloc;
739 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
740 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
744 /* get required compiler data */
750 if (code_is_leafmethod(code)) {
751 simplereg_allocate_locals_leafmethod(jd);
755 for (s = 0; s < jd->maxlocals; s++) {
756 intalloc = -1; fltalloc = -1;
757 for (tt=0; tt<=4; tt++) {
760 varindex = jd->local_map[s * 5 + t];
761 if (varindex == UNUSED)
766 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
767 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
770 #ifdef HAS_ADDRESS_REGISTER_FILE
771 if (IS_ADR_TYPE(t)) {
774 TAKE_SAV_ADR(v->vv.regoff);
778 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
783 if (IS_FLT_DBL_TYPE(t)) {
785 v->flags = VAR(fltalloc)->flags;
786 v->vv.regoff = VAR(fltalloc)->vv.regoff;
788 else if (AVAIL_SAV_FLT) {
790 TAKE_SAV_FLT(v->vv.regoff);
794 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
796 fltalloc = jd->local_map[s * 5 + t];
799 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
801 * for i386 put all longs in memory
803 if (IS_2_WORD_TYPE(t)) {
805 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
810 v->flags = VAR(intalloc)->flags;
811 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
812 if (!(v->flags & INMEMORY)
813 && IS_2_WORD_TYPE(VAR(intalloc)->type))
814 v->vv.regoff = GET_LOW_REG(
815 VAR(intalloc)->vv.regoff);
818 v->vv.regoff = VAR(intalloc)->vv.regoff;
820 else if (AVAIL_SAV_INT) {
822 TAKE_SAV_INT(v->vv.regoff);
826 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
828 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
831 intalloc = jd->local_map[s * 5 + t];
833 #ifdef HAS_ADDRESS_REGISTER_FILE
841 static void simplereg_init(jitdata *jd, registerdata *rd)
847 rd->freetmpinttop = 0;
848 rd->freesavinttop = 0;
849 rd->freetmpflttop = 0;
850 rd->freesavflttop = 0;
851 #ifdef HAS_ADDRESS_REGISTER_FILE
852 rd->freetmpadrtop = 0;
853 rd->freesavadrtop = 0;
856 rd->freearginttop = 0;
857 rd->freeargflttop = 0;
858 #ifdef HAS_ADDRESS_REGISTER_FILE
859 rd->freeargadrtop = 0;
862 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
863 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
864 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
866 /* memcopycount is dynamically allocated when needed */
868 rd->memcopycount = NULL;
869 rd->memcopycountsize = 0;
871 rd->intusedinout = DMNEW(int, INT_REG_CNT);
872 MZERO(rd->intusedinout, int, INT_REG_CNT);
873 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
874 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
876 /* record the interface registers as used */
878 for (i=0; i<rd->argintreguse; ++i)
879 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
880 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
881 rd->intusedinout[rd->tmpintregs[i]] = 1;
882 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
883 rd->intusedinout[rd->savintregs[i]] = 1;
885 for (i=0; i<rd->argfltreguse; ++i)
886 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
887 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
888 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
889 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
890 rd->fltusedinout[rd->savfltregs[i]] = 1;
892 #ifdef HAS_ADDRESS_REGISTER_FILE
893 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
894 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
896 for (i=0; i<rd->argadrreguse; ++i)
897 rd->adrusedinout[rd->argadrregs[i]] = 1;
898 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
899 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
900 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
901 rd->adrusedinout[rd->savadrregs[i]] = 1;
906 static void simplereg_init_block(registerdata *rd)
910 /* remove all interface registers from the free lists */
912 for (i=0; i<rd->freearginttop; ++i)
913 if (rd->intusedinout[rd->freeargintregs[i]]) {
914 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
916 for (i=0; i<rd->freetmpinttop; ++i)
917 if (rd->intusedinout[rd->freetmpintregs[i]]) {
918 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
920 for (i=0; i<rd->freesavinttop; ++i)
921 if (rd->intusedinout[rd->freesavintregs[i]]) {
922 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
925 for (i=0; i<rd->freeargflttop; ++i)
926 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
927 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
929 for (i=0; i<rd->freetmpflttop; ++i)
930 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
931 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
933 for (i=0; i<rd->freesavflttop; ++i)
934 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
935 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
938 #ifdef HAS_ADDRESS_REGISTER_FILE
939 for (i=0; i<rd->freeargadrtop; ++i)
940 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
941 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
943 for (i=0; i<rd->freetmpadrtop; ++i)
944 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
945 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
947 for (i=0; i<rd->freesavadrtop; ++i)
948 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
949 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
955 static void simplereg_new_temp(jitdata *jd, s4 index)
957 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
967 /* assert that constants are not allocated */
969 assert(v->type != TYPE_RET);
971 /* Try to allocate a saved register if there is no temporary one */
972 /* available. This is what happens during the second run. */
973 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
975 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
976 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
979 for(; tryagain; --tryagain) {
981 if (!(v->flags & SAVEDVAR))
983 #ifdef HAS_ADDRESS_REGISTER_FILE
984 if (IS_ADR_TYPE(v->type)) {
985 if (AVAIL_FREE_SAV_ADR) {
986 TAKE_FREE_SAV_ADR(v->vv.regoff);
989 else if (AVAIL_SAV_ADR) {
990 TAKE_SAV_ADR(v->vv.regoff);
997 if (IS_FLT_DBL_TYPE(v->type)) {
998 if (AVAIL_FREE_SAV_FLT) {
999 TAKE_FREE_SAV_FLT(v->vv.regoff);
1002 else if (AVAIL_SAV_FLT) {
1003 TAKE_SAV_FLT(v->vv.regoff);
1008 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1010 * for i386 put all longs in memory
1012 if (!IS_2_WORD_TYPE(v->type))
1015 if (AVAIL_FREE_SAV_INT) {
1016 TAKE_FREE_SAV_INT(v->vv.regoff);
1019 else if (AVAIL_SAV_INT) {
1020 TAKE_SAV_INT(v->vv.regoff);
1027 else { /* tryagain == 2 */
1028 #ifdef HAS_ADDRESS_REGISTER_FILE
1029 if (IS_ADR_TYPE(v->type)) {
1030 if (AVAIL_FREE_TMP_ADR) {
1031 TAKE_FREE_TMP_ADR(v->vv.regoff);
1034 else if (AVAIL_TMP_ADR) {
1035 TAKE_TMP_ADR(v->vv.regoff);
1042 if (IS_FLT_DBL_TYPE(v->type)) {
1043 if (AVAIL_FREE_ARG_FLT) {
1045 TAKE_FREE_ARG_FLT(v->vv.regoff);
1048 else if (AVAIL_ARG_FLT) {
1050 TAKE_ARG_FLT(v->vv.regoff);
1053 else if (AVAIL_FREE_TMP_FLT) {
1054 TAKE_FREE_TMP_FLT(v->vv.regoff);
1057 else if (AVAIL_TMP_FLT) {
1058 TAKE_TMP_FLT(v->vv.regoff);
1064 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1066 * for i386 put all longs in memory
1068 if (!IS_2_WORD_TYPE(v->type))
1071 if (AVAIL_FREE_ARG_INT) {
1073 TAKE_FREE_ARG_INT(v->vv.regoff);
1076 else if (AVAIL_ARG_INT) {
1078 TAKE_ARG_INT(v->vv.regoff);
1081 else if (AVAIL_FREE_TMP_INT) {
1082 TAKE_FREE_TMP_INT(v->vv.regoff);
1085 else if (AVAIL_TMP_INT) {
1086 TAKE_TMP_INT(v->vv.regoff);
1089 } /* if (!IS_2_WORD_TYPE(s->type)) */
1090 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1091 } /* if (IS_ADR_TYPE(s->type)) */
1092 } /* if (tryagain == 1) else */
1093 } /* for(; tryagain; --tryagain) */
1095 /* spill to memory */
1097 v->flags |= INMEMORY;
1099 if (rd->freememtop > 0)
1100 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1102 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1106 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1108 /* assert that constants are not freed */
1110 assert(type != TYPE_RET);
1112 /* if this is a copy of another variable, just decrement the copy counter */
1114 if (flags & INMEMORY) {
1120 memindex = regoff / SIZE_OF_STACKSLOT;
1122 if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
1123 rd->memcopycount[memindex]--;
1130 regindex = REG_INDEX(regoff, type);
1132 /* do not free interface registers that are needed as outvars */
1134 if (flags & INOUT) {
1135 if (rd->regisoutvar[regindex]) {
1136 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1140 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1143 if (rd->regcopycount[regindex]) {
1144 rd->regcopycount[regindex]--;
1149 if (flags & INMEMORY) {
1150 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1154 /* freeing a register */
1156 #ifdef HAS_ADDRESS_REGISTER_FILE
1157 if (IS_ADR_TYPE(type)) {
1158 if (flags & (SAVEDVAR | SAVREG))
1159 PUSH_FREE_SAV_ADR(regoff);
1161 PUSH_FREE_TMP_ADR(regoff);
1164 else if (IS_FLT_DBL_TYPE(type)) {
1165 if (flags & (SAVEDVAR | SAVREG))
1166 PUSH_FREE_SAV_FLT(regoff);
1167 else if (flags & ARGREG)
1168 PUSH_FREE_ARG_FLT(regoff);
1170 PUSH_FREE_TMP_FLT(regoff);
1172 else { /* IS_INT_LNG_TYPE */
1173 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1174 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1177 if (flags & (SAVEDVAR | SAVREG))
1178 PUSH_FREE_SAV_INT(regoff);
1179 else if (flags & ARGREG)
1180 PUSH_FREE_ARG_INT(regoff);
1182 PUSH_FREE_TMP_INT(regoff);
1187 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1193 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1197 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1202 /* do not coalesce local variables here */
1204 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1210 /* do not coalesce in/out vars or preallocated variables here */
1212 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1215 /* if the source is in memory, we can coalesce in any case */
1217 if (sv->flags & INMEMORY) {
1218 dv->flags |= INMEMORY;
1219 dv->vv.regoff = sv->vv.regoff;
1223 /* we do not allocate a REG_TMP to a REG_SAV variable */
1225 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1229 dv->vv.regoff = sv->vv.regoff;
1230 dv->flags |= sv->flags & (SAVREG | ARGREG);
1236 /* simplereg_allocate_temporaries **********************************************
1238 Allocate temporary (non-interface, non-local) registers.
1240 *******************************************************************************/
1242 static void simplereg_allocate_temporaries(jitdata *jd)
1250 builtintable_entry *bte;
1259 /* get required compiler data */
1264 /* initialize temp registers */
1266 simplereg_init(jd, rd);
1268 bptr = jd->basicblocks;
1270 while (bptr != NULL) {
1271 if (bptr->flags >= BBREACHED) {
1273 LOG(("\nallocating block L%03d\n", bptr->nr));
1275 simplereg_init_block(rd);
1277 /* assert that all copy counts are zero */
1279 #if !defined(NDEBUG) && !defined(ENABLE_SSA)
1280 for (i=0; i < TOTAL_REG_CNT; ++i)
1281 assert(rd->regcopycount[i] == 0);
1284 /* reset outvar flags */
1286 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1288 /* set allocation of invars */
1290 for (i=0; i<bptr->indepth; ++i)
1292 v = VAR(bptr->invars[i]);
1293 if (v->type == TYPE_RET)
1296 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1297 v->flags = jd->interface_map[5*i + v->type].flags;
1299 if (!(v->flags & INMEMORY))
1300 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1303 /* set allocation of outvars */
1305 for (i=0; i<bptr->outdepth; ++i)
1307 v = VAR(bptr->outvars[i]);
1308 if (v->type == TYPE_RET)
1311 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1312 v->flags = jd->interface_map[5*i + v->type].flags;
1314 if (!(v->flags & INMEMORY)) {
1315 regindex = REG_INDEX(v->vv.regoff, v->type);
1316 rd->regcopycount[regindex] = 1;
1317 rd->regisoutvar[regindex] = 1;
1321 /* free interface registers not used in this block */
1323 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1325 regoff = jd->interface_map[i].regoff;
1326 flags = jd->interface_map[i].flags;
1328 if (!(flags & INMEMORY)) {
1329 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1330 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1331 flags, regoff, type));
1332 simplereg_free(rd, flags, regoff, type);
1334 /* mark it, so it is not freed again */
1335 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1340 /* reset copy counts */
1342 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1344 /* iterate over ICMDS to allocate temporary variables */
1346 iptr = bptr->iinstr;
1349 while (--len >= 0) {
1351 switch (iptr->opc) {
1357 case ICMD_CHECKNULL:
1362 case ICMD_PUTSTATICCONST:
1363 case ICMD_INLINE_START:
1364 case ICMD_INLINE_END:
1365 case ICMD_INLINE_BODY:
1368 /* pop 0 push 1 const */
1375 case ICMD_GETEXCEPTION:
1377 /* pop 0 push 1 load */
1384 NEW_TEMP_REG(iptr->dst.varindex);
1398 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1399 FREE_TEMP_REG(iptr->s1.varindex);
1400 NEW_TEMP_REG(iptr->dst.varindex);
1414 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1415 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1416 FREE_TEMP_REG(iptr->s1.varindex);
1419 /* pop 1 push 0 store */
1439 case ICMD_PUTSTATIC:
1440 case ICMD_PUTFIELDCONST:
1442 /* pop 1 push 0 branch */
1445 case ICMD_IFNONNULL:
1461 /* pop 1 push 0 table branch */
1463 case ICMD_TABLESWITCH:
1464 case ICMD_LOOKUPSWITCH:
1466 case ICMD_MONITORENTER:
1467 case ICMD_MONITOREXIT:
1468 FREE_TEMP_REG(iptr->s1.varindex);
1471 /* pop 2 push 0 branch */
1473 case ICMD_IF_ICMPEQ:
1474 case ICMD_IF_ICMPNE:
1475 case ICMD_IF_ICMPLT:
1476 case ICMD_IF_ICMPGE:
1477 case ICMD_IF_ICMPGT:
1478 case ICMD_IF_ICMPLE:
1480 case ICMD_IF_LCMPEQ:
1481 case ICMD_IF_LCMPNE:
1482 case ICMD_IF_LCMPLT:
1483 case ICMD_IF_LCMPGE:
1484 case ICMD_IF_LCMPGT:
1485 case ICMD_IF_LCMPLE:
1487 case ICMD_IF_ACMPEQ:
1488 case ICMD_IF_ACMPNE:
1496 case ICMD_IASTORECONST:
1497 case ICMD_LASTORECONST:
1498 case ICMD_AASTORECONST:
1499 case ICMD_BASTORECONST:
1500 case ICMD_CASTORECONST:
1501 case ICMD_SASTORECONST:
1502 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1503 FREE_TEMP_REG(iptr->s1.varindex);
1506 /* pop 0 push 1 copy */
1509 /* src === dst->prev (identical Stackslot Element) */
1510 /* src --> dst (copied value, take same reg/mem) */
1512 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1513 NEW_TEMP_REG(iptr->dst.varindex);
1516 v = VAROP(iptr->dst);
1518 if (v->flags & INMEMORY) {
1519 int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
1520 if (memindex >= rd->memcopycountsize) {
1521 int newsize = (memindex + 1) * 2;
1522 i = rd->memcopycountsize;
1523 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1524 MZERO(rd->memcopycount + i, int, newsize - i);
1525 rd->memcopycountsize = newsize;
1527 rd->memcopycount[memindex]++;
1530 /* XXX split reg/mem variables on arm may need special handling here */
1532 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1534 rd->regcopycount[regindex]++;
1539 /* pop 1 push 1 move */
1542 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1543 NEW_TEMP_REG(iptr->dst.varindex);
1544 FREE_TEMP_REG(iptr->s1.varindex);
1594 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1595 FREE_TEMP_REG(iptr->s1.varindex);
1596 NEW_TEMP_REG(iptr->dst.varindex);
1601 case ICMD_IADDCONST:
1602 case ICMD_ISUBCONST:
1603 case ICMD_IMULCONST:
1607 case ICMD_IANDCONST:
1609 case ICMD_IXORCONST:
1610 case ICMD_ISHLCONST:
1611 case ICMD_ISHRCONST:
1612 case ICMD_IUSHRCONST:
1614 case ICMD_LADDCONST:
1615 case ICMD_LSUBCONST:
1616 case ICMD_LMULCONST:
1620 case ICMD_LANDCONST:
1622 case ICMD_LXORCONST:
1623 case ICMD_LSHLCONST:
1624 case ICMD_LSHRCONST:
1625 case ICMD_LUSHRCONST:
1630 case ICMD_INT2SHORT:
1648 case ICMD_CHECKCAST:
1650 case ICMD_ARRAYLENGTH:
1651 case ICMD_INSTANCEOF:
1654 case ICMD_ANEWARRAY:
1657 FREE_TEMP_REG(iptr->s1.varindex);
1658 NEW_TEMP_REG(iptr->dst.varindex);
1663 case ICMD_GETSTATIC:
1666 NEW_TEMP_REG(iptr->dst.varindex);
1669 /* pop many push any */
1671 case ICMD_INVOKESTATIC:
1672 case ICMD_INVOKESPECIAL:
1673 case ICMD_INVOKEVIRTUAL:
1674 case ICMD_INVOKEINTERFACE:
1675 INSTRUCTION_GET_METHODDESC(iptr,md);
1677 argp = iptr->sx.s23.s2.args;
1679 FREE_TEMP_REG(*argp);
1682 if (md->returntype.type != TYPE_VOID)
1683 NEW_TEMP_REG(iptr->dst.varindex);
1687 bte = iptr->sx.s23.s3.bte;
1690 argp = iptr->sx.s23.s2.args;
1692 FREE_TEMP_REG(*argp);
1695 if (md->returntype.type != TYPE_VOID)
1696 NEW_TEMP_REG(iptr->dst.varindex);
1699 case ICMD_MULTIANEWARRAY:
1700 i = iptr->s1.argcount;
1701 argp = iptr->sx.s23.s2.args;
1703 FREE_TEMP_REG(*argp);
1706 NEW_TEMP_REG(iptr->dst.varindex);
1710 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1715 } /* while instructions */
1718 } /* while blocks */
1722 #if defined(ENABLE_STATISTICS)
1723 void simplereg_make_statistics(jitdata *jd)
1731 stackelement_t* src, src_old;
1732 stackelement_t* dst;
1736 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1740 /* get required compiler data */
1750 /* count how many local variables are held in memory or register */
1751 for(i=0; i < jd->localcount; i++) {
1752 if (VAR(i)->flags & INMEMORY) {
1753 count_locals_spilled++;
1757 count_locals_register++;
1761 /* count how many stack slots are held in memory or register */
1763 bptr = jd->basicblocks;
1765 while (bptr != NULL) {
1766 if (bptr->flags >= BBREACHED) {
1768 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1771 /* check for memory moves from interface to BB instack */
1772 len = bptr->indepth;
1774 if (len > size_interface) size_interface = len;
1778 var = VAR(bptr->invars[len]);
1780 /* invars statistics (currently none) */
1783 /* check for memory moves from BB outstack to interface */
1784 len = bptr->outdepth;
1785 if (len > size_interface) size_interface = len;
1789 var = VAR(bptr->outvars[len]);
1791 /* outvars statistics (currently none) */
1793 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1799 dst = bptr->instack;
1800 iptr = bptr->iinstr;
1804 while (--len >= 0) {
1806 dst = iptr->dst.var;
1808 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1809 switch (src->varkind) {
1812 if (!(src->flags & INMEMORY))
1813 count_ss_register++;
1819 /* case LOCALVAR: */
1820 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1821 /* count_ss_register++; */
1823 /* count_ss_spilled++; */
1826 if (!(src->flags & INMEMORY))
1827 count_argument_mem_ss++;
1829 count_argument_reg_ss++;
1833 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1834 /* if (src->varnum < FLT_ARG_CNT) { */
1835 /* count_ss_register++; */
1839 /* #if defined(__POWERPC__) */
1840 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1842 /* if (src->varnum < INT_ARG_CNT) { */
1844 /* count_ss_register++; */
1848 /* count_ss_spilled++; */
1855 } /* while instructions */
1860 } /* while blocks */
1862 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1863 if (in_register) count_method_in_register++;
1865 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1868 #endif /* defined(ENABLE_STATISTICS) */
1872 * These are local overrides for various environment variables in Emacs.
1873 * Please do not remove this and leave it at the end of the file, where
1874 * Emacs will automagically detect them.
1875 * ---------------------------------------------------------------------
1878 * indent-tabs-mode: t
1882 * vim:noexpandtab:sw=4:ts=4: