1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
33 $Id: stack.c 5428 2006-09-08 16:26:59Z edwin $
49 #include "mm/memory.h"
50 #include "native/native.h"
51 #include "toolbox/logging.h"
52 #include "vm/global.h"
53 #include "vm/builtin.h"
54 #include "vm/options.h"
55 #include "vm/resolve.h"
56 #include "vm/statistics.h"
57 #include "vm/stringlocal.h"
58 #include "vm/jit/cfg.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/abi.h"
61 #include "vm/jit/show.h"
63 #if defined(ENABLE_DISASSEMBLER)
64 # include "vm/jit/disass.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/stack.h"
70 #if defined(ENABLE_LSRA)
71 # include "vm/jit/allocator/lsra.h"
74 /*#define STACK_VERBOSE*/
77 /* macro for saving #ifdefs ***************************************************/
79 #if defined(ENABLE_INTRP)
80 #define IF_INTRP(x) if (opt_intrp) { x }
81 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
84 #define IF_NO_INTRP(x) { x }
87 #if defined(ENABLE_INTRP)
88 #if defined(ENABLE_JIT)
89 #define IF_JIT(x) if (!opt_intrp) { x }
93 #else /* !defined(ENABLE_INTRP) */
94 #define IF_JIT(x) { x }
95 #endif /* defined(ENABLE_INTRP) */
97 #if defined(ENABLE_STATISTICS)
98 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
101 if (stackdepth >= 10) \
102 count_store_depth[10]++; \
104 count_store_depth[stackdepth]++; \
107 #else /* !defined(ENABLE_STATISTICS) */
108 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
111 /* stackdata_t ****************************************************************/
113 typedef struct stackdata_t stackdata_t;
125 /* stack_init ******************************************************************
127 Initialized the stack analysis subsystem (called by jit_init).
129 *******************************************************************************/
131 bool stack_init(void)
137 /* stack_analyse ***************************************************************
139 Analyse_stack uses the intermediate code created by parse.c to
140 build a model of the JVM operand stack for the current method.
142 The following checks are performed:
143 - check for operand stack underflow (before each instruction)
144 - check for operand stack overflow (after[1] each instruction)
145 - check for matching stack depth at merging points
146 - check for matching basic types[2] at merging points
147 - check basic types for instruction input (except for BUILTIN*
148 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
150 [1]) Checking this after the instruction should be ok. parse.c
151 counts the number of required stack slots in such a way that it is
152 only vital that we don't exceed `maxstack` at basic block
155 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
156 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
157 types are not discerned.
159 *******************************************************************************/
161 #define GET_NEW_INDEX(sd, new_varindex) \
163 assert((sd).vartop < (sd).varcount); \
164 (new_varindex) = ((sd).vartop)++; \
167 /* not implemented now, can be used to reuse varindices */
168 /* pay attention to not release a localvar once implementing it! */
169 #define RELEASE_INDEX(sd, varindex)
171 /* with the new vars setting an OUTVAR is not as trivial as changing */
172 /* the varkind before. If varindex was a localvar, a new TEMPVAR has */
173 /* to be created for the slot and the OUTVAR flag set */
174 #define SET_OUTVAR(sd, sp) \
176 if (IS_LOCALVAR_SD(sd, (sp))) { \
177 GET_NEW_INDEX((sd),new_index); \
178 sp->varnum = new_index; \
181 SET_OUTVAR_BY_INDEX((sd), (sp)->varnum); \
184 #define SET_OUTVAR_BY_INDEX(sd, index) \
186 assert(index >= (sd).localcount); \
187 (sd).var[(index)].flags |= OUTVAR; \
190 #define SET_TEMPVAR(sp) \
192 if ( IS_LOCALVAR( (sp) ) ) { \
193 GET_NEW_INDEX(sd, new_index); \
194 (sp)->varnum = new_index; \
195 sd.var[(sp)->varnum].flags = copy->flags; \
197 sd.var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC); \
200 #define SET_PREALLOC(sp) \
202 assert(!IS_LOCALVAR((sp))); \
203 sd.var[(sp)->varnum].flags |= PREALLOC; \
206 #define IS_OUTVAR(sp) \
207 (sd.var[(sp)->varnum].flags & OUTVAR)
209 #define IS_PREALLOC(sp) \
210 (sd.var[(sp)->varnum].flags & PREALLOC)
212 #define IS_TEMPVAR(sp) \
213 ( (sd.var[(sp)->varnum].flags & (OUTVAR | PREALLOC) \
214 && (((sp)->varnum < sd.localcount)) == 0) )
216 #define IS_LOCALVAR_SD(sd, sp) \
217 ((sp)->varnum < (sd).localcount)
219 #define IS_LOCALVAR(sp) \
220 IS_LOCALVAR_SD(sd, (sp))
223 (iptr->s1.varindex = -1)
225 #define USE_S1_LOCAL(type1)
227 #define USE_S1(type1) \
230 CHECK_BASIC_TYPE(type1, curstack->type); \
231 iptr->s1.varindex = curstack->varnum; \
237 iptr->s1.varindex = curstack->varnum; \
240 #define USE_S1_S2(type1, type2) \
243 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
244 CHECK_BASIC_TYPE(type2, curstack->type); \
245 iptr->sx.s23.s2.varindex = curstack->varnum; \
246 iptr->s1.varindex = curstack->prev->varnum; \
249 #define USE_S1_S2_ANY_ANY \
252 iptr->sx.s23.s2.varindex = curstack->varnum; \
253 iptr->s1.varindex = curstack->prev->varnum; \
256 #define USE_S1_S2_S3(type1, type2, type3) \
259 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
260 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
261 CHECK_BASIC_TYPE(type3, curstack->type); \
262 iptr->sx.s23.s3.varindex = curstack->varnum; \
263 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
264 iptr->s1.varindex = curstack->prev->prev->varnum; \
268 (iptr->dst.varindex = -1)
270 #define DST(typed, index) \
272 NEWSTACKn((typed),(index)); \
273 iptr->dst.varindex = (index); \
276 /* XXX temporatily turn off coalescing */
278 #define DST_LOCALVAR(typed, index) \
280 NEWSTACK((typed), LOCALVAR, (index)); \
281 iptr->dst.varindex = (index); \
284 #define DST_LOCALVAR(typed, index) \
286 GET_NEW_INDEX(sd, new_index); \
287 NEWSTACKn((typed), (new_index)); \
288 iptr->dst.varindex = (new_index); \
292 #define OP0_1(typed) \
295 GET_NEW_INDEX(sd, new_index); \
296 DST(typed, new_index); \
307 #define OP1_BRANCH(type1) \
313 #define OP1_1(type1, typed) \
316 GET_NEW_INDEX(sd, new_index); \
317 DST(typed, new_index); \
320 #define OP2_1(type1, type2, typed) \
322 POP_S1_S2(type1, type2); \
323 GET_NEW_INDEX(sd, new_index); \
324 DST(typed, new_index); \
328 /* XXX turn off coalescing */
330 #define DUP_SLOT(sp) \
332 if ((sp)->varkind != TEMPVAR) { \
333 GET_NEW_INDEX(sd, new_index); \
334 NEWSTACK((sp)->type, TEMPVAR, new_index); \
337 NEWSTACK((sp)->type, (sp)->varkind, (sp)->varnum); \
340 #define DUP_SLOT(sp) \
342 GET_NEW_INDEX(sd, new_index); \
343 NEWSTACK((sp)->type, TEMPVAR, new_index); \
347 #define POP_S1(type1) \
350 if (curstack->varkind == UNDEFVAR) \
351 curstack->varkind = TEMPVAR; \
352 curstack = curstack->prev; \
358 if (curstack->varkind == UNDEFVAR) \
359 curstack->varkind = TEMPVAR; \
360 curstack = curstack->prev; \
363 #define POP_S1_S2(type1, type2) \
365 USE_S1_S2(type1, type2); \
366 if (curstack->varkind == UNDEFVAR) \
367 curstack->varkind = TEMPVAR; \
368 if (curstack->prev->varkind == UNDEFVAR) \
369 curstack->prev->varkind = TEMPVAR; \
370 curstack = curstack->prev->prev; \
373 #define POP_S1_S2_ANY_ANY \
376 if (curstack->varkind == UNDEFVAR) \
377 curstack->varkind = TEMPVAR; \
378 if (curstack->prev->varkind == UNDEFVAR) \
379 curstack->prev->varkind = TEMPVAR; \
380 curstack = curstack->prev->prev; \
383 #define POP_S1_S2_S3(type1, type2, type3) \
385 USE_S1_S2_S3(type1, type2, type3); \
386 if (curstack->varkind == UNDEFVAR) \
387 curstack->varkind = TEMPVAR; \
388 if (curstack->prev->varkind == UNDEFVAR) \
389 curstack->prev->varkind = TEMPVAR; \
390 if (curstack->prev->prev->varkind == UNDEFVAR) \
391 curstack->prev->prev->varkind = TEMPVAR; \
392 curstack = curstack->prev->prev->prev; \
409 #define OP1_0(type1) \
416 #define OP2_0(type1, type2) \
418 POP_S1_S2(type1, type2); \
423 #define OP2_BRANCH(type1, type2) \
425 POP_S1_S2(type1, type2); \
429 #define OP2_0_ANY_ANY \
436 #define OP3_0(type1, type2, type3) \
438 POP_S1_S2_S3(type1, type2, type3); \
443 #define LOAD(type1, index) \
445 DST_LOCALVAR(type1, index); \
449 #define STORE(type1, index) \
455 #if defined(ENABLE_VERIFIER)
456 #define MARKREACHED(b, c) \
458 if (!stack_mark_reached(&sd, (b), curstack, stackdepth)) \
462 #define MARKREACHED(b, c) \
464 (void) stack_mark_reached(&sd, (b), curstack, stackdepth); \
468 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
470 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
471 MARKREACHED(tempbptr, tempsp); \
474 #define BRANCH(tempbptr, tempsp) \
476 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
477 MARKREACHED(tempbptr, tempsp); \
480 /* does not check input stackdepth */
481 #define MOVE_COPY_UP(o, v) \
484 iptr->s1.varindex = (v)->varnum; \
486 iptr->dst.varindex = curstack->varnum; \
490 #define COPY_DOWN(s, d) \
492 iptr->opc = ICMD_COPY; \
493 iptr->s1.varindex = (s)->varnum; \
494 iptr->dst.varindex = (d)->varnum; \
497 /* MARKREACHED marks the destination block <b> as reached. If this
498 * block has been reached before we check if stack depth and types
499 * match. Otherwise the destination block receives a copy of the
500 * current stack as its input stack.
502 * b...destination block
506 static bool stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
511 #if defined(ENABLE_VERIFIER)
512 int expectedtype; /* used by CHECK_BASIC_TYPE */
516 b->bitflags |= BBFLAG_REPLACEMENT;
518 if (b->flags < BBREACHED) {
519 /* b is reached for the first time. Create its instack */
520 COPYCURSTACK(*sd, sp);
521 b->flags = BBREACHED;
523 b->indepth = stackdepth;
524 b->invars = DMNEW(s4, stackdepth);
525 for (i = stackdepth; i--; sp = sp->prev) {
526 b->invars[i] = sp->varnum;
531 /* b has been reached before. Check that its instack matches */
534 CHECK_STACK_DEPTH(b->indepth, stackdepth);
536 CHECK_BASIC_TYPE(sp->type,tsp->type);
544 #if defined(ENABLE_VERIFIER)
545 throw_stack_depth_error:
546 exceptions_throw_verifyerror(m,"Stack depth mismatch");
549 throw_stack_type_error:
550 exceptions_throw_verifyerror_for_stack(m, expectedtype);
555 bool new_stack_analyse(jitdata *jd)
557 methodinfo *m; /* method being analyzed */
562 int b_count; /* basic block counter */
563 int b_index; /* basic block index */
565 stackptr curstack; /* current stack top */
567 int opcode; /* opcode of current instruction */
570 int len; /* # of instructions after the current one */
571 bool superblockend; /* if true, no fallthrough to next block */
572 bool repeat; /* if true, outermost loop must run again */
573 bool deadcode; /* true if no live code has been reached */
574 instruction *iptr; /* the current instruction */
577 stackptr *last_store_boundary;
578 stackptr last_pei_boundary;
579 stackptr last_dup_boundary;
581 stackptr src1, src2, src3, src4, dst1, dst2;
583 branch_target_t *table;
584 lookup_target_t *lookup;
585 #if defined(ENABLE_VERIFIER)
586 int expectedtype; /* used by CHECK_BASIC_TYPE */
588 builtintable_entry *bte;
590 constant_FMIref *fmiref;
591 #if defined(ENABLE_STATISTICS)
592 int iteration_count; /* number of iterations of analysis */
594 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
596 #if defined(STACK_VERBOSE)
597 new_show_method(jd, SHOW_PARSE);
600 /* get required compiler data - initialization */
607 /* initialize the stackdata_t struct */
609 sd.varcount = jd->varcount;
610 sd.vartop = jd->vartop;
611 sd.localcount = jd->localcount;
613 sd.new = jd->new_stack;
615 #if defined(ENABLE_LSRA)
619 #if defined(ENABLE_STATISTICS)
623 /* init jd->interface_map */
625 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
626 for (i = 0; i < m->maxstack * 5; i++)
627 jd->interface_map[i].flags = UNUSED;
629 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
631 /* initialize in-stack of first block */
633 jd->new_basicblocks[0].flags = BBREACHED;
634 jd->new_basicblocks[0].instack = NULL;
635 jd->new_basicblocks[0].invars = NULL;
636 jd->new_basicblocks[0].indepth = 0;
638 /* initialize in-stack of exception handlers */
640 for (i = 0; i < cd->exceptiontablelength; i++) {
641 sd.bptr = BLOCK_OF(cd->exceptiontable[i].handlerpc);
642 sd.bptr->flags = BBREACHED;
643 sd.bptr->type = BBTYPE_EXH;
644 sd.bptr->instack = sd.new;
645 sd.bptr->indepth = 1;
646 sd.bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
648 GET_NEW_INDEX(sd, new_index);
649 sd.bptr->invars = DMNEW(s4, 1);
650 sd.bptr->invars[0] = new_index;
651 NEWSTACK(TYPE_ADR, STACKVAR, new_index);
653 jd->interface_map[0 * 5 + TYPE_ADR].flags = 0;
654 SET_OUTVAR_BY_INDEX(sd, new_index);
657 /* stack analysis loop (until fixpoint reached) **************************/
660 #if defined(ENABLE_STATISTICS)
664 /* initialize loop over basic blocks */
666 b_count = jd->new_basicblockcount;
667 sd.bptr = jd->new_basicblocks;
668 superblockend = true;
673 /* iterate over basic blocks *****************************************/
675 while (--b_count >= 0) {
676 #if defined(STACK_VERBOSE)
677 printf("----\nANALYZING BLOCK L%03d ", sd.bptr->nr);
678 if (sd.bptr->type == BBTYPE_EXH) printf("EXH\n");
679 else if (sd.bptr->type == BBTYPE_SBR) printf("SBR\n");
680 else printf("STD\n");
684 if (sd.bptr->flags == BBDELETED) {
685 /* This block has been deleted - do nothing. */
687 else if (superblockend && (sd.bptr->flags < BBREACHED)) {
688 /* This block has not been reached so far, and we */
689 /* don't fall into it, so we'll have to iterate again. */
692 else if (sd.bptr->flags <= BBREACHED) {
694 /* We know that sd.bptr->flags == BBREACHED. */
695 /* This block has been reached before. */
696 stackdepth = sd.bptr->indepth;
698 else if (sd.bptr->flags < BBREACHED) {
699 /* This block is reached for the first time now */
700 /* by falling through from the previous block. */
701 /* Create the instack (propagated). */
702 COPYCURSTACK(sd, copy);
703 sd.bptr->instack = copy;
705 sd.bptr->invars = DMNEW(s4, stackdepth);
706 for (i=stackdepth; i--; copy = copy->prev)
707 sd.bptr->invars[i] = copy->varnum;
708 sd.bptr->indepth = stackdepth;
711 /* This block has been reached before. now we are */
712 /* falling into it from the previous block. */
713 /* Check that stack depth is well-defined. */
714 CHECK_STACK_DEPTH(sd.bptr->indepth, stackdepth);
716 /* XXX check stack types? */
719 /* set up local variables for analyzing this block */
721 curstack = sd.bptr->instack;
723 superblockend = false;
724 len = sd.bptr->icount;
725 iptr = sd.bptr->iinstr;
726 b_index = sd.bptr - jd->new_basicblocks;
728 /* mark the block as analysed */
730 sd.bptr->flags = BBFINISHED;
732 /* reset variables for dependency checking */
734 last_pei_boundary = sd.new;
735 last_dup_boundary = sd.new;
736 for( i = 0; i < cd->maxlocals; i++)
737 last_store_boundary[i] = sd.new;
739 /* XXX store the start of the block's stack representation */
741 sd.bptr->stack = sd.new;
743 #if defined(STACK_VERBOSE)
745 for( copy = sd.bptr->instack; copy; copy = copy->prev ) {
746 printf("%2d(%d", copy->varnum, copy->type);
749 if (IS_PREALLOC(copy))
755 printf("INVARS - indices:\t\n");
756 for (i=0; i<sd.bptr->indepth; ++i) {
757 printf("%d ", sd.bptr->invars[i]);
763 /* iterate over ICMDs ****************************************/
767 #if defined(STACK_VERBOSE)
768 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
769 for( copy = curstack; copy; copy = copy->prev ) {
770 printf("%2d(%d", copy->varnum, copy->type);
773 if (IS_PREALLOC(copy))
780 /* fetch the current opcode */
784 /* automatically replace some ICMDs with builtins */
786 #if defined(USEBUILTINTABLE)
788 bte = builtintable_get_automatic(opcode);
790 if (bte && bte->opcode == opcode) {
791 iptr->opc = ICMD_BUILTIN;
792 iptr->flags.bits = 0;
793 iptr->sx.s23.s3.bte = bte;
794 /* iptr->line is already set */
795 jd->isleafmethod = false;
799 #endif /* defined(USEBUILTINTABLE) */
801 /* main opcode switch *************************************/
814 last_pei_boundary = sd.new;
815 COUNT(count_check_null);
818 CLR_DST; /* XXX live through? */
823 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
825 USE_S1_LOCAL(TYPE_ADR);
828 #if !defined(NEW_VAR)
829 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
831 superblockend = true;
835 COUNT(count_pcmd_return);
838 superblockend = true;
842 /* pop 0 push 1 const */
844 /************************** ICONST OPTIMIZATIONS **************************/
847 COUNT(count_pcmd_load);
851 switch (iptr[1].opc) {
853 iptr->opc = ICMD_IADDCONST;
857 iptr[1].opc = ICMD_NOP;
858 OP1_1(TYPE_INT, TYPE_INT);
859 COUNT(count_pcmd_op);
863 iptr->opc = ICMD_ISUBCONST;
864 goto icmd_iconst_tail;
865 #if SUPPORT_CONST_MUL
867 iptr->opc = ICMD_IMULCONST;
868 goto icmd_iconst_tail;
869 #else /* SUPPORT_CONST_MUL */
871 if (iptr->sx.val.i == 0x00000002)
873 else if (iptr->sx.val.i == 0x00000004)
875 else if (iptr->sx.val.i == 0x00000008)
877 else if (iptr->sx.val.i == 0x00000010)
879 else if (iptr->sx.val.i == 0x00000020)
881 else if (iptr->sx.val.i == 0x00000040)
883 else if (iptr->sx.val.i == 0x00000080)
885 else if (iptr->sx.val.i == 0x00000100)
887 else if (iptr->sx.val.i == 0x00000200)
889 else if (iptr->sx.val.i == 0x00000400)
891 else if (iptr->sx.val.i == 0x00000800)
893 else if (iptr->sx.val.i == 0x00001000)
895 else if (iptr->sx.val.i == 0x00002000)
897 else if (iptr->sx.val.i == 0x00004000)
899 else if (iptr->sx.val.i == 0x00008000)
901 else if (iptr->sx.val.i == 0x00010000)
903 else if (iptr->sx.val.i == 0x00020000)
905 else if (iptr->sx.val.i == 0x00040000)
907 else if (iptr->sx.val.i == 0x00080000)
909 else if (iptr->sx.val.i == 0x00100000)
911 else if (iptr->sx.val.i == 0x00200000)
913 else if (iptr->sx.val.i == 0x00400000)
915 else if (iptr->sx.val.i == 0x00800000)
917 else if (iptr->sx.val.i == 0x01000000)
919 else if (iptr->sx.val.i == 0x02000000)
921 else if (iptr->sx.val.i == 0x04000000)
923 else if (iptr->sx.val.i == 0x08000000)
925 else if (iptr->sx.val.i == 0x10000000)
927 else if (iptr->sx.val.i == 0x20000000)
929 else if (iptr->sx.val.i == 0x40000000)
931 else if (iptr->sx.val.i == 0x80000000)
936 iptr->opc = ICMD_IMULPOW2;
937 goto icmd_iconst_tail;
938 #endif /* SUPPORT_CONST_MUL */
940 if (iptr->sx.val.i == 0x00000002)
942 else if (iptr->sx.val.i == 0x00000004)
944 else if (iptr->sx.val.i == 0x00000008)
946 else if (iptr->sx.val.i == 0x00000010)
948 else if (iptr->sx.val.i == 0x00000020)
950 else if (iptr->sx.val.i == 0x00000040)
952 else if (iptr->sx.val.i == 0x00000080)
954 else if (iptr->sx.val.i == 0x00000100)
956 else if (iptr->sx.val.i == 0x00000200)
958 else if (iptr->sx.val.i == 0x00000400)
960 else if (iptr->sx.val.i == 0x00000800)
962 else if (iptr->sx.val.i == 0x00001000)
964 else if (iptr->sx.val.i == 0x00002000)
966 else if (iptr->sx.val.i == 0x00004000)
968 else if (iptr->sx.val.i == 0x00008000)
970 else if (iptr->sx.val.i == 0x00010000)
972 else if (iptr->sx.val.i == 0x00020000)
974 else if (iptr->sx.val.i == 0x00040000)
976 else if (iptr->sx.val.i == 0x00080000)
978 else if (iptr->sx.val.i == 0x00100000)
980 else if (iptr->sx.val.i == 0x00200000)
982 else if (iptr->sx.val.i == 0x00400000)
984 else if (iptr->sx.val.i == 0x00800000)
986 else if (iptr->sx.val.i == 0x01000000)
988 else if (iptr->sx.val.i == 0x02000000)
990 else if (iptr->sx.val.i == 0x04000000)
992 else if (iptr->sx.val.i == 0x08000000)
994 else if (iptr->sx.val.i == 0x10000000)
996 else if (iptr->sx.val.i == 0x20000000)
998 else if (iptr->sx.val.i == 0x40000000)
1000 else if (iptr->sx.val.i == 0x80000000)
1001 iptr->sx.val.i = 31;
1005 iptr->opc = ICMD_IDIVPOW2;
1006 goto icmd_iconst_tail;
1009 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
1010 if ((iptr->sx.val.i == 0x00000002) ||
1011 (iptr->sx.val.i == 0x00000004) ||
1012 (iptr->sx.val.i == 0x00000008) ||
1013 (iptr->sx.val.i == 0x00000010) ||
1014 (iptr->sx.val.i == 0x00000020) ||
1015 (iptr->sx.val.i == 0x00000040) ||
1016 (iptr->sx.val.i == 0x00000080) ||
1017 (iptr->sx.val.i == 0x00000100) ||
1018 (iptr->sx.val.i == 0x00000200) ||
1019 (iptr->sx.val.i == 0x00000400) ||
1020 (iptr->sx.val.i == 0x00000800) ||
1021 (iptr->sx.val.i == 0x00001000) ||
1022 (iptr->sx.val.i == 0x00002000) ||
1023 (iptr->sx.val.i == 0x00004000) ||
1024 (iptr->sx.val.i == 0x00008000) ||
1025 (iptr->sx.val.i == 0x00010000) ||
1026 (iptr->sx.val.i == 0x00020000) ||
1027 (iptr->sx.val.i == 0x00040000) ||
1028 (iptr->sx.val.i == 0x00080000) ||
1029 (iptr->sx.val.i == 0x00100000) ||
1030 (iptr->sx.val.i == 0x00200000) ||
1031 (iptr->sx.val.i == 0x00400000) ||
1032 (iptr->sx.val.i == 0x00800000) ||
1033 (iptr->sx.val.i == 0x01000000) ||
1034 (iptr->sx.val.i == 0x02000000) ||
1035 (iptr->sx.val.i == 0x04000000) ||
1036 (iptr->sx.val.i == 0x08000000) ||
1037 (iptr->sx.val.i == 0x10000000) ||
1038 (iptr->sx.val.i == 0x20000000) ||
1039 (iptr->sx.val.i == 0x40000000) ||
1040 (iptr->sx.val.i == 0x80000000))
1042 iptr->opc = ICMD_IREMPOW2;
1043 iptr->sx.val.i -= 1;
1044 goto icmd_iconst_tail;
1047 #if SUPPORT_CONST_LOGICAL
1049 iptr->opc = ICMD_IANDCONST;
1050 goto icmd_iconst_tail;
1053 iptr->opc = ICMD_IORCONST;
1054 goto icmd_iconst_tail;
1057 iptr->opc = ICMD_IXORCONST;
1058 goto icmd_iconst_tail;
1060 #endif /* SUPPORT_CONST_LOGICAL */
1062 iptr->opc = ICMD_ISHLCONST;
1063 goto icmd_iconst_tail;
1066 iptr->opc = ICMD_ISHRCONST;
1067 goto icmd_iconst_tail;
1070 iptr->opc = ICMD_IUSHRCONST;
1071 goto icmd_iconst_tail;
1072 #if SUPPORT_LONG_SHIFT
1074 iptr->opc = ICMD_LSHLCONST;
1075 goto icmd_lconst_tail;
1078 iptr->opc = ICMD_LSHRCONST;
1079 goto icmd_lconst_tail;
1082 iptr->opc = ICMD_LUSHRCONST;
1083 goto icmd_lconst_tail;
1084 #endif /* SUPPORT_LONG_SHIFT */
1085 case ICMD_IF_ICMPEQ:
1086 iptr[1].opc = ICMD_IFEQ;
1090 /* set the constant for the following icmd */
1091 iptr[1].sx.val.i = iptr->sx.val.i;
1093 /* this instruction becomes a nop */
1094 iptr->opc = ICMD_NOP;
1097 case ICMD_IF_ICMPLT:
1098 iptr[1].opc = ICMD_IFLT;
1099 goto icmd_if_icmp_tail;
1101 case ICMD_IF_ICMPLE:
1102 iptr[1].opc = ICMD_IFLE;
1103 goto icmd_if_icmp_tail;
1105 case ICMD_IF_ICMPNE:
1106 iptr[1].opc = ICMD_IFNE;
1107 goto icmd_if_icmp_tail;
1109 case ICMD_IF_ICMPGT:
1110 iptr[1].opc = ICMD_IFGT;
1111 goto icmd_if_icmp_tail;
1113 case ICMD_IF_ICMPGE:
1114 iptr[1].opc = ICMD_IFGE;
1115 goto icmd_if_icmp_tail;
1117 #if SUPPORT_CONST_STORE
1122 IF_INTRP( goto normal_ICONST; )
1123 # if SUPPORT_CONST_STORE_ZERO_ONLY
1124 if (iptr->sx.val.i != 0)
1127 switch (iptr[1].opc) {
1129 iptr->opc = ICMD_IASTORECONST;
1130 iptr->flags.bits |= INS_FLAG_CHECK;
1133 iptr->opc = ICMD_BASTORECONST;
1134 iptr->flags.bits |= INS_FLAG_CHECK;
1137 iptr->opc = ICMD_CASTORECONST;
1138 iptr->flags.bits |= INS_FLAG_CHECK;
1141 iptr->opc = ICMD_SASTORECONST;
1142 iptr->flags.bits |= INS_FLAG_CHECK;
1146 iptr[1].opc = ICMD_NOP;
1148 /* copy the constant to s3 */
1149 /* XXX constval -> astoreconstval? */
1150 iptr->sx.s23.s3.constval = iptr->sx.val.i;
1151 OP2_0(TYPE_ADR, TYPE_INT);
1152 COUNT(count_pcmd_op);
1155 case ICMD_PUTSTATIC:
1157 IF_INTRP( goto normal_ICONST; )
1158 # if SUPPORT_CONST_STORE_ZERO_ONLY
1159 if (iptr->sx.val.i != 0)
1162 /* XXX check field type? */
1164 /* copy the constant to s2 */
1165 /* XXX constval -> fieldconstval? */
1166 iptr->sx.s23.s2.constval = iptr->sx.val.i;
1169 /* set the field reference (s3) */
1170 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
1171 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
1172 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1175 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
1178 switch (iptr[1].opc) {
1179 case ICMD_PUTSTATIC:
1180 iptr->opc = ICMD_PUTSTATICCONST;
1184 iptr->opc = ICMD_PUTFIELDCONST;
1189 iptr[1].opc = ICMD_NOP;
1190 COUNT(count_pcmd_op);
1192 #endif /* SUPPORT_CONST_STORE */
1198 /* if we get here, the ICONST has been optimized */
1202 /* normal case of an unoptimized ICONST */
1206 /************************** LCONST OPTIMIZATIONS **************************/
1209 COUNT(count_pcmd_load);
1213 /* switch depending on the following instruction */
1215 switch (iptr[1].opc) {
1216 #if SUPPORT_LONG_ADD
1218 iptr->opc = ICMD_LADDCONST;
1222 /* instruction of type LONG -> LONG */
1223 iptr[1].opc = ICMD_NOP;
1224 OP1_1(TYPE_LNG, TYPE_LNG);
1225 COUNT(count_pcmd_op);
1229 iptr->opc = ICMD_LSUBCONST;
1230 goto icmd_lconst_tail;
1232 #endif /* SUPPORT_LONG_ADD */
1233 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
1235 iptr->opc = ICMD_LMULCONST;
1236 goto icmd_lconst_tail;
1237 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1238 # if SUPPORT_LONG_SHIFT
1240 if (iptr->sx.val.l == 0x00000002)
1242 else if (iptr->sx.val.l == 0x00000004)
1244 else if (iptr->sx.val.l == 0x00000008)
1246 else if (iptr->sx.val.l == 0x00000010)
1248 else if (iptr->sx.val.l == 0x00000020)
1250 else if (iptr->sx.val.l == 0x00000040)
1252 else if (iptr->sx.val.l == 0x00000080)
1254 else if (iptr->sx.val.l == 0x00000100)
1256 else if (iptr->sx.val.l == 0x00000200)
1258 else if (iptr->sx.val.l == 0x00000400)
1259 iptr->sx.val.i = 10;
1260 else if (iptr->sx.val.l == 0x00000800)
1261 iptr->sx.val.i = 11;
1262 else if (iptr->sx.val.l == 0x00001000)
1263 iptr->sx.val.i = 12;
1264 else if (iptr->sx.val.l == 0x00002000)
1265 iptr->sx.val.i = 13;
1266 else if (iptr->sx.val.l == 0x00004000)
1267 iptr->sx.val.i = 14;
1268 else if (iptr->sx.val.l == 0x00008000)
1269 iptr->sx.val.i = 15;
1270 else if (iptr->sx.val.l == 0x00010000)
1271 iptr->sx.val.i = 16;
1272 else if (iptr->sx.val.l == 0x00020000)
1273 iptr->sx.val.i = 17;
1274 else if (iptr->sx.val.l == 0x00040000)
1275 iptr->sx.val.i = 18;
1276 else if (iptr->sx.val.l == 0x00080000)
1277 iptr->sx.val.i = 19;
1278 else if (iptr->sx.val.l == 0x00100000)
1279 iptr->sx.val.i = 20;
1280 else if (iptr->sx.val.l == 0x00200000)
1281 iptr->sx.val.i = 21;
1282 else if (iptr->sx.val.l == 0x00400000)
1283 iptr->sx.val.i = 22;
1284 else if (iptr->sx.val.l == 0x00800000)
1285 iptr->sx.val.i = 23;
1286 else if (iptr->sx.val.l == 0x01000000)
1287 iptr->sx.val.i = 24;
1288 else if (iptr->sx.val.l == 0x02000000)
1289 iptr->sx.val.i = 25;
1290 else if (iptr->sx.val.l == 0x04000000)
1291 iptr->sx.val.i = 26;
1292 else if (iptr->sx.val.l == 0x08000000)
1293 iptr->sx.val.i = 27;
1294 else if (iptr->sx.val.l == 0x10000000)
1295 iptr->sx.val.i = 28;
1296 else if (iptr->sx.val.l == 0x20000000)
1297 iptr->sx.val.i = 29;
1298 else if (iptr->sx.val.l == 0x40000000)
1299 iptr->sx.val.i = 30;
1300 else if (iptr->sx.val.l == 0x80000000)
1301 iptr->sx.val.i = 31;
1305 iptr->opc = ICMD_LMULPOW2;
1306 goto icmd_lconst_tail;
1307 # endif /* SUPPORT_LONG_SHIFT */
1308 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
1309 #if SUPPORT_LONG_DIV_POW2
1311 if (iptr->sx.val.l == 0x00000002)
1313 else if (iptr->sx.val.l == 0x00000004)
1315 else if (iptr->sx.val.l == 0x00000008)
1317 else if (iptr->sx.val.l == 0x00000010)
1319 else if (iptr->sx.val.l == 0x00000020)
1321 else if (iptr->sx.val.l == 0x00000040)
1323 else if (iptr->sx.val.l == 0x00000080)
1325 else if (iptr->sx.val.l == 0x00000100)
1327 else if (iptr->sx.val.l == 0x00000200)
1329 else if (iptr->sx.val.l == 0x00000400)
1330 iptr->sx.val.i = 10;
1331 else if (iptr->sx.val.l == 0x00000800)
1332 iptr->sx.val.i = 11;
1333 else if (iptr->sx.val.l == 0x00001000)
1334 iptr->sx.val.i = 12;
1335 else if (iptr->sx.val.l == 0x00002000)
1336 iptr->sx.val.i = 13;
1337 else if (iptr->sx.val.l == 0x00004000)
1338 iptr->sx.val.i = 14;
1339 else if (iptr->sx.val.l == 0x00008000)
1340 iptr->sx.val.i = 15;
1341 else if (iptr->sx.val.l == 0x00010000)
1342 iptr->sx.val.i = 16;
1343 else if (iptr->sx.val.l == 0x00020000)
1344 iptr->sx.val.i = 17;
1345 else if (iptr->sx.val.l == 0x00040000)
1346 iptr->sx.val.i = 18;
1347 else if (iptr->sx.val.l == 0x00080000)
1348 iptr->sx.val.i = 19;
1349 else if (iptr->sx.val.l == 0x00100000)
1350 iptr->sx.val.i = 20;
1351 else if (iptr->sx.val.l == 0x00200000)
1352 iptr->sx.val.i = 21;
1353 else if (iptr->sx.val.l == 0x00400000)
1354 iptr->sx.val.i = 22;
1355 else if (iptr->sx.val.l == 0x00800000)
1356 iptr->sx.val.i = 23;
1357 else if (iptr->sx.val.l == 0x01000000)
1358 iptr->sx.val.i = 24;
1359 else if (iptr->sx.val.l == 0x02000000)
1360 iptr->sx.val.i = 25;
1361 else if (iptr->sx.val.l == 0x04000000)
1362 iptr->sx.val.i = 26;
1363 else if (iptr->sx.val.l == 0x08000000)
1364 iptr->sx.val.i = 27;
1365 else if (iptr->sx.val.l == 0x10000000)
1366 iptr->sx.val.i = 28;
1367 else if (iptr->sx.val.l == 0x20000000)
1368 iptr->sx.val.i = 29;
1369 else if (iptr->sx.val.l == 0x40000000)
1370 iptr->sx.val.i = 30;
1371 else if (iptr->sx.val.l == 0x80000000)
1372 iptr->sx.val.i = 31;
1376 iptr->opc = ICMD_LDIVPOW2;
1377 goto icmd_lconst_tail;
1378 #endif /* SUPPORT_LONG_DIV_POW2 */
1380 #if SUPPORT_LONG_REM_POW2
1382 if ((iptr->sx.val.l == 0x00000002) ||
1383 (iptr->sx.val.l == 0x00000004) ||
1384 (iptr->sx.val.l == 0x00000008) ||
1385 (iptr->sx.val.l == 0x00000010) ||
1386 (iptr->sx.val.l == 0x00000020) ||
1387 (iptr->sx.val.l == 0x00000040) ||
1388 (iptr->sx.val.l == 0x00000080) ||
1389 (iptr->sx.val.l == 0x00000100) ||
1390 (iptr->sx.val.l == 0x00000200) ||
1391 (iptr->sx.val.l == 0x00000400) ||
1392 (iptr->sx.val.l == 0x00000800) ||
1393 (iptr->sx.val.l == 0x00001000) ||
1394 (iptr->sx.val.l == 0x00002000) ||
1395 (iptr->sx.val.l == 0x00004000) ||
1396 (iptr->sx.val.l == 0x00008000) ||
1397 (iptr->sx.val.l == 0x00010000) ||
1398 (iptr->sx.val.l == 0x00020000) ||
1399 (iptr->sx.val.l == 0x00040000) ||
1400 (iptr->sx.val.l == 0x00080000) ||
1401 (iptr->sx.val.l == 0x00100000) ||
1402 (iptr->sx.val.l == 0x00200000) ||
1403 (iptr->sx.val.l == 0x00400000) ||
1404 (iptr->sx.val.l == 0x00800000) ||
1405 (iptr->sx.val.l == 0x01000000) ||
1406 (iptr->sx.val.l == 0x02000000) ||
1407 (iptr->sx.val.l == 0x04000000) ||
1408 (iptr->sx.val.l == 0x08000000) ||
1409 (iptr->sx.val.l == 0x10000000) ||
1410 (iptr->sx.val.l == 0x20000000) ||
1411 (iptr->sx.val.l == 0x40000000) ||
1412 (iptr->sx.val.l == 0x80000000))
1414 iptr->opc = ICMD_LREMPOW2;
1415 iptr->sx.val.l -= 1;
1416 goto icmd_lconst_tail;
1419 #endif /* SUPPORT_LONG_REM_POW2 */
1421 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
1424 iptr->opc = ICMD_LANDCONST;
1425 goto icmd_lconst_tail;
1428 iptr->opc = ICMD_LORCONST;
1429 goto icmd_lconst_tail;
1432 iptr->opc = ICMD_LXORCONST;
1433 goto icmd_lconst_tail;
1434 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
1436 #if SUPPORT_LONG_CMP_CONST
1438 if ((len <= 1) || (iptr[2].sx.val.i != 0))
1441 /* switch on the instruction after LCONST - LCMP */
1443 switch (iptr[2].opc) {
1445 iptr->opc = ICMD_IF_LEQ;
1448 icmd_lconst_lcmp_tail:
1449 /* convert LCONST, LCMP, IFXX to IF_LXX */
1450 iptr->dst.insindex = iptr[2].dst.insindex;
1451 iptr[1].opc = ICMD_NOP;
1452 iptr[2].opc = ICMD_NOP;
1454 OP1_BRANCH(TYPE_LNG);
1455 BRANCH(tbptr, copy);
1456 COUNT(count_pcmd_bra);
1457 COUNT(count_pcmd_op);
1461 iptr->opc = ICMD_IF_LNE;
1462 goto icmd_lconst_lcmp_tail;
1465 iptr->opc = ICMD_IF_LLT;
1466 goto icmd_lconst_lcmp_tail;
1469 iptr->opc = ICMD_IF_LGT;
1470 goto icmd_lconst_lcmp_tail;
1473 iptr->opc = ICMD_IF_LLE;
1474 goto icmd_lconst_lcmp_tail;
1477 iptr->opc = ICMD_IF_LGE;
1478 goto icmd_lconst_lcmp_tail;
1482 } /* end switch on opcode after LCONST - LCMP */
1484 #endif /* SUPPORT_LONG_CMP_CONST */
1486 #if SUPPORT_CONST_STORE
1488 IF_INTRP( goto normal_LCONST; )
1489 # if SUPPORT_CONST_STORE_ZERO_ONLY
1490 if (iptr->sx.val.l != 0)
1493 #if SIZEOF_VOID_P == 4
1494 /* the constant must fit into a ptrint */
1495 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1498 /* move the constant to s3 */
1499 iptr->sx.s23.s3.constval = iptr->sx.val.l;
1501 iptr->opc = ICMD_LASTORECONST;
1502 iptr->flags.bits |= INS_FLAG_CHECK;
1503 OP2_0(TYPE_ADR, TYPE_INT);
1505 iptr[1].opc = ICMD_NOP;
1506 COUNT(count_pcmd_op);
1509 case ICMD_PUTSTATIC:
1511 IF_INTRP( goto normal_LCONST; )
1512 # if SUPPORT_CONST_STORE_ZERO_ONLY
1513 if (iptr->sx.val.l != 0)
1516 #if SIZEOF_VOID_P == 4
1517 /* the constant must fit into a ptrint */
1518 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
1521 /* XXX check field type? */
1523 /* copy the constant to s2 */
1524 /* XXX constval -> fieldconstval? */
1525 iptr->sx.s23.s2.constval = iptr->sx.val.l;
1529 #endif /* SUPPORT_CONST_STORE */
1533 } /* end switch opcode after LCONST */
1535 /* if we get here, the LCONST has been optimized */
1539 /* the normal case of an unoptimized LCONST */
1543 /************************ END OF LCONST OPTIMIZATIONS *********************/
1546 COUNT(count_pcmd_load);
1551 COUNT(count_pcmd_load);
1555 /************************** ACONST OPTIMIZATIONS **************************/
1558 last_pei_boundary = sd.new;
1559 COUNT(count_pcmd_load);
1560 #if SUPPORT_CONST_STORE
1561 IF_INTRP( goto normal_ACONST; )
1563 /* We can only optimize if the ACONST is resolved
1564 * and there is an instruction after it. */
1566 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
1569 switch (iptr[1].opc) {
1571 /* We can only optimize for NULL values
1572 * here because otherwise a checkcast is
1574 if (iptr->sx.val.anyptr != NULL)
1577 /* copy the constant (NULL) to s3 */
1578 iptr->sx.s23.s3.constval = 0;
1579 iptr->opc = ICMD_AASTORECONST;
1580 iptr->flags.bits |= INS_FLAG_CHECK;
1581 OP2_0(TYPE_ADR, TYPE_INT);
1583 iptr[1].opc = ICMD_NOP;
1584 COUNT(count_pcmd_op);
1587 case ICMD_PUTSTATIC:
1589 # if SUPPORT_CONST_STORE_ZERO_ONLY
1590 if (iptr->sx.val.anyptr != NULL)
1593 /* XXX check field type? */
1594 /* copy the constant to s2 */
1595 /* XXX constval -> fieldconstval? */
1596 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
1604 /* if we get here the ACONST has been optimized */
1608 #endif /* SUPPORT_CONST_STORE */
1613 /* pop 0 push 1 load */
1620 COUNT(count_load_instruction);
1621 i = opcode - ICMD_ILOAD; /* type */
1624 jd->local_map[iptr->s1.varindex * 5 + i];
1626 LOAD(i, iptr->s1.varindex);
1635 last_pei_boundary = sd.new;
1636 iptr->flags.bits |= INS_FLAG_CHECK;
1637 COUNT(count_check_null);
1638 COUNT(count_check_bound);
1639 COUNT(count_pcmd_mem);
1640 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
1647 last_pei_boundary = sd.new;
1648 iptr->flags.bits |= INS_FLAG_CHECK;
1649 COUNT(count_check_null);
1650 COUNT(count_check_bound);
1651 COUNT(count_pcmd_mem);
1652 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
1655 /* pop 0 push 0 iinc */
1658 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
1660 last_store_boundary[iptr->s1.varindex] = sd.new;
1663 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
1668 if ((copy->varkind == LOCALVAR) &&
1669 (copy->varnum == iptr->s1.varindex))
1671 copy->varkind = TEMPVAR;
1672 assert(IS_LOCALVAR(copy));
1679 iptr->dst.varindex = iptr->s1.varindex;
1682 /* pop 1 push 0 store */
1691 i = opcode - ICMD_ISTORE; /* type */
1692 javaindex = iptr->dst.varindex;
1693 j = iptr->dst.varindex =
1694 jd->local_map[javaindex * 5 + i];
1697 #if defined(ENABLE_STATISTICS)
1700 i = sd.new - curstack;
1702 count_store_length[20]++;
1704 count_store_length[i]++;
1707 count_store_depth[10]++;
1709 count_store_depth[i]++;
1712 /* check for conflicts as described in Figure 5.2 */
1714 copy = curstack->prev;
1717 if ((copy->varkind == LOCALVAR) &&
1718 (copy->varnum == j))
1720 copy->varkind = TEMPVAR;
1721 assert(IS_LOCALVAR(copy));
1728 /* if the variable is already coalesced, don't bother */
1730 if (IS_OUTVAR(curstack)
1731 || (curstack->varkind == LOCALVAR
1732 && curstack->varnum != j))
1735 /* there is no STORE Lj while curstack is live */
1737 if (curstack < last_store_boundary[javaindex])
1738 goto assume_conflict;
1740 /* there is no PEI while curstack is live */
1742 if (curstack < last_pei_boundary)
1743 goto assume_conflict;
1745 /*there is no non-consuming USE while curstack is live*/
1747 if (curstack < last_dup_boundary)
1748 goto assume_conflict;
1750 /* there is no DEF LOCALVAR(j) while curstack is live */
1752 copy = sd.new; /* most recent stackslot created + 1 */
1753 while (--copy > curstack) {
1754 if (copy->varkind == LOCALVAR && copy->varnum == j)
1755 goto assume_conflict;
1758 /* XXX temporatily turn off coalescing */ goto assume_conflict;
1760 /* coalesce the temporary variable with Lj */
1761 assert( (CURKIND == TEMPVAR) || (CURKIND == UNDEFVAR));
1762 assert(!IS_LOCALVAR(curstack));
1763 assert(!IS_OUTVAR(curstack));
1764 assert(!IS_PREALLOC(curstack));
1766 RELEASE_INDEX(sd, curstack);
1767 curstack->varkind = LOCALVAR;
1768 curstack->varnum = j;
1771 /* revert the coalescing, if it has been done earlier */
1773 if ((curstack->varkind == LOCALVAR)
1774 && (curstack->varnum == j))
1776 curstack->varkind = TEMPVAR;
1777 assert(IS_LOCALVAR(curstack));
1778 SET_TEMPVAR(curstack);
1781 /* remember the stack boundary at this store */
1783 last_store_boundary[javaindex] = sd.new;
1785 STORE(opcode - ICMD_ISTORE, j);
1791 last_pei_boundary = sd.new;
1792 iptr->flags.bits |= INS_FLAG_CHECK;
1793 COUNT(count_check_null);
1794 COUNT(count_check_bound);
1795 COUNT(count_pcmd_mem);
1797 bte = builtintable_get_internal(BUILTIN_canstore);
1800 if (md->memuse > rd->memuse)
1801 rd->memuse = md->memuse;
1802 if (md->argintreguse > rd->argintreguse)
1803 rd->argintreguse = md->argintreguse;
1804 /* XXX non-leaf method? */
1806 /* make all stack variables saved */
1810 sd.var[copy->varnum].flags |= SAVEDVAR;
1811 /* in case copy->varnum is/will be a LOCALVAR */
1812 /* once and set back to a non LOCALVAR */
1813 /* the correct SAVEDVAR flag has to be */
1814 /* remembered in copy->flags, too */
1815 copy->flags |= SAVEDVAR;
1819 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
1826 last_pei_boundary = sd.new;
1827 iptr->flags.bits |= INS_FLAG_CHECK;
1828 COUNT(count_check_null);
1829 COUNT(count_check_bound);
1830 COUNT(count_pcmd_mem);
1831 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
1838 last_pei_boundary = sd.new;
1839 iptr->flags.bits |= INS_FLAG_CHECK;
1840 COUNT(count_check_null);
1841 COUNT(count_check_bound);
1842 COUNT(count_pcmd_mem);
1843 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
1849 #ifdef ENABLE_VERIFIER
1852 if (IS_2_WORD_TYPE(curstack->type))
1853 goto throw_stack_category_error;
1864 last_pei_boundary = sd.new;
1865 IF_JIT( md_return_alloc(jd, curstack); )
1866 COUNT(count_pcmd_return);
1867 OP1_0(opcode - ICMD_IRETURN);
1868 superblockend = true;
1872 last_pei_boundary = sd.new;
1873 COUNT(count_check_null);
1876 superblockend = true;
1879 case ICMD_PUTSTATIC:
1880 last_pei_boundary = sd.new;
1881 COUNT(count_pcmd_mem);
1882 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1883 OP1_0(fmiref->parseddesc.fd->type);
1886 /* pop 1 push 0 branch */
1889 case ICMD_IFNONNULL:
1890 COUNT(count_pcmd_bra);
1891 OP1_BRANCH(TYPE_ADR);
1892 BRANCH(tbptr, copy);
1901 COUNT(count_pcmd_bra);
1902 /* iptr->sx.val.i is set implicitly in parse by
1903 clearing the memory or from IF_ICMPxx
1906 OP1_BRANCH(TYPE_INT);
1907 /* iptr->sx.val.i = 0; */
1908 BRANCH(tbptr, copy);
1911 /* pop 0 push 0 branch */
1914 COUNT(count_pcmd_bra);
1916 BRANCH(tbptr, copy);
1917 superblockend = true;
1920 /* pop 1 push 0 table branch */
1922 case ICMD_TABLESWITCH:
1923 COUNT(count_pcmd_table);
1924 OP1_BRANCH(TYPE_INT);
1926 table = iptr->dst.table;
1927 BRANCH_TARGET(*table, tbptr, copy);
1930 i = iptr->sx.s23.s3.tablehigh
1931 - iptr->sx.s23.s2.tablelow + 1;
1934 BRANCH_TARGET(*table, tbptr, copy);
1937 superblockend = true;
1940 /* pop 1 push 0 table branch */
1942 case ICMD_LOOKUPSWITCH:
1943 COUNT(count_pcmd_table);
1944 OP1_BRANCH(TYPE_INT);
1946 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
1948 lookup = iptr->dst.lookup;
1950 i = iptr->sx.s23.s2.lookupcount;
1953 BRANCH_TARGET(lookup->target, tbptr, copy);
1956 superblockend = true;
1959 case ICMD_MONITORENTER:
1960 case ICMD_MONITOREXIT:
1961 last_pei_boundary = sd.new;
1962 COUNT(count_check_null);
1966 /* pop 2 push 0 branch */
1968 case ICMD_IF_ICMPEQ:
1969 case ICMD_IF_ICMPNE:
1970 case ICMD_IF_ICMPLT:
1971 case ICMD_IF_ICMPGE:
1972 case ICMD_IF_ICMPGT:
1973 case ICMD_IF_ICMPLE:
1974 COUNT(count_pcmd_bra);
1975 OP2_BRANCH(TYPE_INT, TYPE_INT);
1976 BRANCH(tbptr, copy);
1979 case ICMD_IF_ACMPEQ:
1980 case ICMD_IF_ACMPNE:
1981 COUNT(count_pcmd_bra);
1982 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
1983 BRANCH(tbptr, copy);
1989 last_pei_boundary = sd.new;
1990 COUNT(count_check_null);
1991 COUNT(count_pcmd_mem);
1992 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
1993 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
1998 if (!IS_2_WORD_TYPE(curstack->type)) {
2000 #ifdef ENABLE_VERIFIER
2003 if (IS_2_WORD_TYPE(curstack->prev->type))
2004 goto throw_stack_category_error;
2007 OP2_0_ANY_ANY; /* pop two slots */
2010 iptr->opc = ICMD_POP;
2011 OP1_0_ANY; /* pop one (two-word) slot */
2015 /* pop 0 push 1 dup */
2018 #ifdef ENABLE_VERIFIER
2021 if (IS_2_WORD_TYPE(curstack->type))
2022 goto throw_stack_category_error;
2025 COUNT(count_dup_instruction);
2030 MOVE_COPY_UP(ICMD_COPY, src1);
2031 last_dup_boundary = sd.new - 1;
2036 if (IS_2_WORD_TYPE(curstack->type)) {
2038 iptr->opc = ICMD_DUP;
2043 /* ..., ????, cat1 */
2044 #ifdef ENABLE_VERIFIER
2046 if (IS_2_WORD_TYPE(curstack->prev->type))
2047 goto throw_stack_category_error;
2050 src1 = curstack->prev;
2053 MOVE_COPY_UP(ICMD_COPY, src1); iptr++; len--;
2054 MOVE_COPY_UP(ICMD_COPY, src2);
2056 last_dup_boundary = sd.new;
2060 /* pop 2 push 3 dup */
2063 #ifdef ENABLE_VERIFIER
2066 if (IS_2_WORD_TYPE(curstack->type) ||
2067 IS_2_WORD_TYPE(curstack->prev->type))
2068 goto throw_stack_category_error;
2073 src1 = curstack->prev;
2078 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2080 MOVE_COPY_UP(ICMD_MOVE, src1); iptr++; len--;
2081 MOVE_COPY_UP(ICMD_MOVE, src2); iptr++; len--;
2083 COPY_DOWN(curstack, dst1);
2085 last_dup_boundary = sd.new;
2090 if (IS_2_WORD_TYPE(curstack->type)) {
2091 /* ..., ????, cat2 */
2092 #ifdef ENABLE_VERIFIER
2094 if (IS_2_WORD_TYPE(curstack->prev->type))
2095 goto throw_stack_category_error;
2098 iptr->opc = ICMD_DUP_X1;
2102 /* ..., ????, cat1 */
2103 #ifdef ENABLE_VERIFIER
2106 if (IS_2_WORD_TYPE(curstack->prev->type)
2107 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2108 goto throw_stack_category_error;
2113 src1 = curstack->prev->prev;
2114 src2 = curstack->prev;
2116 POPANY; POPANY; POPANY;
2119 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
2120 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
2122 MOVE_COPY_UP(ICMD_MOVE, src1); iptr++; len--;
2123 MOVE_COPY_UP(ICMD_MOVE, src2); iptr++; len--;
2124 MOVE_COPY_UP(ICMD_MOVE, src3); iptr++; len--;
2126 COPY_DOWN(curstack, dst2); iptr++; len--;
2127 COPY_DOWN(curstack->prev, dst1);
2129 last_dup_boundary = sd.new;
2133 /* pop 3 push 4 dup */
2137 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2138 /* ..., cat2, ???? */
2139 #ifdef ENABLE_VERIFIER
2141 if (IS_2_WORD_TYPE(curstack->type))
2142 goto throw_stack_category_error;
2145 iptr->opc = ICMD_DUP_X1;
2149 /* ..., cat1, ???? */
2150 #ifdef ENABLE_VERIFIER
2153 if (IS_2_WORD_TYPE(curstack->type)
2154 || IS_2_WORD_TYPE(curstack->prev->prev->type))
2155 goto throw_stack_category_error;
2159 src1 = curstack->prev->prev;
2160 src2 = curstack->prev;
2162 POPANY; POPANY; POPANY;
2165 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2167 MOVE_COPY_UP(ICMD_MOVE, src1); iptr++; len--;
2168 MOVE_COPY_UP(ICMD_MOVE, src2); iptr++; len--;
2169 MOVE_COPY_UP(ICMD_MOVE, src3); iptr++; len--;
2171 COPY_DOWN(curstack, dst1);
2173 last_dup_boundary = sd.new;
2179 if (IS_2_WORD_TYPE(curstack->type)) {
2180 /* ..., ????, cat2 */
2181 if (IS_2_WORD_TYPE(curstack->prev->type)) {
2182 /* ..., cat2, cat2 */
2183 iptr->opc = ICMD_DUP_X1;
2187 /* ..., cat1, cat2 */
2188 #ifdef ENABLE_VERIFIER
2191 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
2192 goto throw_stack_category_error;
2195 iptr->opc = ICMD_DUP_X2;
2201 /* ..., ????, ????, cat1 */
2203 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
2204 /* ..., cat2, ????, cat1 */
2205 #ifdef ENABLE_VERIFIER
2207 if (IS_2_WORD_TYPE(curstack->prev->type))
2208 goto throw_stack_category_error;
2211 iptr->opc = ICMD_DUP2_X1;
2215 /* ..., cat1, ????, cat1 */
2216 #ifdef ENABLE_VERIFIER
2219 if (IS_2_WORD_TYPE(curstack->prev->type)
2220 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
2221 goto throw_stack_category_error;
2225 src1 = curstack->prev->prev->prev;
2226 src2 = curstack->prev->prev;
2227 src3 = curstack->prev;
2229 POPANY; POPANY; POPANY; POPANY;
2232 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
2233 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
2235 MOVE_COPY_UP(ICMD_MOVE, src1); iptr++; len--;
2236 MOVE_COPY_UP(ICMD_MOVE, src2); iptr++; len--;
2237 MOVE_COPY_UP(ICMD_MOVE, src3); iptr++; len--;
2238 MOVE_COPY_UP(ICMD_MOVE, src4); iptr++; len--;
2240 COPY_DOWN(curstack, dst2); iptr++; len--;
2241 COPY_DOWN(curstack->prev, dst1);
2243 last_dup_boundary = sd.new;
2247 /* pop 2 push 2 swap */
2250 #ifdef ENABLE_VERIFIER
2253 if (IS_2_WORD_TYPE(curstack->type)
2254 || IS_2_WORD_TYPE(curstack->prev->type))
2255 goto throw_stack_category_error;
2259 src1 = curstack->prev;
2264 MOVE_COPY_UP(ICMD_MOVE, src2); iptr++; len--;
2265 MOVE_COPY_UP(ICMD_MOVE, src1);
2267 last_dup_boundary = sd.new;
2274 last_pei_boundary = sd.new;
2275 #if !SUPPORT_DIVISION
2276 bte = iptr->sx.s23.s3.bte;
2279 if (md->memuse > rd->memuse)
2280 rd->memuse = md->memuse;
2281 if (md->argintreguse > rd->argintreguse)
2282 rd->argintreguse = md->argintreguse;
2284 /* make all stack variables saved */
2288 sd.var[copy->varnum].flags |= SAVEDVAR;
2289 copy->flags |= SAVEDVAR;
2294 #endif /* !SUPPORT_DIVISION */
2305 COUNT(count_pcmd_op);
2306 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
2311 last_pei_boundary = sd.new;
2312 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
2313 bte = iptr->sx.s23.s3.bte;
2316 if (md->memuse > rd->memuse)
2317 rd->memuse = md->memuse;
2318 if (md->argintreguse > rd->argintreguse)
2319 rd->argintreguse = md->argintreguse;
2320 /* XXX non-leaf method? */
2322 /* make all stack variables saved */
2326 sd.var[copy->varnum].flags |= SAVEDVAR;
2327 copy->flags |= SAVEDVAR;
2332 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
2337 #if SUPPORT_LONG_LOGICAL
2341 #endif /* SUPPORT_LONG_LOGICAL */
2342 COUNT(count_pcmd_op);
2343 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
2349 COUNT(count_pcmd_op);
2350 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
2358 COUNT(count_pcmd_op);
2359 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
2367 COUNT(count_pcmd_op);
2368 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
2372 COUNT(count_pcmd_op);
2373 #if SUPPORT_LONG_CMP_CONST
2374 if ((len == 0) || (iptr[1].sx.val.i != 0))
2377 switch (iptr[1].opc) {
2379 iptr->opc = ICMD_IF_LCMPEQ;
2381 iptr->dst.insindex = iptr[1].dst.insindex;
2382 iptr[1].opc = ICMD_NOP;
2384 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
2385 BRANCH(tbptr, copy);
2387 COUNT(count_pcmd_bra);
2390 iptr->opc = ICMD_IF_LCMPNE;
2391 goto icmd_lcmp_if_tail;
2393 iptr->opc = ICMD_IF_LCMPLT;
2394 goto icmd_lcmp_if_tail;
2396 iptr->opc = ICMD_IF_LCMPGT;
2397 goto icmd_lcmp_if_tail;
2399 iptr->opc = ICMD_IF_LCMPLE;
2400 goto icmd_lcmp_if_tail;
2402 iptr->opc = ICMD_IF_LCMPGE;
2403 goto icmd_lcmp_if_tail;
2409 #endif /* SUPPORT_LONG_CMP_CONST */
2410 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
2413 /* XXX why is this deactivated? */
2416 COUNT(count_pcmd_op);
2417 if ((len == 0) || (iptr[1].sx.val.i != 0))
2420 switch (iptr[1].opc) {
2422 iptr->opc = ICMD_IF_FCMPEQ;
2424 iptr->dst.insindex = iptr[1].dst.insindex;
2425 iptr[1].opc = ICMD_NOP;
2427 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2428 BRANCH(tbptr, copy);
2430 COUNT(count_pcmd_bra);
2433 iptr->opc = ICMD_IF_FCMPNE;
2434 goto icmd_if_fcmpl_tail;
2436 iptr->opc = ICMD_IF_FCMPL_LT;
2437 goto icmd_if_fcmpl_tail;
2439 iptr->opc = ICMD_IF_FCMPL_GT;
2440 goto icmd_if_fcmpl_tail;
2442 iptr->opc = ICMD_IF_FCMPL_LE;
2443 goto icmd_if_fcmpl_tail;
2445 iptr->opc = ICMD_IF_FCMPL_GE;
2446 goto icmd_if_fcmpl_tail;
2453 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2457 COUNT(count_pcmd_op);
2458 if ((len == 0) || (iptr[1].sx.val.i != 0))
2461 switch (iptr[1].opc) {
2463 iptr->opc = ICMD_IF_FCMPEQ;
2465 iptr->dst.insindex = iptr[1].dst.insindex;
2466 iptr[1].opc = ICMD_NOP;
2468 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
2469 BRANCH(tbptr, copy);
2471 COUNT(count_pcmd_bra);
2474 iptr->opc = ICMD_IF_FCMPNE;
2475 goto icmd_if_fcmpg_tail;
2477 iptr->opc = ICMD_IF_FCMPG_LT;
2478 goto icmd_if_fcmpg_tail;
2480 iptr->opc = ICMD_IF_FCMPG_GT;
2481 goto icmd_if_fcmpg_tail;
2483 iptr->opc = ICMD_IF_FCMPG_LE;
2484 goto icmd_if_fcmpg_tail;
2486 iptr->opc = ICMD_IF_FCMPG_GE;
2487 goto icmd_if_fcmpg_tail;
2494 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2498 COUNT(count_pcmd_op);
2499 if ((len == 0) || (iptr[1].sx.val.i != 0))
2502 switch (iptr[1].opc) {
2504 iptr->opc = ICMD_IF_DCMPEQ;
2506 iptr->dst.insindex = iptr[1].dst.insindex;
2507 iptr[1].opc = ICMD_NOP;
2509 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2510 BRANCH(tbptr, copy);
2512 COUNT(count_pcmd_bra);
2515 iptr->opc = ICMD_IF_DCMPNE;
2516 goto icmd_if_dcmpl_tail;
2518 iptr->opc = ICMD_IF_DCMPL_LT;
2519 goto icmd_if_dcmpl_tail;
2521 iptr->opc = ICMD_IF_DCMPL_GT;
2522 goto icmd_if_dcmpl_tail;
2524 iptr->opc = ICMD_IF_DCMPL_LE;
2525 goto icmd_if_dcmpl_tail;
2527 iptr->opc = ICMD_IF_DCMPL_GE;
2528 goto icmd_if_dcmpl_tail;
2535 OPTT2_1(TYPE_DBL, TYPE_INT);
2539 COUNT(count_pcmd_op);
2540 if ((len == 0) || (iptr[1].sx.val.i != 0))
2543 switch (iptr[1].opc) {
2545 iptr->opc = ICMD_IF_DCMPEQ;
2547 iptr->dst.insindex = iptr[1].dst.insindex;
2548 iptr[1].opc = ICMD_NOP;
2550 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
2551 BRANCH(tbptr, copy);
2553 COUNT(count_pcmd_bra);
2556 iptr->opc = ICMD_IF_DCMPNE;
2557 goto icmd_if_dcmpg_tail;
2559 iptr->opc = ICMD_IF_DCMPG_LT;
2560 goto icmd_if_dcmpg_tail;
2562 iptr->opc = ICMD_IF_DCMPG_GT;
2563 goto icmd_if_dcmpg_tail;
2565 iptr->opc = ICMD_IF_DCMPG_LE;
2566 goto icmd_if_dcmpg_tail;
2568 iptr->opc = ICMD_IF_DCMPG_GE;
2569 goto icmd_if_dcmpg_tail;
2576 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2581 COUNT(count_pcmd_op);
2582 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
2587 COUNT(count_pcmd_op);
2588 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
2597 case ICMD_INT2SHORT:
2598 COUNT(count_pcmd_op);
2599 OP1_1(TYPE_INT, TYPE_INT);
2602 COUNT(count_pcmd_op);
2603 OP1_1(TYPE_LNG, TYPE_LNG);
2606 COUNT(count_pcmd_op);
2607 OP1_1(TYPE_FLT, TYPE_FLT);
2610 COUNT(count_pcmd_op);
2611 OP1_1(TYPE_DBL, TYPE_DBL);
2615 COUNT(count_pcmd_op);
2616 OP1_1(TYPE_INT, TYPE_LNG);
2619 COUNT(count_pcmd_op);
2620 OP1_1(TYPE_INT, TYPE_FLT);
2623 COUNT(count_pcmd_op);
2624 OP1_1(TYPE_INT, TYPE_DBL);
2627 COUNT(count_pcmd_op);
2628 OP1_1(TYPE_LNG, TYPE_INT);
2631 COUNT(count_pcmd_op);
2632 OP1_1(TYPE_LNG, TYPE_FLT);
2635 COUNT(count_pcmd_op);
2636 OP1_1(TYPE_LNG, TYPE_DBL);
2639 COUNT(count_pcmd_op);
2640 OP1_1(TYPE_FLT, TYPE_INT);
2643 COUNT(count_pcmd_op);
2644 OP1_1(TYPE_FLT, TYPE_LNG);
2647 COUNT(count_pcmd_op);
2648 OP1_1(TYPE_FLT, TYPE_DBL);
2651 COUNT(count_pcmd_op);
2652 OP1_1(TYPE_DBL, TYPE_INT);
2655 COUNT(count_pcmd_op);
2656 OP1_1(TYPE_DBL, TYPE_LNG);
2659 COUNT(count_pcmd_op);
2660 OP1_1(TYPE_DBL, TYPE_FLT);
2663 case ICMD_CHECKCAST:
2664 last_pei_boundary = sd.new;
2665 if (iptr->flags.bits & INS_FLAG_ARRAY) {
2666 /* array type cast-check */
2668 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
2671 if (md->memuse > rd->memuse)
2672 rd->memuse = md->memuse;
2673 if (md->argintreguse > rd->argintreguse)
2674 rd->argintreguse = md->argintreguse;
2676 /* make all stack variables saved */
2680 sd.var[copy->varnum].flags |= SAVEDVAR;
2681 copy->flags |= SAVEDVAR;
2685 OP1_1(TYPE_ADR, TYPE_ADR);
2688 case ICMD_INSTANCEOF:
2689 case ICMD_ARRAYLENGTH:
2690 last_pei_boundary = sd.new;
2691 OP1_1(TYPE_ADR, TYPE_INT);
2695 case ICMD_ANEWARRAY:
2696 last_pei_boundary = sd.new;
2697 OP1_1(TYPE_INT, TYPE_ADR);
2701 last_pei_boundary = sd.new;
2702 COUNT(count_check_null);
2703 COUNT(count_pcmd_mem);
2704 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2705 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
2710 case ICMD_GETSTATIC:
2711 last_pei_boundary = sd.new;
2712 COUNT(count_pcmd_mem);
2713 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
2714 OP0_1(fmiref->parseddesc.fd->type);
2718 last_pei_boundary = sd.new;
2725 BRANCH_TARGET(iptr->sx.s23.s3.jsrtarget, tbptr, copy);
2727 tbptr->type = BBTYPE_SBR;
2729 /* We need to check for overflow right here because
2730 * the pushed value is poped afterwards */
2733 /* calculate stack after return */
2738 /* pop many push any */
2742 bte = iptr->sx.s23.s3.bte;
2746 case ICMD_INVOKESTATIC:
2747 case ICMD_INVOKESPECIAL:
2748 case ICMD_INVOKEVIRTUAL:
2749 case ICMD_INVOKEINTERFACE:
2750 COUNT(count_pcmd_met);
2752 /* Check for functions to replace with builtin
2755 if (builtintable_replace_function(iptr))
2758 INSTRUCTION_GET_METHODDESC(iptr, md);
2759 /* XXX resurrect this COUNT? */
2760 /* if (lm->flags & ACC_STATIC) */
2761 /* {COUNT(count_check_null);} */
2765 last_pei_boundary = sd.new;
2769 if (md->memuse > rd->memuse)
2770 rd->memuse = md->memuse;
2771 if (md->argintreguse > rd->argintreguse)
2772 rd->argintreguse = md->argintreguse;
2773 if (md->argfltreguse > rd->argfltreguse)
2774 rd->argfltreguse = md->argfltreguse;
2778 /* XXX optimize for <= 2 args */
2779 /* XXX not for ICMD_BUILTIN */
2780 iptr->s1.argcount = stackdepth;
2781 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
2784 for (i-- ; i >= 0; i--) {
2785 iptr->sx.s23.s2.args[i] = copy->varnum;
2787 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
2788 /* -> won't help anyway */
2789 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
2791 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2792 /* If we pass float arguments in integer argument registers, we
2793 * are not allowed to precolor them here. Floats have to be moved
2794 * to this regs explicitly in codegen().
2795 * Only arguments that are passed by stack anyway can be precolored
2796 * (michi 2005/07/24) */
2797 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
2798 (!IS_FLT_DBL_TYPE(copy->type)
2799 || md->params[i].inmemory)) {
2801 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
2806 #if defined(ENABLE_INTRP)
2809 if (md->params[i].inmemory) {
2810 sd.var[copy->varnum].regoff =
2811 md->params[i].regoff;
2812 sd.var[copy->varnum].flags |=
2816 if (IS_FLT_DBL_TYPE(copy->type)) {
2817 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
2818 assert(0); /* XXX is this assert ok? */
2820 sd.var[copy->varnum].regoff =
2821 rd->argfltregs[md->params[i].regoff];
2822 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
2825 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
2826 if (IS_2_WORD_TYPE(copy->type))
2827 sd.var[copy->varnum].regoff =
2828 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
2829 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
2832 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
2833 sd.var[copy->varnum].regoff =
2834 rd->argintregs[md->params[i].regoff];
2837 #if defined(ENABLE_INTRP)
2838 } /* end if (!opt_intrp) */
2845 /* deal with live-through stack slots "under" the */
2847 /* XXX not for ICMD_BUILTIN */
2852 iptr->sx.s23.s2.args[i++] = copy->varnum;
2853 sd.var[copy->varnum].flags |= SAVEDVAR;
2857 /* pop the arguments */
2866 /* push the return value */
2868 if (md->returntype.type != TYPE_VOID) {
2869 GET_NEW_INDEX(sd, new_index);
2870 DST(md->returntype.type, new_index);
2875 case ICMD_INLINE_START:
2876 case ICMD_INLINE_END:
2881 case ICMD_MULTIANEWARRAY:
2882 last_pei_boundary = sd.new;
2883 if (rd->argintreguse < 3)
2884 rd->argintreguse = 3;
2886 i = iptr->s1.argcount;
2890 iptr->sx.s23.s2.args = DMNEW(s4, i);
2892 #if defined(SPECIALMEMUSE)
2893 # if defined(__DARWIN__)
2894 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
2895 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
2897 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
2898 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
2901 # if defined(__I386__)
2902 if (rd->memuse < i + 3)
2903 rd->memuse = i + 3; /* n integer args spilled on stack */
2904 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2905 if (rd->memuse < i + 2)
2906 rd->memuse = i + 2; /* 4*4 bytes callee save space */
2909 rd->memuse = i; /* n integer args spilled on stack */
2910 # endif /* defined(__I386__) */
2914 /* check INT type here? Currently typecheck does this. */
2915 iptr->sx.s23.s2.args[i] = copy->varnum;
2916 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
2917 && (!IS_OUTVAR(copy))
2918 && (!IS_LOCALVAR(copy)) ) {
2919 copy->varkind = ARGVAR;
2920 sd.var[copy->varnum].flags |=
2921 INMEMORY & PREALLOC;
2922 #if defined(SPECIALMEMUSE)
2923 # if defined(__DARWIN__)
2924 sd.var[copy->varnum].regoff = i +
2925 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
2927 sd.var[copy->varnum].regoff = i +
2928 LA_SIZE_IN_POINTERS + 3;
2931 # if defined(__I386__)
2932 sd.var[copy->varnum].regoff = i + 3;
2933 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
2934 sd.var[copy->varnum].regoff = i + 2;
2936 sd.var[copy->varnum].regoff = i;
2937 # endif /* defined(__I386__) */
2938 #endif /* defined(SPECIALMEMUSE) */
2943 sd.var[copy->varnum].flags |= SAVEDVAR;
2947 i = iptr->s1.argcount;
2952 GET_NEW_INDEX(sd, new_index);
2953 DST(TYPE_ADR, new_index);
2959 new_internalerror("Unknown ICMD %d", opcode);
2965 } /* while instructions */
2967 /* set out-stack of block */
2969 sd.bptr->outstack = curstack;
2970 sd.bptr->outdepth = stackdepth;
2971 sd.bptr->outvars = DMNEW(s4, stackdepth);
2972 for (i = stackdepth, copy = curstack; i--; copy = copy->prev)
2973 sd.bptr->outvars[i] = copy->varnum;
2975 /* stack slots at basic block end become interfaces */
2978 for (copy = curstack; copy; i--, copy = copy->prev) {
2981 /* with the new vars rd->interfaces will be removed */
2982 /* and all in and outvars have to be STACKVARS! */
2983 /* in the moment i.e. SWAP with in and out vars can */
2984 /* create an unresolvable conflict */
2986 v = sd.var + copy->varnum;
2988 SET_OUTVAR(sd, copy);
2990 if (jd->interface_map[i*5 + copy->type].flags == UNUSED) {
2991 /* no interface var until now for this depth and */
2993 jd->interface_map[i*5 + copy->type].flags = v->flags;
2996 jd->interface_map[i*5 + copy->type].flags |= v->flags;
3000 /* check if interface slots at basic block begin must be saved */
3002 for (i=0; i<sd.bptr->indepth; ++i) {
3003 varinfo *v = sd.var + sd.bptr->invars[i];
3005 if (jd->interface_map[i*5 + v->type].flags == UNUSED) {
3006 /* no interface var until now for this depth and */
3008 jd->interface_map[i*5 + v->type].flags = v->flags;
3011 jd->interface_map[i*5 + v->type].flags |= v->flags;
3016 #if defined(STACK_VERBOSE)
3017 printf("OUTVARS\n");
3018 for( copy = sd.bptr->outstack; copy; copy = copy->prev ) {
3019 printf("%2d(%d", copy->varnum, copy->type);
3020 if (IS_OUTVAR(copy))
3022 if (IS_PREALLOC(copy))
3030 superblockend = true;
3033 } /* while blocks */
3034 } while (repeat && !deadcode);
3036 /* gather statistics *****************************************************/
3038 #if defined(ENABLE_STATISTICS)
3040 if (jd->new_basicblockcount > count_max_basic_blocks)
3041 count_max_basic_blocks = jd->new_basicblockcount;
3042 count_basic_blocks += jd->new_basicblockcount;
3043 if (jd->new_instructioncount > count_max_javainstr)
3044 count_max_javainstr = jd->new_instructioncount;
3045 count_javainstr += jd->new_instructioncount;
3046 if (jd->new_stackcount > count_upper_bound_new_stack)
3047 count_upper_bound_new_stack = jd->new_stackcount;
3048 if ((sd.new - jd->new_stack) > count_max_new_stack)
3049 count_max_new_stack = (sd.new - jd->new_stack);
3051 b_count = jd->new_basicblockcount;
3052 sd.bptr = jd->new_basicblocks;
3053 while (--b_count >= 0) {
3054 if (sd.bptr->flags > BBREACHED) {
3055 if (sd.bptr->indepth >= 10)
3056 count_block_stack[10]++;
3058 count_block_stack[sd.bptr->indepth]++;
3059 len = sd.bptr->icount;
3061 count_block_size_distribution[len]++;
3063 count_block_size_distribution[10]++;
3065 count_block_size_distribution[11]++;
3067 count_block_size_distribution[12]++;
3069 count_block_size_distribution[13]++;
3071 count_block_size_distribution[14]++;
3073 count_block_size_distribution[15]++;
3075 count_block_size_distribution[16]++;
3077 count_block_size_distribution[17]++;
3082 if (iteration_count == 1)
3083 count_analyse_iterations[0]++;
3084 else if (iteration_count == 2)
3085 count_analyse_iterations[1]++;
3086 else if (iteration_count == 3)
3087 count_analyse_iterations[2]++;
3088 else if (iteration_count == 4)
3089 count_analyse_iterations[3]++;
3091 count_analyse_iterations[4]++;
3093 if (jd->new_basicblockcount <= 5)
3094 count_method_bb_distribution[0]++;
3095 else if (jd->new_basicblockcount <= 10)
3096 count_method_bb_distribution[1]++;
3097 else if (jd->new_basicblockcount <= 15)
3098 count_method_bb_distribution[2]++;
3099 else if (jd->new_basicblockcount <= 20)
3100 count_method_bb_distribution[3]++;
3101 else if (jd->new_basicblockcount <= 30)
3102 count_method_bb_distribution[4]++;
3103 else if (jd->new_basicblockcount <= 40)
3104 count_method_bb_distribution[5]++;
3105 else if (jd->new_basicblockcount <= 50)
3106 count_method_bb_distribution[6]++;
3107 else if (jd->new_basicblockcount <= 75)
3108 count_method_bb_distribution[7]++;
3110 count_method_bb_distribution[8]++;
3112 #endif /* defined(ENABLE_STATISTICS) */
3114 /* everything's ok *******************************************************/
3118 /* goto labels for throwing verifier exceptions **************************/
3120 #if defined(ENABLE_VERIFIER)
3122 throw_stack_underflow:
3123 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
3126 throw_stack_overflow:
3127 exceptions_throw_verifyerror(m, "Stack size too large");
3130 throw_stack_depth_error:
3131 exceptions_throw_verifyerror(m,"Stack depth mismatch");
3134 throw_stack_type_error:
3135 exceptions_throw_verifyerror_for_stack(m, expectedtype);
3138 throw_stack_category_error:
3139 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
3147 * These are local overrides for various environment variables in Emacs.
3148 * Please do not remove this and leave it at the end of the file, where
3149 * Emacs will automagically detect them.
3150 * ---------------------------------------------------------------------
3153 * indent-tabs-mode: t
3157 * vim:noexpandtab:sw=4:ts=4: