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 5595 2006-09-30 23:06:36Z 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 interface_regalloc(jd);
84 new_allocate_scratch_registers(jd);
92 /* interface_regalloc **********************************************************
94 Allocates registers for all interface variables.
96 *******************************************************************************/
98 static void interface_regalloc(jitdata *jd)
105 int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
106 /* in case more vars are packed into this interface slot */
107 int intregsneeded = 0;
109 /* allocate LNG and DBL Types first to ensure 2 memory slots or registers */
110 /* on HAS_4BYTE_STACKSLOT architectures */
111 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
114 /* get required compiler data */
120 /* rd->memuse was already set in stack.c to allocate stack space
121 for passing arguments to called methods. */
123 #if defined(__I386__)
124 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
125 /* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
131 if (jd->isleafmethod) {
132 /* Reserve argument register, which will be used for Locals acting */
134 if (rd->argintreguse < m->parseddesc->argintreguse)
135 rd->argintreguse = m->parseddesc->argintreguse;
136 if (rd->argfltreguse < m->parseddesc->argfltreguse)
137 rd->argfltreguse = m->parseddesc->argfltreguse;
138 #ifdef HAS_ADDRESS_REGISTER_FILE
139 if (rd->argadrreguse < m->parseddesc->argadrreguse)
140 rd->argadrreguse = m->parseddesc->argadrreguse;
145 for (s = 0; s < cd->maxstack; s++) {
146 intalloc = -1; fltalloc = -1;
150 for (tt = 0; tt <=4; tt++) {
151 if ((t = jd->interface_map[s * 5 + tt].flags) != UNUSED) {
152 saved |= t & SAVEDVAR;
156 for (tt = 0; tt <= 4; tt++) {
158 if (jd->interface_map[s * 5 + t].flags == UNUSED)
162 regoff = -1; /* XXX for debugging */
164 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
165 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
167 #if defined(HAS_4BYTE_STACKSLOT)
168 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
171 #if defined(HAS_ADDRESS_REGISTER_FILE)
172 if (IS_ADR_TYPE(t)) {
173 if (!jd->isleafmethod
174 &&(rd->argadrreguse < ADR_ARG_CNT)) {
175 regoff = rd->argadrregs[rd->argadrreguse++];
176 } else if (rd->tmpadrreguse > 0) {
177 regoff = rd->tmpadrregs[--rd->tmpadrreguse];
178 } else if (rd->savadrreguse > 0) {
179 regoff = rd->savadrregs[--rd->savadrreguse];
182 regoff = rd->memuse++;
184 } else /* !IS_ADR_TYPE */
185 #endif /* defined(HAS_ADDRESS_REGISTER_FILE) */
187 if (IS_FLT_DBL_TYPE(t)) {
189 /* Reuse memory slot(s)/register(s) for shared interface slots */
190 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
191 regoff = jd->interface_map[fltalloc].regoff;
192 } else if (rd->argfltreguse < FLT_ARG_CNT) {
193 regoff = rd->argfltregs[rd->argfltreguse++];
194 } else if (rd->tmpfltreguse > 0) {
195 regoff = rd->tmpfltregs[--rd->tmpfltreguse];
196 } else if (rd->savfltreguse > 0) {
197 regoff = rd->savfltregs[--rd->savfltreguse];
200 #if defined(ALIGN_DOUBLES_IN_MEMORY)
201 /* Align doubles in Memory */
202 if ( (memneeded) && (rd->memuse & 1))
206 rd->memuse += memneeded + 1;
208 fltalloc = s * 5 + t;
209 } else { /* !IS_FLT_DBL_TYPE(t) */
210 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
212 * for i386 put all longs in memory
214 if (IS_2_WORD_TYPE(t)) {
216 #if defined(ALIGN_LONGS_IN_MEMORY)
217 /* Align longs in Memory */
222 rd->memuse += memneeded + 1;
224 #endif /* defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE...GISTERS) */
226 /* Reuse memory slot(s)/register(s) for shared interface slots */
227 flags |= jd->interface_map[intalloc].flags & INMEMORY;
228 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
229 if (!(flags & INMEMORY)
230 && IS_2_WORD_TYPE(intalloc % 5))
231 regoff = GET_LOW_REG(
232 jd->interface_map[intalloc].regoff);
236 jd->interface_map[intalloc].regoff;
238 if (rd->argintreguse + intregsneeded
240 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
243 rd->argintregs[rd->argintreguse],
244 rd->argintregs[rd->argintreguse + 1]);
248 rd->argintregs[rd->argintreguse];
249 rd->argintreguse += intregsneeded + 1;
251 else if (rd->tmpintreguse > intregsneeded) {
252 rd->tmpintreguse -= intregsneeded + 1;
253 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
256 rd->tmpintregs[rd->tmpintreguse],
257 rd->tmpintregs[rd->tmpintreguse + 1]);
261 rd->tmpintregs[rd->tmpintreguse];
263 else if (rd->savintreguse > intregsneeded) {
264 rd->savintreguse -= intregsneeded + 1;
266 rd->savintregs[rd->savintreguse];
267 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
270 rd->savintregs[rd->savintreguse],
271 rd->savintregs[rd->savintreguse + 1]);
275 rd->savintregs[rd->savintreguse];
279 #if defined(ALIGN_LONGS_IN_MEMORY)
280 /* Align longs in Memory */
281 if ( (memneeded) && (rd->memuse & 1))
285 rd->memuse += memneeded + 1;
288 intalloc = s * 5 + t;
289 } /* if (IS_FLT_DBL_TYPE(t)) */
291 } else { /* (saved) */
292 /* now the same like above, but without a chance to take a temporary register */
293 #ifdef HAS_ADDRESS_REGISTER_FILE
294 if (IS_ADR_TYPE(t)) {
295 if (rd->savadrreguse > 0) {
296 regoff = rd->savadrregs[--rd->savadrreguse];
300 regoff = rd->memuse++;
305 if (IS_FLT_DBL_TYPE(t)) {
307 flags |= jd->interface_map[fltalloc].flags & INMEMORY;
308 regoff = jd->interface_map[fltalloc].regoff;
310 if (rd->savfltreguse > 0) {
312 rd->savfltregs[--rd->savfltreguse];
316 #if defined(ALIGN_DOUBLES_IN_MEMORY)
317 /* Align doubles in Memory */
318 if ( (memneeded) && (rd->memuse & 1))
322 rd->memuse += memneeded + 1;
324 fltalloc = s * 5 + t;
326 else { /* IS_INT_LNG */
327 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
329 * for i386 put all longs in memory
331 if (IS_2_WORD_TYPE(t)) {
333 #if defined(ALIGN_LONGS_IN_MEMORY)
334 /* Align longs in Memory */
339 rd->memuse += memneeded + 1;
344 flags |= jd->interface_map[intalloc].flags & INMEMORY;
345 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
346 if (!(flags & INMEMORY)
347 && IS_2_WORD_TYPE(intalloc % 5))
350 jd->interface_map[intalloc].regoff);
354 jd->interface_map[intalloc].regoff;
356 if (rd->savintreguse > intregsneeded) {
357 rd->savintreguse -= intregsneeded + 1;
358 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
361 rd->savintregs[rd->savintreguse],
362 rd->savintregs[rd->savintreguse + 1]);
366 rd->savintregs[rd->savintreguse];
369 #if defined(ALIGN_LONGS_IN_MEMORY)
370 /* Align longs in Memory */
371 if ( (memneeded) && (rd->memuse & 1))
375 rd->memuse += memneeded + 1;
380 } /* if (IS_FLT_DBL_TYPE(t) else */
381 } /* if (IS_ADR_TYPE(t)) else */
382 } /* if (saved) else */
386 jd->interface_map[5*s + t].flags = flags | OUTVAR;
387 jd->interface_map[5*s + t].regoff = regoff;
394 /* local_regalloc **************************************************************
396 Allocates registers for all local variables.
398 *******************************************************************************/
400 static void local_regalloc(jitdata *jd)
407 int intalloc, fltalloc;
409 int intregsneeded = 0;
411 int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
412 int fargcnt, iargcnt;
413 #ifdef HAS_ADDRESS_REGISTER_FILE
417 /* get required compiler data */
423 if (jd->isleafmethod) {
424 methoddesc *md = m->parseddesc;
426 iargcnt = rd->argintreguse;
427 fargcnt = rd->argfltreguse;
428 #ifdef HAS_ADDRESS_REGISTER_FILE
429 aargcnt = rd->argadrreguse;
431 for (p = 0, s = 0; s < cd->maxlocals; s++, p++) {
432 intalloc = -1; fltalloc = -1;
433 for (tt = 0; tt <= 4; tt++) {
435 lm = jd->local_map[s * 5 + t];
441 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
442 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
444 #if defined(HAS_4BYTE_STACKSLOT)
445 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
451 * #ifdef HAS_ADDRESS_REGISTER_FILE
458 * } else { / int & lng
462 * must not to be changed!
465 #ifdef HAS_ADDRESS_REGISTER_FILE
466 if (IS_ADR_TYPE(t)) {
467 if ((p < md->paramcount) && !md->params[p].inmemory) {
469 v->vv.regoff = rd->argadrregs[md->params[p].regoff];
471 else if (rd->tmpadrreguse > 0) {
473 v->vv.regoff = rd->tmpadrregs[--rd->tmpadrreguse];
475 /* use unused argument registers as local registers */
476 else if ((p >= md->paramcount) &&
477 (aargcnt < ADR_ARG_CNT)) {
479 v->vv.regoff = rd->argadrregs[aargcnt++];
481 else if (rd->savadrreguse > 0) {
483 v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
486 v->flags |= INMEMORY;
487 v->vv.regoff = rd->memuse++;
491 if (IS_FLT_DBL_TYPE(t)) {
493 v->flags = VAR(fltalloc)->flags;
494 v->vv.regoff = VAR(fltalloc)->vv.regoff;
496 #if !defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
497 /* We can only use float arguments as local variables,
498 * if we do not pass them in integer registers. */
499 else if ((p < md->paramcount) &&
500 !md->params[p].inmemory) {
502 v->vv.regoff = rd->argfltregs[md->params[p].regoff];
505 else if (rd->tmpfltreguse > 0) {
507 v->vv.regoff = rd->tmpfltregs[--rd->tmpfltreguse];
509 /* use unused argument registers as local registers */
510 else if ((p >= md->paramcount) &&
511 (fargcnt < FLT_ARG_CNT)) {
513 v->vv.regoff = rd->argfltregs[fargcnt];
516 else if (rd->savfltreguse > 0) {
518 v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
522 #if defined(ALIGN_DOUBLES_IN_MEMORY)
523 /* Align doubles in Memory */
524 if ( (memneeded) && (rd->memuse & 1))
527 v->vv.regoff = rd->memuse;
528 rd->memuse += memneeded + 1;
530 fltalloc = jd->local_map[s * 5 + t];
533 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
535 * for i386 put all longs in memory
537 if (IS_2_WORD_TYPE(t)) {
539 #if defined(ALIGN_LONGS_IN_MEMORY)
540 /* Align longs in Memory */
544 v->vv.regoff = rd->memuse;
545 rd->memuse += memneeded + 1;
550 v->flags = VAR(intalloc)->flags;
551 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
552 if (!(v->flags & INMEMORY)
553 && IS_2_WORD_TYPE(VAR(intalloc)->type))
554 v->vv.regoff = GET_LOW_REG(
555 VAR(intalloc)->vv.regoff);
558 v->vv.regoff = VAR(intalloc)->vv.regoff;
560 else if ((p < md->paramcount) &&
561 !md->params[p].inmemory) {
563 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
564 if (IS_2_WORD_TYPE(t))
565 v->vv.regoff = PACK_REGS(
566 rd->argintregs[GET_LOW_REG(md->params[p].regoff)],
567 rd->argintregs[GET_HIGH_REG(md->params[p].regoff)]);
571 rd->argintregs[md->params[p].regoff];
573 else if (rd->tmpintreguse > intregsneeded) {
574 rd->tmpintreguse -= intregsneeded + 1;
576 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
578 v->vv.regoff = PACK_REGS(
579 rd->tmpintregs[rd->tmpintreguse],
580 rd->tmpintregs[rd->tmpintreguse + 1]);
584 rd->tmpintregs[rd->tmpintreguse];
587 * use unused argument registers as local registers
589 else if ((p >= m->parseddesc->paramcount) &&
590 (iargcnt + intregsneeded < INT_ARG_CNT)) {
592 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
594 v->vv.regoff=PACK_REGS(
595 rd->argintregs[iargcnt],
596 rd->argintregs[iargcnt + 1]);
599 v->vv.regoff = rd->argintregs[iargcnt];
600 iargcnt += intregsneeded + 1;
602 else if (rd->savintreguse > intregsneeded) {
603 rd->savintreguse -= intregsneeded + 1;
605 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
607 v->vv.regoff = PACK_REGS(
608 rd->savintregs[rd->savintreguse],
609 rd->savintregs[rd->savintreguse + 1]);
612 v->vv.regoff =rd->savintregs[rd->savintreguse];
616 #if defined(ALIGN_LONGS_IN_MEMORY)
617 /* Align longs in Memory */
618 if ( (memneeded) && (rd->memuse & 1))
621 v->vv.regoff = rd->memuse;
622 rd->memuse += memneeded + 1;
625 intalloc = jd->local_map[s * 5 + t];
627 #ifdef HAS_ADDRESS_REGISTER_FILE
630 } /* for (tt=0;...) */
632 /* If the current parameter is a 2-word type, the next local slot */
635 if (p < md->paramcount)
636 if (IS_2_WORD_TYPE(md->paramtypes[p].type))
642 for (s = 0; s < cd->maxlocals; s++) {
643 intalloc = -1; fltalloc = -1;
644 for (tt=0; tt<=4; tt++) {
647 lm = jd->local_map[s * 5 + t];
653 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
654 intregsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
656 #if defined(HAS_4BYTE_STACKSLOT)
657 memneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0;
659 #ifdef HAS_ADDRESS_REGISTER_FILE
660 if ( IS_ADR_TYPE(t) ) {
661 if (rd->savadrreguse > 0) {
663 v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
667 v->vv.regoff = rd->memuse++;
671 if (IS_FLT_DBL_TYPE(t)) {
673 v->flags = VAR(fltalloc)->flags;
674 v->vv.regoff = VAR(fltalloc)->vv.regoff;
676 else if (rd->savfltreguse > 0) {
678 v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
682 #if defined(ALIGN_DOUBLES_IN_MEMORY)
683 /* Align doubles in Memory */
684 if ( (memneeded) && (rd->memuse & 1))
687 v->vv.regoff = rd->memuse;
688 rd->memuse += memneeded + 1;
690 fltalloc = jd->local_map[s * 5 + t];
693 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
695 * for i386 put all longs in memory
697 if (IS_2_WORD_TYPE(t)) {
699 #if defined(ALIGN_LONGS_IN_MEMORY)
700 /* Align longs in Memory */
704 v->vv.regoff = rd->memuse;
705 rd->memuse += memneeded + 1;
709 v->flags = VAR(intalloc)->flags;
710 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
711 if (!(v->flags & INMEMORY)
712 && IS_2_WORD_TYPE(VAR(intalloc)->type))
713 v->vv.regoff = GET_LOW_REG(
714 VAR(intalloc)->vv.regoff);
717 v->vv.regoff = VAR(intalloc)->vv.regoff;
719 else if (rd->savintreguse > intregsneeded) {
720 rd->savintreguse -= intregsneeded+1;
722 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
724 v->vv.regoff = PACK_REGS(
725 rd->savintregs[rd->savintreguse],
726 rd->savintregs[rd->savintreguse + 1]);
729 v->vv.regoff =rd->savintregs[rd->savintreguse];
733 #if defined(ALIGN_LONGS_IN_MEMORY)
734 /* Align longs in Memory */
735 if ( (memneeded) && (rd->memuse & 1))
738 v->vv.regoff = rd->memuse;
739 rd->memuse += memneeded + 1;
741 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
744 intalloc = jd->local_map[s * 5 + t];
746 #ifdef HAS_ADDRESS_REGISTER_FILE
755 static void reg_init_temp(jitdata *jd, registerdata *rd)
758 #if defined(HAS_4BYTE_STACKSLOT)
759 rd->freememtop_2 = 0;
762 rd->freetmpinttop = 0;
763 rd->freesavinttop = 0;
764 rd->freetmpflttop = 0;
765 rd->freesavflttop = 0;
766 #ifdef HAS_ADDRESS_REGISTER_FILE
767 rd->freetmpadrtop = 0;
768 rd->freesavadrtop = 0;
771 rd->freearginttop = 0;
772 rd->freeargflttop = 0;
773 #ifdef HAS_ADDRESS_REGISTER_FILE
774 rd->freeargadrtop = 0;
777 rd->regcopycount = DMNEW(int, INT_REG_CNT + FLT_REG_CNT);
778 MZERO(rd->regcopycount, int, INT_REG_CNT + FLT_REG_CNT);
780 /* memcopycount is dynamically allocated when needed */
782 rd->memcopycount = NULL;
783 rd->memcopycountsize = 0;
787 #define reg_new_temp(jd,index) \
788 if ( (index >= jd->localcount) \
789 && (!(VAR(index)->flags & OUTVAR)) \
790 && (!(VAR(index)->flags & PREALLOC)) ) \
791 reg_new_temp_func(jd, index)
793 static void reg_new_temp_func(jitdata *jd, s4 index)
804 /* Try to allocate a saved register if there is no temporary one */
805 /* available. This is what happens during the second run. */
806 tryagain = (v->flags & SAVEDVAR) ? 1 : 2;
808 #ifdef SUPPORT_COMBINE_INTEGER_REGISTERS
809 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
813 #if defined(HAS_4BYTE_STACKSLOT)
814 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
819 for(; tryagain; --tryagain) {
821 if (!(v->flags & SAVEDVAR))
822 v->flags |= SAVEDTMP;
823 #ifdef HAS_ADDRESS_REGISTER_FILE
824 if (IS_ADR_TYPE(v->type)) {
825 if (rd->freesavadrtop > 0) {
826 v->vv.regoff = rd->freesavadrregs[--rd->freesavadrtop];
828 } else if (rd->savadrreguse > 0) {
829 v->vv.regoff = rd->savadrregs[--rd->savadrreguse];
835 if (IS_FLT_DBL_TYPE(v->type)) {
836 if (rd->freesavflttop > 0) {
837 v->vv.regoff = rd->freesavfltregs[--rd->freesavflttop];
839 } else if (rd->savfltreguse > 0) {
840 v->vv.regoff = rd->savfltregs[--rd->savfltreguse];
844 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
846 * for i386 put all longs in memory
848 if (!IS_2_WORD_TYPE(v->type))
851 if (rd->freesavinttop > intregsneeded) {
852 rd->freesavinttop -= intregsneeded + 1;
853 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
855 v->vv.regoff = PACK_REGS(
856 rd->freesavintregs[rd->freesavinttop],
857 rd->freesavintregs[rd->freesavinttop + 1]);
861 rd->freesavintregs[rd->freesavinttop];
863 } else if (rd->savintreguse > intregsneeded) {
864 rd->savintreguse -= intregsneeded + 1;
865 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
867 v->vv.regoff = PACK_REGS(
868 rd->savintregs[rd->savintreguse],
869 rd->savintregs[rd->savintreguse + 1]);
872 v->vv.regoff = rd->savintregs[rd->savintreguse];
878 } else { /* tryagain == 2 */
879 #ifdef HAS_ADDRESS_REGISTER_FILE
880 if (IS_ADR_TYPE(v->type)) {
881 if (rd->freetmpadrtop > 0) {
882 v->vv.regoff = rd->freetmpadrregs[--rd->freetmpadrtop];
884 } else if (rd->tmpadrreguse > 0) {
885 v->vv.regoff = rd->tmpadrregs[--rd->tmpadrreguse];
891 if (IS_FLT_DBL_TYPE(v->type)) {
892 if (rd->freeargflttop > 0) {
893 v->vv.regoff = rd->freeargfltregs[--rd->freeargflttop];
896 } else if (rd->argfltreguse < FLT_ARG_CNT) {
897 v->vv.regoff = rd->argfltregs[rd->argfltreguse++];
900 } else if (rd->freetmpflttop > 0) {
901 v->vv.regoff = rd->freetmpfltregs[--rd->freetmpflttop];
903 } else if (rd->tmpfltreguse > 0) {
904 v->vv.regoff = rd->tmpfltregs[--rd->tmpfltreguse];
909 #if defined(HAS_4BYTE_STACKSLOT) && !defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
911 * for i386 put all longs in memory
913 if (!IS_2_WORD_TYPE(v->type))
916 if (rd->freearginttop > intregsneeded) {
917 rd->freearginttop -= intregsneeded + 1;
919 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
921 v->vv.regoff = PACK_REGS(
922 rd->freeargintregs[rd->freearginttop],
923 rd->freeargintregs[rd->freearginttop + 1]);
927 rd->freeargintregs[rd->freearginttop];
929 } else if (rd->argintreguse
930 < INT_ARG_CNT - intregsneeded) {
931 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
933 v->vv.regoff = PACK_REGS(
934 rd->argintregs[rd->argintreguse],
935 rd->argintregs[rd->argintreguse + 1]);
938 v->vv.regoff = rd->argintregs[rd->argintreguse];
940 rd->argintreguse += intregsneeded + 1;
942 } else if (rd->freetmpinttop > intregsneeded) {
943 rd->freetmpinttop -= intregsneeded + 1;
944 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
946 v->vv.regoff = PACK_REGS(
947 rd->freetmpintregs[rd->freetmpinttop],
948 rd->freetmpintregs[rd->freetmpinttop + 1]);
951 v->vv.regoff = rd->freetmpintregs[rd->freetmpinttop];
953 } else if (rd->tmpintreguse > intregsneeded) {
954 rd->tmpintreguse -= intregsneeded + 1;
955 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
957 v->vv.regoff = PACK_REGS(
958 rd->tmpintregs[rd->tmpintreguse],
959 rd->tmpintregs[rd->tmpintreguse + 1]);
962 v->vv.regoff = rd->tmpintregs[rd->tmpintreguse];
965 } /* if (!IS_2_WORD_TYPE(s->type)) */
966 } /* if (IS_FLT_DBL_TYPE(s->type)) */
967 } /* if (IS_ADR_TYPE(s->type)) */
968 } /* if (tryagain == 1) else */
969 } /* for(; tryagain; --tryagain) */
971 #if defined(HAS_4BYTE_STACKSLOT)
972 if ((memneeded == 1) && (rd->freememtop_2 > 0)) {
974 v->vv.regoff = rd->freemem_2[rd->freememtop_2];
976 #endif /*defined(HAS_4BYTE_STACKSLOT) */
977 if ((memneeded == 0) && (rd->freememtop > 0)) {
979 v->vv.regoff = rd->freemem[rd->freememtop];
981 #if defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY)
982 /* align 2 Word Types */
983 if ((memneeded) && ((rd->memuse & 1) == 1)) {
984 /* Put patched memory slot on freemem */
985 rd->freemem[rd->freememtop++] = rd->memuse;
988 #endif /* defined(ALIGN_LONGS_IN_MEMORY) || defined(ALIGN_DOUBLES_IN_MEMORY) */
989 v->vv.regoff = rd->memuse;
990 rd->memuse += memneeded + 1;
992 v->flags |= INMEMORY;
996 #define reg_free_temp(jd,index) \
997 if ((index > jd->localcount) \
998 && (!(VAR(index)->flags & (OUTVAR | PREALLOC)))) \
999 reg_free_temp_func(jd, index)
1001 /* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
1002 /* alive using this reg/memory location */
1004 static void reg_free_temp_func(jitdata *jd, s4 index)
1014 /* if this is a copy of another variable, just decrement the copy counter */
1016 /* XXX split reg/mem variables on arm may need special handling here */
1018 if (v->flags & INMEMORY) {
1019 if (v->vv.regoff < rd->memcopycountsize && rd->memcopycount[v->vv.regoff]) {
1020 rd->memcopycount[v->vv.regoff]--;
1025 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1026 if (rd->regcopycount[GET_LOW_REG(v->vv.regoff)]) {
1027 rd->regcopycount[GET_LOW_REG(v->vv.regoff)]--;
1031 if (rd->regcopycount[v->vv.regoff]) {
1032 rd->regcopycount[v->vv.regoff]--;
1038 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1039 intregsneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1044 #if defined(HAS_4BYTE_STACKSLOT)
1045 memneeded = (IS_2_WORD_TYPE(v->type)) ? 1 : 0;
1050 if (v->flags & INMEMORY) {
1051 #if defined(HAS_4BYTE_STACKSLOT)
1052 if (memneeded > 0) {
1053 rd->freemem_2[rd->freememtop_2] = v->vv.regoff;
1058 rd->freemem[rd->freememtop] = v->vv.regoff;
1062 #ifdef HAS_ADDRESS_REGISTER_FILE
1063 } else if (IS_ADR_TYPE(v->type)) {
1064 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1065 /* v->flags &= ~SAVEDTMP; */
1066 rd->freesavadrregs[rd->freesavadrtop++] = v->vv.regoff;
1068 rd->freetmpadrregs[rd->freetmpadrtop++] = v->vv.regoff;
1070 } else if (IS_FLT_DBL_TYPE(v->type)) {
1071 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1072 /* v->flags &= ~SAVEDTMP; */
1073 rd->freesavfltregs[rd->freesavflttop++] = v->vv.regoff;
1074 } else if (v->flags & TMPARG) {
1075 /* v->flags &= ~TMPARG; */
1076 rd->freeargfltregs[rd->freeargflttop++] = v->vv.regoff;
1078 rd->freetmpfltregs[rd->freetmpflttop++] = v->vv.regoff;
1079 } else { /* IS_INT_LNG_TYPE */
1080 if (v->flags & (SAVEDVAR | SAVEDTMP)) {
1081 /* v->flags &= ~SAVEDTMP; */
1082 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1083 if (intregsneeded) {
1084 rd->freesavintregs[rd->freesavinttop] =
1085 GET_LOW_REG(v->vv.regoff);
1086 rd->freesavintregs[rd->freesavinttop + 1] =
1087 GET_HIGH_REG(v->vv.regoff);
1090 rd->freesavintregs[rd->freesavinttop] = v->vv.regoff;
1091 rd->freesavinttop += intregsneeded + 1;
1093 } else if (v->flags & TMPARG) {
1094 /* s->flags &= ~TMPARG; */
1095 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1096 if (intregsneeded) {
1097 rd->freeargintregs[rd->freearginttop] =
1098 GET_LOW_REG(v->vv.regoff);
1099 rd->freeargintregs[rd->freearginttop + 1] =
1100 GET_HIGH_REG(v->vv.regoff);
1103 rd->freeargintregs[rd->freearginttop] = v->vv.regoff;
1104 rd->freearginttop += intregsneeded + 1;
1106 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1107 if (intregsneeded) {
1108 rd->freetmpintregs[rd->freetmpinttop] =
1109 GET_LOW_REG(v->vv.regoff);
1110 rd->freetmpintregs[rd->freetmpinttop + 1] =
1111 GET_HIGH_REG(v->vv.regoff);
1114 rd->freetmpintregs[rd->freetmpinttop] = v->vv.regoff;
1115 rd->freetmpinttop += intregsneeded + 1;
1121 static bool reg_alloc_dup(jitdata *jd, s4 srcindex, s4 dstindex)
1126 /* do not coalesce local variables here */
1128 if (srcindex <= jd->localcount || dstindex <= jd->localcount)
1134 /* do not coalesce in/out vars or preallocated variables here */
1136 if ((sv->flags | dv->flags) & (OUTVAR | PREALLOC))
1139 /* if the source is in memory, we can coalesce in any case */
1141 if (sv->flags & INMEMORY) {
1142 dv->flags |= INMEMORY;
1143 dv->vv.regoff = sv->vv.regoff;
1147 /* we do not allocate a REG_TMP to a REG_SAV variable */
1149 if ((sv->flags & SAVEDVAR) != (dv->flags & SAVEDVAR))
1153 dv->vv.regoff = sv->vv.regoff;
1154 dv->flags |= sv->flags & (SAVEDTMP | TMPARG);
1160 /* allocate_scratch_registers **************************************************
1162 Allocate temporary (non-interface, non-local) registers.
1164 *******************************************************************************/
1166 static void new_allocate_scratch_registers(jitdata *jd)
1174 builtintable_entry *bte;
1179 /* get required compiler data */
1184 /* initialize temp registers */
1186 reg_init_temp(jd, rd);
1188 bptr = jd->new_basicblocks;
1190 while (bptr != NULL) {
1191 if (bptr->flags >= BBREACHED) {
1193 /* set allocation of invars */
1195 for (i=0; i<bptr->indepth; ++i)
1197 v = VAR(bptr->invars[i]);
1199 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1200 v->flags = jd->interface_map[5*i + v->type].flags;
1203 /* set allocation of outvars */
1205 for (i=0; i<bptr->outdepth; ++i)
1207 v = VAR(bptr->outvars[i]);
1209 v->vv.regoff = jd->interface_map[5*i + v->type].regoff;
1210 v->flags = jd->interface_map[5*i + v->type].flags;
1213 /* iterate over ICMDS to allocate temporary variables */
1215 iptr = bptr->iinstr;
1218 while (--len >= 0) {
1219 switch (iptr->opc) {
1224 #if !defined(NDEBUG)
1225 /* avoid problems with show_allocation */
1226 VAROP(iptr->dst)->vv.regoff = 0;
1229 case ICMD_CHECKNULL:
1234 case ICMD_PUTSTATICCONST:
1235 case ICMD_INLINE_START:
1236 case ICMD_INLINE_END:
1237 case ICMD_INLINE_GOTO:
1240 /* pop 0 push 1 const */
1248 /* pop 0 push 1 load */
1255 reg_new_temp(jd, iptr->dst.varindex);
1269 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1270 reg_free_temp(jd, iptr->s1.varindex);
1271 reg_new_temp(jd, iptr->dst.varindex);
1285 reg_free_temp(jd, iptr->sx.s23.s3.varindex);
1286 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1287 reg_free_temp(jd, iptr->s1.varindex);
1290 /* pop 1 push 0 store */
1310 case ICMD_PUTSTATIC:
1311 case ICMD_PUTFIELDCONST:
1313 /* pop 1 push 0 branch */
1316 case ICMD_IFNONNULL:
1332 /* pop 1 push 0 table branch */
1334 case ICMD_TABLESWITCH:
1335 case ICMD_LOOKUPSWITCH:
1337 case ICMD_MONITORENTER:
1338 case ICMD_MONITOREXIT:
1339 reg_free_temp(jd, iptr->s1.varindex);
1342 /* pop 2 push 0 branch */
1344 case ICMD_IF_ICMPEQ:
1345 case ICMD_IF_ICMPNE:
1346 case ICMD_IF_ICMPLT:
1347 case ICMD_IF_ICMPGE:
1348 case ICMD_IF_ICMPGT:
1349 case ICMD_IF_ICMPLE:
1351 case ICMD_IF_LCMPEQ:
1352 case ICMD_IF_LCMPNE:
1353 case ICMD_IF_LCMPLT:
1354 case ICMD_IF_LCMPGE:
1355 case ICMD_IF_LCMPGT:
1356 case ICMD_IF_LCMPLE:
1358 case ICMD_IF_FCMPEQ:
1359 case ICMD_IF_FCMPNE:
1361 case ICMD_IF_FCMPL_LT:
1362 case ICMD_IF_FCMPL_GE:
1363 case ICMD_IF_FCMPL_GT:
1364 case ICMD_IF_FCMPL_LE:
1366 case ICMD_IF_FCMPG_LT:
1367 case ICMD_IF_FCMPG_GE:
1368 case ICMD_IF_FCMPG_GT:
1369 case ICMD_IF_FCMPG_LE:
1371 case ICMD_IF_DCMPEQ:
1372 case ICMD_IF_DCMPNE:
1374 case ICMD_IF_DCMPL_LT:
1375 case ICMD_IF_DCMPL_GE:
1376 case ICMD_IF_DCMPL_GT:
1377 case ICMD_IF_DCMPL_LE:
1379 case ICMD_IF_DCMPG_LT:
1380 case ICMD_IF_DCMPG_GE:
1381 case ICMD_IF_DCMPG_GT:
1382 case ICMD_IF_DCMPG_LE:
1384 case ICMD_IF_ACMPEQ:
1385 case ICMD_IF_ACMPNE:
1393 case ICMD_IASTORECONST:
1394 case ICMD_LASTORECONST:
1395 case ICMD_AASTORECONST:
1396 case ICMD_BASTORECONST:
1397 case ICMD_CASTORECONST:
1398 case ICMD_SASTORECONST:
1399 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1400 reg_free_temp(jd, iptr->s1.varindex);
1403 /* pop 0 push 1 copy */
1406 /* src === dst->prev (identical Stackslot Element) */
1407 /* src --> dst (copied value, take same reg/mem) */
1409 if (!reg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1410 reg_new_temp(jd, iptr->dst.varindex);
1412 v = VAROP(iptr->dst);
1414 if (v->flags & INMEMORY) {
1415 if (v->vv.regoff >= rd->memcopycountsize) {
1416 int newsize = (v->vv.regoff + 1) * 2;
1417 i = rd->memcopycountsize;
1418 rd->memcopycount = DMREALLOC(rd->memcopycount, int, i, newsize);
1419 MZERO(rd->memcopycount + i, int, newsize - i);
1420 rd->memcopycountsize = newsize;
1422 rd->memcopycount[v->vv.regoff]++;
1425 /* XXX split reg/mem variables on arm may need special handling here */
1427 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
1428 rd->regcopycount[GET_LOW_REG(v->vv.regoff)]++;
1430 rd->regcopycount[v->vv.regoff]++;
1436 /* pop 1 push 1 move */
1439 if (!reg_alloc_dup(jd, iptr->s1.varindex, iptr->dst.varindex)) {
1440 reg_new_temp(jd, iptr->dst.varindex);
1441 reg_free_temp(jd, iptr->s1.varindex);
1491 reg_free_temp(jd, iptr->sx.s23.s2.varindex);
1492 reg_free_temp(jd, iptr->s1.varindex);
1493 reg_new_temp(jd, iptr->dst.varindex);
1498 case ICMD_IADDCONST:
1499 case ICMD_ISUBCONST:
1500 case ICMD_IMULCONST:
1504 case ICMD_IANDCONST:
1506 case ICMD_IXORCONST:
1507 case ICMD_ISHLCONST:
1508 case ICMD_ISHRCONST:
1509 case ICMD_IUSHRCONST:
1511 case ICMD_LADDCONST:
1512 case ICMD_LSUBCONST:
1513 case ICMD_LMULCONST:
1517 case ICMD_LANDCONST:
1519 case ICMD_LXORCONST:
1520 case ICMD_LSHLCONST:
1521 case ICMD_LSHRCONST:
1522 case ICMD_LUSHRCONST:
1527 case ICMD_INT2SHORT:
1545 case ICMD_CHECKCAST:
1547 case ICMD_ARRAYLENGTH:
1548 case ICMD_INSTANCEOF:
1551 case ICMD_ANEWARRAY:
1554 reg_free_temp(jd, iptr->s1.varindex);
1555 reg_new_temp(jd, iptr->dst.varindex);
1560 case ICMD_GETSTATIC:
1563 reg_new_temp(jd, iptr->dst.varindex);
1566 /* pop many push any */
1568 case ICMD_INVOKESTATIC:
1569 case ICMD_INVOKESPECIAL:
1570 case ICMD_INVOKEVIRTUAL:
1571 case ICMD_INVOKEINTERFACE:
1572 INSTRUCTION_GET_METHODDESC(iptr,md);
1574 argp = iptr->sx.s23.s2.args;
1576 reg_free_temp(jd, *argp);
1579 if (md->returntype.type != TYPE_VOID)
1580 reg_new_temp(jd, iptr->dst.varindex);
1584 bte = iptr->sx.s23.s3.bte;
1587 argp = iptr->sx.s23.s2.args;
1589 reg_free_temp(jd, *argp);
1592 if (md->returntype.type != TYPE_VOID)
1593 reg_new_temp(jd, iptr->dst.varindex);
1596 case ICMD_MULTIANEWARRAY:
1597 i = iptr->s1.argcount;
1598 argp = iptr->sx.s23.s2.args;
1600 reg_free_temp(jd, *argp);
1603 reg_new_temp(jd, iptr->dst.varindex);
1608 new_internalerror("Unknown ICMD %d during register allocation",
1613 } /* while instructions */
1616 } /* while blocks */
1620 #if defined(ENABLE_STATISTICS)
1621 void reg_make_statistics(jitdata *jd)
1628 stackptr src, src_old;
1632 int size_interface; /* == maximum size of in/out stack at basic block boundaries */
1635 /* get required compiler data */
1645 /* count how many local variables are held in memory or register */
1646 for(i=0; i < cd->maxlocals; i++)
1647 for (type=0; type <=4; type++)
1648 if (rd->locals[i][type].type != -1) { /* valid local */
1649 if (rd->locals[i][type].flags & INMEMORY) {
1650 count_locals_spilled++;
1654 count_locals_register++;
1657 /* count how many stack slots are held in memory or register */
1659 bptr = jd->new_basicblocks;
1661 while (bptr != NULL) {
1662 if (bptr->flags >= BBREACHED) {
1664 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1667 /* check for memory moves from interface to BB instack */
1668 dst = bptr->instack;
1669 len = bptr->indepth;
1671 if (len > size_interface) size_interface = len;
1673 while (dst != NULL) {
1675 if (dst->varkind != STACKVAR) {
1676 if ( (dst->flags & INMEMORY) ||
1677 (rd->interfaces[len][dst->type].flags & INMEMORY) ||
1678 ( (dst->flags & INMEMORY) &&
1679 (rd->interfaces[len][dst->type].flags & INMEMORY) &&
1680 (dst->vv.regoff != rd->interfaces[len][dst->type].regoff) ))
1682 /* one in memory or both inmemory at different offsets */
1683 count_mem_move_bb++;
1691 /* check for memory moves from BB outstack to interface */
1692 dst = bptr->outstack;
1693 len = bptr->outdepth;
1694 if (len > size_interface) size_interface = len;
1698 if (dst->varkind != STACKVAR) {
1699 if ( (dst->flags & INMEMORY) || \
1700 (rd->interfaces[len][dst->type].flags & INMEMORY) || \
1701 ( (dst->flags & INMEMORY) && \
1702 (rd->interfaces[len][dst->type].flags & INMEMORY) && \
1703 (dst->vv.regoff != rd->interfaces[len][dst->type].regoff) ))
1705 /* one in memory or both inmemory at different offsets */
1706 count_mem_move_bb++;
1713 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1718 dst = bptr->instack;
1719 iptr = bptr->iinstr;
1723 while (--len >= 0) {
1725 dst = iptr->dst.var;
1727 if ((src!= NULL) && (src != src_old)) { /* new stackslot */
1728 switch (src->varkind) {
1731 if (!(src->flags & INMEMORY))
1732 count_ss_register++;
1738 /* case LOCALVAR: */
1739 /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */
1740 /* count_ss_register++; */
1742 /* count_ss_spilled++; */
1745 if (!(src->flags & INMEMORY))
1746 count_argument_mem_ss++;
1748 count_argument_reg_ss++;
1752 /* if (IS_FLT_DBL_TYPE(src->type)) { */
1753 /* if (src->varnum < FLT_ARG_CNT) { */
1754 /* count_ss_register++; */
1758 /* #if defined(__POWERPC__) */
1759 /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */
1761 /* if (src->varnum < INT_ARG_CNT) { */
1763 /* count_ss_register++; */
1767 /* count_ss_spilled++; */
1774 } /* while instructions */
1778 } /* while blocks */
1779 count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
1780 if (in_register) count_method_in_register++;
1782 printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
1785 #endif /* defined(ENABLE_STATISTICS) */
1789 * These are local overrides for various environment variables in Emacs.
1790 * Please do not remove this and leave it at the end of the file, where
1791 * Emacs will automagically detect them.
1792 * ---------------------------------------------------------------------
1795 * indent-tabs-mode: t
1799 * vim:noexpandtab:sw=4:ts=4: