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
5 Copyright (C) 2009 Theobroma Systems Ltd.
7 This file is part of CACAO.
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2, or (at
12 your option) any later version.
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
37 #include "mm/memory.hpp"
39 #include "vm/jit/builtin.hpp"
40 #include "vm/exceptions.hpp"
41 #include "vm/method.hpp"
42 #include "vm/options.h"
43 #include "vm/resolve.hpp"
44 #include "vm/string.hpp"
46 #include "vm/jit/abi.h"
47 #include "vm/jit/reg.h"
48 #include "vm/jit/show.hpp"
49 #include "vm/jit/allocator/simplereg.h"
53 # define LOG(args) printf args
59 /* function prototypes for this file ******************************************/
61 static void simplereg_allocate_interfaces(jitdata *jd);
62 static void simplereg_allocate_locals(jitdata *jd);
63 static void simplereg_allocate_temporaries(jitdata *jd);
66 /* size of a stackslot used by the internal ABI */
68 #define SIZE_OF_STACKSLOT 8
71 /* total number of registers */
73 #if defined(HAS_ADDRESS_REGISTER_FILE)
74 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT + ADR_REG_CNT)
76 #define TOTAL_REG_CNT (INT_REG_CNT + FLT_REG_CNT)
80 /* macros for handling register stacks ****************************************/
83 # define AVAIL_FRONT(cnt, limit) (!opt_RegallocSpillAll && ((cnt) < (limit)))
84 # define AVAIL_BACK(cnt) (!opt_RegallocSpillAll && ((cnt) > 0))
86 # define AVAIL_FRONT(cnt, limit) ((cnt) < (limit))
87 # define AVAIL_BACK(cnt) ((cnt) > 0)
90 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
92 # define AVAIL_FRONT_INT(cnt, limit) (!opt_RegallocSpillAll && ((cnt) < (limit) - intregsneeded))
93 # define AVAIL_BACK_INT(cnt) (!opt_RegallocSpillAll && ((cnt) > intregsneeded))
95 # define AVAIL_FRONT_INT(cnt, limit) ((cnt) < (limit) - intregsneeded)
96 # define AVAIL_BACK_INT(cnt) ((cnt) > intregsneeded)
99 # define AVAIL_FRONT_INT(cnt, limit) AVAIL_FRONT(cnt, limit)
100 # define AVAIL_BACK_INT(cnt) AVAIL_BACK(cnt)
103 #define POP_FRONT(stk, cnt, reg) do { reg = stk[cnt++]; } while (0)
104 #define POP_BACK(stk, cnt, reg) do { reg = stk[--cnt]; } while (0)
105 #define PUSH_FRONT(stk, cnt, reg) do { stk[--cnt] = (reg); } while (0)
106 #define PUSH_BACK(stk, cnt, reg) do { stk[cnt++] = (reg); } while (0)
108 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
109 #define POP_FRONT_INT(stk, cnt, reg) \
111 if (intregsneeded) { \
112 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
116 POP_FRONT(stk, cnt, reg); \
119 #define POP_FRONT_INT(stk, cnt, reg) POP_FRONT(stk, cnt, reg)
122 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
123 #define POP_BACK_INT(stk, cnt, reg) \
125 if (intregsneeded) { \
127 reg = PACK_REGS(stk[cnt], stk[cnt+1]); \
130 POP_BACK(stk, cnt, reg); \
133 #define POP_BACK_INT(stk, cnt, reg) POP_BACK(stk, cnt, reg)
136 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
137 #define PUSH_BACK_INT(stk, cnt, reg) \
139 if (intregsneeded) { \
140 stk[cnt] = GET_LOW_REG(reg); \
141 stk[cnt + 1] = GET_HIGH_REG(reg); \
145 PUSH_BACK(stk, cnt, reg); \
148 #define PUSH_BACK_INT(stk, cnt, reg) PUSH_BACK(stk, cnt, reg)
151 #define AVAIL_ARG_FLT AVAIL_FRONT(rd->argfltreguse, FLT_ARG_CNT)
152 #define AVAIL_TMP_FLT AVAIL_BACK(rd->tmpfltreguse)
153 #define AVAIL_SAV_FLT AVAIL_BACK(rd->savfltreguse)
155 #define AVAIL_ARG_ADR AVAIL_FRONT(rd->argadrreguse, ADR_ARG_CNT)
156 #define AVAIL_TMP_ADR AVAIL_BACK(rd->tmpadrreguse)
157 #define AVAIL_SAV_ADR AVAIL_BACK(rd->savadrreguse)
159 #define AVAIL_ARG_INT AVAIL_FRONT_INT(rd->argintreguse, INT_ARG_CNT)
160 #define AVAIL_TMP_INT AVAIL_BACK_INT(rd->tmpintreguse)
161 #define AVAIL_SAV_INT AVAIL_BACK_INT(rd->savintreguse)
163 #define AVAIL_FREE_ARG_FLT AVAIL_BACK(rd->freeargflttop)
164 #define AVAIL_FREE_TMP_FLT AVAIL_BACK(rd->freetmpflttop)
165 #define AVAIL_FREE_SAV_FLT AVAIL_BACK(rd->freesavflttop)
167 #define AVAIL_FREE_ARG_ADR AVAIL_BACK(rd->freeargadrtop)
168 #define AVAIL_FREE_TMP_ADR AVAIL_BACK(rd->freetmpadrtop)
169 #define AVAIL_FREE_SAV_ADR AVAIL_BACK(rd->freesavadrtop)
171 #define AVAIL_FREE_ARG_INT AVAIL_BACK_INT(rd->freearginttop)
172 #define AVAIL_FREE_TMP_INT AVAIL_BACK_INT(rd->freetmpinttop)
173 #define AVAIL_FREE_SAV_INT AVAIL_BACK_INT(rd->freesavinttop)
175 #define TAKE_ARG_FLT(r) POP_FRONT(abi_registers_float_argument, rd->argfltreguse, r)
176 #define TAKE_TMP_FLT(r) POP_BACK(rd->tmpfltregs, rd->tmpfltreguse, r)
177 #define TAKE_SAV_FLT(r) POP_BACK(rd->savfltregs, rd->savfltreguse, r)
179 #define TAKE_ARG_ADR(r) POP_FRONT(rd->argadrregs, rd->argadrreguse, r)
180 #define TAKE_TMP_ADR(r) POP_BACK(rd->tmpadrregs, rd->tmpadrreguse, r)
181 #define TAKE_SAV_ADR(r) POP_BACK(rd->savadrregs, rd->savadrreguse, r)
183 #define TAKE_ARG_INT(r) POP_FRONT_INT(abi_registers_integer_argument, rd->argintreguse, r)
184 #define TAKE_TMP_INT(r) POP_BACK_INT(rd->tmpintregs, rd->tmpintreguse, r)
185 #define TAKE_SAV_INT(r) POP_BACK_INT(rd->savintregs, rd->savintreguse, r)
187 #define TAKE_FREE_ARG_FLT(r) POP_BACK(rd->freeargfltregs, rd->freeargflttop, r)
188 #define TAKE_FREE_TMP_FLT(r) POP_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
189 #define TAKE_FREE_SAV_FLT(r) POP_BACK(rd->freesavfltregs, rd->freesavflttop, r)
191 #define TAKE_FREE_ARG_ADR(r) POP_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
192 #define TAKE_FREE_TMP_ADR(r) POP_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
193 #define TAKE_FREE_SAV_ADR(r) POP_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
195 #define TAKE_FREE_ARG_INT(r) POP_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
196 #define TAKE_FREE_TMP_INT(r) POP_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
197 #define TAKE_FREE_SAV_INT(r) POP_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
199 #define PUSH_FREE_ARG_FLT(r) PUSH_BACK(rd->freeargfltregs, rd->freeargflttop, r)
200 #define PUSH_FREE_TMP_FLT(r) PUSH_BACK(rd->freetmpfltregs, rd->freetmpflttop, r)
201 #define PUSH_FREE_SAV_FLT(r) PUSH_BACK(rd->freesavfltregs, rd->freesavflttop, r)
203 #define PUSH_FREE_ARG_ADR(r) PUSH_BACK(rd->freeargadrregs, rd->freeargadrtop, r)
204 #define PUSH_FREE_TMP_ADR(r) PUSH_BACK(rd->freetmpadrregs, rd->freetmpadrtop, r)
205 #define PUSH_FREE_SAV_ADR(r) PUSH_BACK(rd->freesavadrregs, rd->freesavadrtop, r)
207 #define PUSH_FREE_ARG_INT(r) PUSH_BACK_INT(rd->freeargintregs, rd->freearginttop, r)
208 #define PUSH_FREE_TMP_INT(r) PUSH_BACK_INT(rd->freetmpintregs, rd->freetmpinttop, r)
209 #define PUSH_FREE_SAV_INT(r) PUSH_BACK_INT(rd->freesavintregs, rd->freesavinttop, r)
212 /* macros for allocating memory slots ****************************************/
214 #define NEW_MEM_SLOT(r) \
216 (r) = rd->memuse * SIZE_OF_STACKSLOT; \
220 #define NEW_MEM_SLOT_INT_LNG(r) NEW_MEM_SLOT(r)
221 #define NEW_MEM_SLOT_FLT_DBL(r) NEW_MEM_SLOT(r)
222 #define NEW_MEM_SLOT_REUSE_PADDING(r) NEW_MEM_SLOT(r)
225 /* macros for creating/freeing temporary variables ***************************/
227 #define NEW_TEMP_REG(index) \
228 if ( ((index) >= jd->localcount) \
229 && (!(VAR(index)->flags & (INOUT | PREALLOC))) ) \
230 simplereg_new_temp(jd, (index))
233 #define FREE_TEMP_REG(index) \
234 if (((index) > jd->localcount) \
235 && (!(VAR(index)->flags & (PREALLOC)))) \
236 simplereg_free_temp(jd, (index))
239 /* macro for getting a unique register index *********************************/
241 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
242 #define REG_INDEX_NON_ADR(regoff, type) \
243 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (GET_LOW_REG(regoff)))
245 #define REG_INDEX_NON_ADR(regoff, type) \
246 (IS_FLT_DBL_TYPE(type) ? (INT_REG_CNT + (regoff)) : (regoff))
249 #if defined(HAS_ADDRESS_REGISTER_FILE)
250 #define REG_INDEX(regoff, type) \
251 (IS_ADR_TYPE(type) ? (regoff) : (ADR_REG_CNT + REG_INDEX_NON_ADR(regoff, type)))
253 #define REG_INDEX(regoff, type) REG_INDEX_NON_ADR(regoff, type)
257 /* regalloc ********************************************************************
259 Does a simple register allocation.
261 *******************************************************************************/
263 bool regalloc(jitdata *jd)
265 /* There is a problem with the use of unused float argument
266 registers in leafmethods for stackslots on c7 (2 * Dual Core
267 AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
268 benchmark is heaviliy increased. This could be prevented by
269 setting rd->argfltreguse to FLT_ARG_CNT before calling
270 simplereg_allocate_temporaries and setting it back to the original
271 value before calling simplereg_allocate_locals. */
273 simplereg_allocate_interfaces(jd);
274 simplereg_allocate_temporaries(jd);
275 simplereg_allocate_locals(jd);
283 /* simplereg_allocate_interfaces ***********************************************
285 Allocates registers for all interface variables.
287 *******************************************************************************/
289 static void simplereg_allocate_interfaces(jitdata *jd)
297 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
298 /* in case more vars are packed into this interface slot */
299 /* Allocate LNG and DBL types first to ensure 2 registers */
300 /* on some architectures. */
301 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
303 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
307 /* get required compiler data */
314 /* rd->memuse was already set in stack.c to allocate stack space
315 for passing arguments to called methods. */
317 #if defined(__I386__)
318 if (checksync && code_is_synchronized(code)) {
319 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
325 if (code_is_leafmethod(code)) {
326 /* Reserve argument register, which will be used for Locals acting */
328 if (rd->argintreguse < m->parseddesc->argintreguse)
329 rd->argintreguse = m->parseddesc->argintreguse;
330 if (rd->argfltreguse < m->parseddesc->argfltreguse)
331 rd->argfltreguse = m->parseddesc->argfltreguse;
332 #ifdef HAS_ADDRESS_REGISTER_FILE
333 if (rd->argadrreguse < m->parseddesc->argadrreguse)
334 rd->argadrreguse = m->parseddesc->argadrreguse;
338 for (s = 0; s < jd->maxinterfaces; s++) {
339 intalloc = -1; fltalloc = -1;
341 /* check if the interface at this stack depth must be a SAVEDVAR */
345 for (tt = 0; tt <=4; tt++) {
346 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
347 saved |= t & SAVEDVAR;
351 /* allocate reg/mem for each type the interface is used as */
353 for (tt = 0; tt <= 4; tt++) {
355 if (jd->interface_map[s * 5 + t].flags == UNUSED)
359 regoff = -1; /* initialize to invalid value */
361 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
362 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
366 #if defined(HAS_ADDRESS_REGISTER_FILE)
367 if (IS_ADR_TYPE(t)) {
368 if (!code_is_leafmethod(code) && AVAIL_ARG_ADR) {
370 TAKE_ARG_ADR(regoff);
372 else if (AVAIL_TMP_ADR) {
373 TAKE_TMP_ADR(regoff);
375 else if (AVAIL_SAV_ADR) {
377 TAKE_SAV_ADR(regoff);
381 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
384 else /* !IS_ADR_TYPE */
385 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
387 if (IS_FLT_DBL_TYPE(t)) {
389 /* Reuse memory slot(s)/register(s) for shared interface slots */
390 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
391 regoff = jd->interface_map[fltalloc].regoff;
393 else if (AVAIL_ARG_FLT) {
395 TAKE_ARG_FLT(regoff);
397 else if (AVAIL_TMP_FLT) {
398 TAKE_TMP_FLT(regoff);
400 else if (AVAIL_SAV_FLT) {
402 TAKE_SAV_FLT(regoff);
406 NEW_MEM_SLOT_FLT_DBL(regoff);
408 fltalloc = s * 5 + t;
410 else { /* !IS_FLT_DBL_TYPE(t) */
411 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
413 * for i386 put all longs in memory
415 if (IS_2_WORD_TYPE(t)) {
417 NEW_MEM_SLOT_INT_LNG(regoff);
422 /* Reuse memory slot(s)/register(s) for shared interface slots */
423 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
424 regoff = jd->interface_map[intalloc].regoff;
425 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
426 /* reuse lower half */
427 if (!(flags & INMEMORY)
428 && IS_2_WORD_TYPE(intalloc % 5))
429 regoff = GET_LOW_REG(regoff);
435 TAKE_ARG_INT(regoff);
437 else if (AVAIL_TMP_INT) {
438 TAKE_TMP_INT(regoff);
440 else if (AVAIL_SAV_INT) {
442 TAKE_SAV_INT(regoff);
446 NEW_MEM_SLOT_INT_LNG(regoff);
450 intalloc = s * 5 + t;
451 } /* if (IS_FLT_DBL_TYPE(t)) */
455 /* now the same like above, but without a chance to take a temporary register */
456 #ifdef HAS_ADDRESS_REGISTER_FILE
457 if (IS_ADR_TYPE(t)) {
459 TAKE_SAV_ADR(regoff);
463 regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
469 if (IS_FLT_DBL_TYPE(t)) {
471 flags |= jd->interface_map[fltalloc].flags & ~SAVEDVAR;
472 regoff = jd->interface_map[fltalloc].regoff;
476 TAKE_SAV_FLT(regoff);
480 NEW_MEM_SLOT_FLT_DBL(regoff);
483 fltalloc = s * 5 + t;
485 else { /* IS_INT_LNG */
486 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
488 * for i386 put all longs in memory
490 if (IS_2_WORD_TYPE(t)) {
492 NEW_MEM_SLOT_INT_LNG(regoff);
498 flags |= jd->interface_map[intalloc].flags & ~SAVEDVAR;
499 regoff = jd->interface_map[intalloc].regoff;
500 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
501 /* reuse lower half */
502 if (!(flags & INMEMORY)
503 && IS_2_WORD_TYPE(intalloc % 5))
504 regoff = GET_LOW_REG(regoff);
509 TAKE_SAV_INT(regoff);
513 NEW_MEM_SLOT_INT_LNG(regoff);
518 } /* if (IS_FLT_DBL_TYPE(t) else */
519 } /* if (IS_ADR_TYPE(t)) else */
520 } /* if (saved) else */
524 jd->interface_map[5*s + t].flags = flags | INOUT;
525 jd->interface_map[5*s + t].regoff = regoff;
531 /* simplereg_allocate_locals_leafmethod ****************************************
533 Allocates registers for all local variables of a leafmethod.
535 *******************************************************************************/
537 static void simplereg_allocate_locals_leafmethod(jitdata *jd)
544 int p, s, t, tt, varindex;
545 int intalloc, fltalloc;
547 int intregsneeded = 0;
548 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
549 int fargcnt, iargcnt;
550 #ifdef HAS_ADDRESS_REGISTER_FILE
554 /* get required compiler data */
562 iargcnt = rd->argintreguse;
563 fargcnt = rd->argfltreguse;
564 #ifdef HAS_ADDRESS_REGISTER_FILE
565 aargcnt = rd->argadrreguse;
567 for (p = 0, s = 0; s < jd->maxlocals; s++, p++) {
568 intalloc = -1; fltalloc = -1;
569 for (tt = 0; tt <= 4; tt++) {
571 varindex = jd->local_map[s * 5 + t];
572 if (varindex == UNUSED)
577 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
578 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
584 * #ifdef HAS_ADDRESS_REGISTER_FILE
591 * } else { / int & lng
595 * must not to be changed!
598 #ifdef HAS_ADDRESS_REGISTER_FILE
599 if (IS_ADR_TYPE(t)) {
600 if ((p < md->paramcount) && !md->params[p].inmemory) {
602 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
604 else if (AVAIL_TMP_ADR) {
606 TAKE_TMP_ADR(v->vv.regoff);
608 /* use unused argument registers as local registers */
609 else if ((p >= md->paramcount) &&
610 (aargcnt < ADR_ARG_CNT))
613 POP_FRONT(rd->argadrregs, aargcnt, v->vv.regoff);
615 else if (AVAIL_SAV_ADR) {
617 TAKE_SAV_ADR(v->vv.regoff);
620 v->flags |= INMEMORY;
621 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
626 if (IS_FLT_DBL_TYPE(t)) {
628 v->flags = VAR(fltalloc)->flags;
629 v->vv.regoff = VAR(fltalloc)->vv.regoff;
631 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
632 /* We can only use float arguments as local variables,
633 * if we do not pass them in integer registers. */
634 else if ((p < md->paramcount) && !md->params[p].inmemory) {
636 v->vv.regoff = md->params[p].regoff;
639 else if (AVAIL_TMP_FLT) {
641 TAKE_TMP_FLT(v->vv.regoff);
643 /* use unused argument registers as local registers */
644 else if ((p >= md->paramcount) && (fargcnt < FLT_ARG_CNT)) {
646 POP_FRONT(abi_registers_float_argument,
647 fargcnt, v->vv.regoff);
649 else if (AVAIL_SAV_FLT) {
651 TAKE_SAV_FLT(v->vv.regoff);
655 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
657 fltalloc = jd->local_map[s * 5 + t];
661 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
663 * for i386 put all longs in memory
665 if (IS_2_WORD_TYPE(t)) {
667 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
673 v->flags = VAR(intalloc)->flags;
674 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
675 if (!(v->flags & INMEMORY)
676 && IS_2_WORD_TYPE(VAR(intalloc)->type))
677 v->vv.regoff = GET_LOW_REG(
678 VAR(intalloc)->vv.regoff);
681 v->vv.regoff = VAR(intalloc)->vv.regoff;
683 else if ((p < md->paramcount) &&
684 !md->params[p].inmemory)
687 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
688 if (IS_2_WORD_TYPE(t))
690 PACK_REGS(GET_LOW_REG(md->params[p].regoff),
691 GET_HIGH_REG(md->params[p].regoff));
694 v->vv.regoff = md->params[p].regoff;
696 else if (AVAIL_TMP_INT) {
698 TAKE_TMP_INT(v->vv.regoff);
701 * use unused argument registers as local registers
703 else if ((p >= m->parseddesc->paramcount) &&
704 (iargcnt + intregsneeded < INT_ARG_CNT))
707 POP_FRONT_INT(abi_registers_integer_argument,
708 iargcnt, v->vv.regoff);
710 else if (AVAIL_SAV_INT) {
712 TAKE_SAV_INT(v->vv.regoff);
716 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
719 intalloc = jd->local_map[s * 5 + t];
721 #ifdef HAS_ADDRESS_REGISTER_FILE
724 } /* for (tt=0;...) */
726 /* If the current parameter is a 2-word type, the next local slot */
729 if (p < md->paramcount)
730 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
735 /* simplereg_allocate_locals ***************************************************
737 Allocates registers for all local variables.
739 *******************************************************************************/
741 static void simplereg_allocate_locals(jitdata *jd)
747 int s, t, tt, varindex;
748 int intalloc, fltalloc;
750 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
751 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
755 /* get required compiler data */
761 if (code_is_leafmethod(code)) {
762 simplereg_allocate_locals_leafmethod(jd);
766 for (s = 0; s < jd->maxlocals; s++) {
767 intalloc = -1; fltalloc = -1;
768 for (tt=0; tt<=4; tt++) {
771 varindex = jd->local_map[s * 5 + t];
772 if (varindex == UNUSED)
777 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
778 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
781 #ifdef HAS_ADDRESS_REGISTER_FILE
782 if (IS_ADR_TYPE(t)) {
785 TAKE_SAV_ADR(v->vv.regoff);
789 v->vv.regoff = rd->memuse++ * SIZE_OF_STACKSLOT;
794 if (IS_FLT_DBL_TYPE(t)) {
796 v->flags = VAR(fltalloc)->flags;
797 v->vv.regoff = VAR(fltalloc)->vv.regoff;
799 else if (AVAIL_SAV_FLT) {
801 TAKE_SAV_FLT(v->vv.regoff);
805 NEW_MEM_SLOT_FLT_DBL(v->vv.regoff);
807 fltalloc = jd->local_map[s * 5 + t];
810 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
812 * for i386 put all longs in memory
814 if (IS_2_WORD_TYPE(t)) {
816 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
821 v->flags = VAR(intalloc)->flags;
822 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
823 if (!(v->flags & INMEMORY)
824 && IS_2_WORD_TYPE(VAR(intalloc)->type))
825 v->vv.regoff = GET_LOW_REG(
826 VAR(intalloc)->vv.regoff);
829 v->vv.regoff = VAR(intalloc)->vv.regoff;
831 else if (AVAIL_SAV_INT) {
833 TAKE_SAV_INT(v->vv.regoff);
837 NEW_MEM_SLOT_INT_LNG(v->vv.regoff);
839 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
842 intalloc = jd->local_map[s * 5 + t];
844 #ifdef HAS_ADDRESS_REGISTER_FILE
852 static void simplereg_init(jitdata *jd, registerdata *rd)
858 rd->freetmpinttop = 0;
859 rd->freesavinttop = 0;
860 rd->freetmpflttop = 0;
861 rd->freesavflttop = 0;
862 #ifdef HAS_ADDRESS_REGISTER_FILE
863 rd->freetmpadrtop = 0;
864 rd->freesavadrtop = 0;
867 rd->freearginttop = 0;
868 rd->freeargflttop = 0;
869 #ifdef HAS_ADDRESS_REGISTER_FILE
870 rd->freeargadrtop = 0;
873 rd->regisoutvar = DMNEW(int, TOTAL_REG_CNT);
874 rd->regcopycount = DMNEW(int, TOTAL_REG_CNT);
875 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
877 /* memcopycount is dynamically allocated when needed */
879 rd->memcopycount = NULL;
880 rd->memcopycountsize = 0;
882 rd->intusedinout = DMNEW(int, INT_REG_CNT);
883 MZERO(rd->intusedinout, int, INT_REG_CNT);
884 rd->fltusedinout = DMNEW(int, FLT_REG_CNT);
885 MZERO(rd->fltusedinout, int, FLT_REG_CNT);
887 /* record the interface registers as used */
889 for (i=0; i<rd->argintreguse; ++i)
890 rd->intusedinout[abi_registers_integer_argument[i]] = 1;
891 for (i=rd->tmpintreguse; i<INT_TMP_CNT; ++i)
892 rd->intusedinout[rd->tmpintregs[i]] = 1;
893 for (i=rd->savintreguse; i<INT_SAV_CNT; ++i)
894 rd->intusedinout[rd->savintregs[i]] = 1;
896 for (i=0; i<rd->argfltreguse; ++i)
897 rd->fltusedinout[abi_registers_float_argument[i]] = 1;
898 for (i=rd->tmpfltreguse; i<FLT_TMP_CNT; ++i)
899 rd->fltusedinout[rd->tmpfltregs[i]] = 1;
900 for (i=rd->savfltreguse; i<FLT_SAV_CNT; ++i)
901 rd->fltusedinout[rd->savfltregs[i]] = 1;
903 #ifdef HAS_ADDRESS_REGISTER_FILE
904 rd->adrusedinout = DMNEW(int, ADR_REG_CNT);
905 MZERO(rd->adrusedinout, int, ADR_REG_CNT);
907 for (i=0; i<rd->argadrreguse; ++i)
908 rd->adrusedinout[rd->argadrregs[i]] = 1;
909 for (i=rd->tmpadrreguse; i<ADR_TMP_CNT; ++i)
910 rd->adrusedinout[rd->tmpadrregs[i]] = 1;
911 for (i=rd->savadrreguse; i<ADR_SAV_CNT; ++i)
912 rd->adrusedinout[rd->savadrregs[i]] = 1;
917 static void simplereg_init_block(registerdata *rd)
921 /* remove all interface registers from the free lists */
923 for (i=0; i<rd->freearginttop; ++i)
924 if (rd->intusedinout[rd->freeargintregs[i]]) {
925 rd->freeargintregs[i--] = rd->freeargintregs[--rd->freearginttop];
927 for (i=0; i<rd->freetmpinttop; ++i)
928 if (rd->intusedinout[rd->freetmpintregs[i]]) {
929 rd->freetmpintregs[i--] = rd->freetmpintregs[--rd->freetmpinttop];
931 for (i=0; i<rd->freesavinttop; ++i)
932 if (rd->intusedinout[rd->freesavintregs[i]]) {
933 rd->freesavintregs[i--] = rd->freesavintregs[--rd->freesavinttop];
936 for (i=0; i<rd->freeargflttop; ++i)
937 if (rd->fltusedinout[rd->freeargfltregs[i]]) {
938 rd->freeargfltregs[i--] = rd->freeargfltregs[--rd->freeargflttop];
940 for (i=0; i<rd->freetmpflttop; ++i)
941 if (rd->fltusedinout[rd->freetmpfltregs[i]]) {
942 rd->freetmpfltregs[i--] = rd->freetmpfltregs[--rd->freetmpflttop];
944 for (i=0; i<rd->freesavflttop; ++i)
945 if (rd->fltusedinout[rd->freesavfltregs[i]]) {
946 rd->freesavfltregs[i--] = rd->freesavfltregs[--rd->freesavflttop];
949 #ifdef HAS_ADDRESS_REGISTER_FILE
950 for (i=0; i<rd->freeargadrtop; ++i)
951 if (rd->adrusedinout[rd->freeargadrregs[i]]) {
952 rd->freeargadrregs[i--] = rd->freeargadrregs[--rd->freeargadrtop];
954 for (i=0; i<rd->freetmpadrtop; ++i)
955 if (rd->adrusedinout[rd->freetmpadrregs[i]]) {
956 rd->freetmpadrregs[i--] = rd->freetmpadrregs[--rd->freetmpadrtop];
958 for (i=0; i<rd->freesavadrtop; ++i)
959 if (rd->adrusedinout[rd->freesavadrregs[i]]) {
960 rd->freesavadrregs[i--] = rd->freesavadrregs[--rd->freesavadrtop];
966 static void simplereg_new_temp(jitdata *jd, s4 index)
968 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
978 /* assert that constants are not allocated */
980 assert(v->type != TYPE_RET);
982 /* Try to allocate a saved register if there is no temporary one */
983 /* available. This is what happens during the second run. */
984 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
986 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
987 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
990 for(; tryagain; --tryagain) {
992 if (!(v->flags & SAVEDVAR))
994 #ifdef HAS_ADDRESS_REGISTER_FILE
995 if (IS_ADR_TYPE(v->type)) {
996 if (AVAIL_FREE_SAV_ADR) {
997 TAKE_FREE_SAV_ADR(v->vv.regoff);
1000 else if (AVAIL_SAV_ADR) {
1001 TAKE_SAV_ADR(v->vv.regoff);
1008 if (IS_FLT_DBL_TYPE(v->type)) {
1009 if (AVAIL_FREE_SAV_FLT) {
1010 TAKE_FREE_SAV_FLT(v->vv.regoff);
1013 else if (AVAIL_SAV_FLT) {
1014 TAKE_SAV_FLT(v->vv.regoff);
1019 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1021 * for i386 put all longs in memory
1023 if (!IS_2_WORD_TYPE(v->type))
1026 if (AVAIL_FREE_SAV_INT) {
1027 TAKE_FREE_SAV_INT(v->vv.regoff);
1030 else if (AVAIL_SAV_INT) {
1031 TAKE_SAV_INT(v->vv.regoff);
1038 else { /* tryagain == 2 */
1039 #ifdef HAS_ADDRESS_REGISTER_FILE
1040 if (IS_ADR_TYPE(v->type)) {
1041 if (AVAIL_FREE_TMP_ADR) {
1042 TAKE_FREE_TMP_ADR(v->vv.regoff);
1045 else if (AVAIL_TMP_ADR) {
1046 TAKE_TMP_ADR(v->vv.regoff);
1053 if (IS_FLT_DBL_TYPE(v->type)) {
1054 if (AVAIL_FREE_ARG_FLT) {
1056 TAKE_FREE_ARG_FLT(v->vv.regoff);
1059 else if (AVAIL_ARG_FLT) {
1061 TAKE_ARG_FLT(v->vv.regoff);
1064 else if (AVAIL_FREE_TMP_FLT) {
1065 TAKE_FREE_TMP_FLT(v->vv.regoff);
1068 else if (AVAIL_TMP_FLT) {
1069 TAKE_TMP_FLT(v->vv.regoff);
1075 #if (SIZEOF_VOID_P == 4) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1077 * for i386 put all longs in memory
1079 if (!IS_2_WORD_TYPE(v->type))
1082 if (AVAIL_FREE_ARG_INT) {
1084 TAKE_FREE_ARG_INT(v->vv.regoff);
1087 else if (AVAIL_ARG_INT) {
1089 TAKE_ARG_INT(v->vv.regoff);
1092 else if (AVAIL_FREE_TMP_INT) {
1093 TAKE_FREE_TMP_INT(v->vv.regoff);
1096 else if (AVAIL_TMP_INT) {
1097 TAKE_TMP_INT(v->vv.regoff);
1100 } /* if (!IS_2_WORD_TYPE(s->type)) */
1101 } /* if (IS_FLT_DBL_TYPE(s->type)) */
1102 } /* if (IS_ADR_TYPE(s->type)) */
1103 } /* if (tryagain == 1) else */
1104 } /* for(; tryagain; --tryagain) */
1106 /* spill to memory */
1108 v->flags |= INMEMORY;
1110 if (rd->freememtop > 0)
1111 POP_BACK(rd->freemem, rd->freememtop, v->vv.regoff);
1113 NEW_MEM_SLOT_REUSE_PADDING(v->vv.regoff);
1117 static void simplereg_free(registerdata *rd, s4 flags, s4 regoff, s4 type)
1119 /* assert that constants are not freed */
1121 assert(type != TYPE_RET);
1123 /* if this is a copy of another variable, just decrement the copy counter */
1125 if (flags & INMEMORY) {
1131 memindex = regoff / SIZE_OF_STACKSLOT;
1133 if (memindex < rd->memcopycountsize && rd->memcopycount[memindex]) {
1134 rd->memcopycount[memindex]--;
1141 regindex = REG_INDEX(regoff, type);
1143 /* do not free interface registers that are needed as outvars */
1145 if (flags & INOUT) {
1146 if (rd->regisoutvar[regindex]) {
1147 LOG(("DONT FREE f=%02x r=%d t=%d\n", flags, regoff, type));
1151 LOG(("FREEING INVAR f=%02x r=%d t=%d\n", flags, regoff, type));
1154 if (rd->regcopycount[regindex]) {
1155 rd->regcopycount[regindex]--;
1160 if (flags & INMEMORY) {
1161 PUSH_BACK(rd->freemem, rd->freememtop, regoff);
1165 /* freeing a register */
1167 #ifdef HAS_ADDRESS_REGISTER_FILE
1168 if (IS_ADR_TYPE(type)) {
1169 if (flags & (SAVEDVAR | SAVREG))
1170 PUSH_FREE_SAV_ADR(regoff);
1172 PUSH_FREE_TMP_ADR(regoff);
1175 else if (IS_FLT_DBL_TYPE(type)) {
1176 if (flags & (SAVEDVAR | SAVREG))
1177 PUSH_FREE_SAV_FLT(regoff);
1178 else if (flags & ARGREG)
1179 PUSH_FREE_ARG_FLT(regoff);
1181 PUSH_FREE_TMP_FLT(regoff);
1183 else { /* IS_INT_LNG_TYPE */
1184 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1185 s4 intregsneeded = (IS_2_WORD_TYPE(type)) ? 1 : 0;
1188 if (flags & (SAVEDVAR | SAVREG))
1189 PUSH_FREE_SAV_INT(regoff);
1190 else if (flags & ARGREG)
1191 PUSH_FREE_ARG_INT(regoff);
1193 PUSH_FREE_TMP_INT(regoff);
1198 static inline void simplereg_free_temp(jitdata *jd, s4 index)
1204 simplereg_free(jd->rd, v->flags, v->vv.regoff, v->type);
1208 static bool simplereg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1213 /* do not coalesce local variables here */
1215 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1221 /* do not coalesce in/out vars or preallocated variables here */
1223 if ((sv->flags | dv->flags) & (INOUT | PREALLOC))
1226 /* if the source is in memory, we can coalesce in any case */
1228 if (sv->flags & INMEMORY) {
1229 dv->flags |= INMEMORY;
1230 dv->vv.regoff = sv->vv.regoff;
1234 /* we do not allocate a REG_TMP to a REG_SAV variable */
1236 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1240 dv->vv.regoff = sv->vv.regoff;
1241 dv->flags |= sv->flags & (SAVREG | ARGREG);
1247 /* simplereg_allocate_temporaries **********************************************
1249 Allocate temporary (non-interface, non-local) registers.
1251 *******************************************************************************/
1253 static void simplereg_allocate_temporaries(jitdata *jd)
1261 builtintable_entry *bte;
1270 /* get required compiler data */
1275 /* initialize temp registers */
1277 simplereg_init(jd, rd);
1279 bptr = jd->basicblocks;
1281 while (bptr != NULL) {
1282 if (bptr->flags >= BBREACHED) {
1284 LOG(("\nallocating block L%03d\n", bptr->nr));
1286 simplereg_init_block(rd);
1288 /* assert that all copy counts are zero */
1290 #if !defined(NDEBUG) && !defined(ENABLE_SSA)
1291 for (i=0; i < TOTAL_REG_CNT; ++i)
1292 assert(rd->regcopycount[i] == 0);
1295 /* reset outvar flags */
1297 MZERO(rd->regisoutvar, int, TOTAL_REG_CNT);
1299 /* set allocation of invars */
1301 for (i=0; i<bptr->indepth; ++i)
1303 v = VAR(bptr->invars[i]);
1304 if (v->type == TYPE_RET)
1307 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1308 v->flags = jd->interface_map[5*i + v->type].flags;
1310 if (!(v->flags & INMEMORY))
1311 rd->regcopycount[REG_INDEX(v->vv.regoff, v->type)] = 1;
1314 /* set allocation of outvars */
1316 for (i=0; i<bptr->outdepth; ++i)
1318 v = VAR(bptr->outvars[i]);
1319 if (v->type == TYPE_RET)
1322 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1323 v->flags = jd->interface_map[5*i + v->type].flags;
1325 if (!(v->flags & INMEMORY)) {
1326 regindex = REG_INDEX(v->vv.regoff, v->type);
1327 rd->regcopycount[regindex] = 1;
1328 rd->regisoutvar[regindex] = 1;
1332 /* free interface registers not used in this block */
1334 for (i=0; i < 5 * jd->maxinterfaces; ++i) {
1336 regoff = jd->interface_map[i].regoff;
1337 flags = jd->interface_map[i].flags;
1339 if (!(flags & INMEMORY)) {
1340 if (!rd->regcopycount[REG_INDEX(regoff, type)]) {
1341 LOG(("MAY REUSE interface register f=%02x r=%d t=%d\n",
1342 flags, regoff, type));
1343 simplereg_free(rd, flags, regoff, type);
1345 /* mark it, so it is not freed again */
1346 rd->regcopycount[REG_INDEX(regoff, type)] = -1;
1351 /* reset copy counts */
1353 MZERO(rd->regcopycount, int, TOTAL_REG_CNT);
1355 /* iterate over ICMDS to allocate temporary variables */
1357 iptr = bptr->iinstr;
1360 while (--len >= 0) {
1362 switch (iptr->opc) {
1368 case ICMD_CHECKNULL:
1373 case ICMD_PUTSTATICCONST:
1374 case ICMD_INLINE_START:
1375 case ICMD_INLINE_END:
1376 case ICMD_INLINE_BODY:
1379 /* pop 0 push 1 const */
1386 case ICMD_GETEXCEPTION:
1388 /* pop 0 push 1 load */
1395 NEW_TEMP_REG(iptr->dst.varindex);
1409 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1410 FREE_TEMP_REG(iptr->s1.varindex);
1411 NEW_TEMP_REG(iptr->dst.varindex);
1425 FREE_TEMP_REG(iptr->sx.s23.s3.varindex);
1426 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1427 FREE_TEMP_REG(iptr->s1.varindex);
1430 /* pop 1 push 0 store */
1450 case ICMD_PUTSTATIC:
1451 case ICMD_PUTFIELDCONST:
1453 /* pop 1 push 0 branch */
1456 case ICMD_IFNONNULL:
1472 /* pop 1 push 0 table branch */
1474 case ICMD_TABLESWITCH:
1475 case ICMD_LOOKUPSWITCH:
1477 case ICMD_MONITORENTER:
1478 case ICMD_MONITOREXIT:
1479 FREE_TEMP_REG(iptr->s1.varindex);
1482 /* pop 2 push 0 branch */
1484 case ICMD_IF_ICMPEQ:
1485 case ICMD_IF_ICMPNE:
1486 case ICMD_IF_ICMPLT:
1487 case ICMD_IF_ICMPGE:
1488 case ICMD_IF_ICMPGT:
1489 case ICMD_IF_ICMPLE:
1491 case ICMD_IF_LCMPEQ:
1492 case ICMD_IF_LCMPNE:
1493 case ICMD_IF_LCMPLT:
1494 case ICMD_IF_LCMPGE:
1495 case ICMD_IF_LCMPGT:
1496 case ICMD_IF_LCMPLE:
1498 case ICMD_IF_ACMPEQ:
1499 case ICMD_IF_ACMPNE:
1507 case ICMD_IASTORECONST:
1508 case ICMD_LASTORECONST:
1509 case ICMD_AASTORECONST:
1510 case ICMD_BASTORECONST:
1511 case ICMD_CASTORECONST:
1512 case ICMD_SASTORECONST:
1513 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1514 FREE_TEMP_REG(iptr->s1.varindex);
1517 /* pop 0 push 1 copy */
1520 /* src === dst->prev (identical Stackslot Element) */
1521 /* src --> dst (copied value, take same reg/mem) */
1523 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1524 NEW_TEMP_REG(iptr->dst.varindex);
1527 v = VAROP(iptr->dst);
1529 if (v->flags & INMEMORY) {
1530 int32_t memindex = v->vv.regoff / SIZE_OF_STACKSLOT;
1531 if (memindex >= rd->memcopycountsize) {
1532 int newsize = (memindex + 1) * 2;
1533 i = rd->memcopycountsize;
1534 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1535 MZERO(rd->memcopycount + i, int, newsize - i);
1536 rd->memcopycountsize = newsize;
1538 rd->memcopycount[memindex]++;
1541 /* XXX split reg/mem variables on arm may need special handling here */
1543 s4 regindex = REG_INDEX(v->vv.regoff, v->type);
1545 rd->regcopycount[regindex]++;
1550 /* pop 1 push 1 move */
1553 if (!simplereg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1554 NEW_TEMP_REG(iptr->dst.varindex);
1555 FREE_TEMP_REG(iptr->s1.varindex);
1605 FREE_TEMP_REG(iptr->sx.s23.s2.varindex);
1606 FREE_TEMP_REG(iptr->s1.varindex);
1607 NEW_TEMP_REG(iptr->dst.varindex);
1612 case ICMD_IADDCONST:
1613 case ICMD_ISUBCONST:
1614 case ICMD_IMULCONST:
1618 case ICMD_IANDCONST:
1620 case ICMD_IXORCONST:
1621 case ICMD_ISHLCONST:
1622 case ICMD_ISHRCONST:
1623 case ICMD_IUSHRCONST:
1625 case ICMD_LADDCONST:
1626 case ICMD_LSUBCONST:
1627 case ICMD_LMULCONST:
1631 case ICMD_LANDCONST:
1633 case ICMD_LXORCONST:
1634 case ICMD_LSHLCONST:
1635 case ICMD_LSHRCONST:
1636 case ICMD_LUSHRCONST:
1641 case ICMD_INT2SHORT:
1659 case ICMD_CHECKCAST:
1661 case ICMD_ARRAYLENGTH:
1662 case ICMD_INSTANCEOF:
1665 case ICMD_ANEWARRAY:
1668 FREE_TEMP_REG(iptr->s1.varindex);
1669 NEW_TEMP_REG(iptr->dst.varindex);
1674 case ICMD_GETSTATIC:
1677 NEW_TEMP_REG(iptr->dst.varindex);
1680 /* pop many push any */
1682 case ICMD_INVOKESTATIC:
1683 case ICMD_INVOKESPECIAL:
1684 case ICMD_INVOKEVIRTUAL:
1685 case ICMD_INVOKEINTERFACE:
1686 INSTRUCTION_GET_METHODDESC(iptr,md);
1688 argp = iptr->sx.s23.s2.args;
1690 FREE_TEMP_REG(*argp);
1693 if (md->returntype.type != TYPE_VOID)
1694 NEW_TEMP_REG(iptr->dst.varindex);
1698 bte = iptr->sx.s23.s3.bte;
1701 argp = iptr->sx.s23.s2.args;
1703 FREE_TEMP_REG(*argp);
1706 if (md->returntype.type != TYPE_VOID)
1707 NEW_TEMP_REG(iptr->dst.varindex);
1710 case ICMD_MULTIANEWARRAY:
1711 i = iptr->s1.argcount;
1712 argp = iptr->sx.s23.s2.args;
1714 FREE_TEMP_REG(*argp);
1717 NEW_TEMP_REG(iptr->dst.varindex);
1721 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1726 } /* while instructions */
1729 } /* while blocks */
1733 #if defined(ENABLE_STATISTICS)
1734 void simplereg_make_statistics(jitdata *jd)
1742 stackelement_t* src, src_old;
1743 stackelement_t* dst;
1747 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1751 /* get required compiler data */
1761 /* count how many local variables are held in memory or register */
1762 for(i=0; i < jd->localcount; i++) {
1763 if (VAR(i)->flags & INMEMORY) {
1764 count_locals_spilled++;
1768 count_locals_register++;
1772 /* count how many stack slots are held in memory or register */
1774 bptr = jd->basicblocks;
1776 while (bptr != NULL) {
1777 if (bptr->flags >= BBREACHED) {
1779 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1782 /* check for memory moves from interface to BB instack */
1783 len = bptr->indepth;
1785 if (len > size_interface) size_interface = len;
1789 var = VAR(bptr->invars[len]);
1791 /* invars statistics (currently none) */
1794 /* check for memory moves from BB outstack to interface */
1795 len = bptr->outdepth;
1796 if (len > size_interface) size_interface = len;
1800 var = VAR(bptr->outvars[len]);
1802 /* outvars statistics (currently none) */
1804 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1810 dst = bptr->instack;
1811 iptr = bptr->iinstr;
1815 while (--len >= 0) {
1817 dst = iptr->dst.var;
1819 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1820 switch (src->varkind) {
1823 if (!(src->flags & INMEMORY))
1824 count_ss_register++;
1830 /* case LOCALVAR: */
1831 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1832 /* count_ss_register++; */
1834 /* count_ss_spilled++; */
1837 if (!(src->flags & INMEMORY))
1838 count_argument_mem_ss++;
1840 count_argument_reg_ss++;
1844 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1845 /* if (src->varnum < FLT_ARG_CNT) { */
1846 /* count_ss_register++; */
1850 /* #if defined(__POWERPC__) */
1851 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1853 /* if (src->varnum < INT_ARG_CNT) { */
1855 /* count_ss_register++; */
1859 /* count_ss_spilled++; */
1866 } /* while instructions */
1871 } /* while blocks */
1873 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1874 if (in_register) count_method_in_register++;
1876 /* printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text); */
1879 #endif /* defined(ENABLE_STATISTICS) */
1883 * These are local overrides for various environment variables in Emacs.
1884 * Please do not remove this and leave it at the end of the file, where
1885 * Emacs will automagically detect them.
1886 * ---------------------------------------------------------------------
1889 * indent-tabs-mode: t
1893 * vim:noexpandtab:sw=4:ts=4: