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 5657 2006-10-03 21:19:05Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/show.h"
67 #if defined(ENABLE_DISASSEMBLER)
68 # include "vm/jit/disass.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/stack.h"
74 #if defined(ENABLE_SSA)
75 # include "vm/jit/optimizing/lsra.h"
76 # include "vm/jit/optimizing/ssa.h"
77 #elif defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
81 /*#define STACK_VERBOSE*/
84 /* macro for saving #ifdefs ***************************************************/
86 #if defined(ENABLE_INTRP)
87 #define IF_INTRP(x) if (opt_intrp) { x }
88 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
91 #define IF_NO_INTRP(x) { x }
94 #if defined(ENABLE_INTRP)
95 #if defined(ENABLE_JIT)
96 #define IF_JIT(x) if (!opt_intrp) { x }
100 #else /* !defined(ENABLE_INTRP) */
101 #define IF_JIT(x) { x }
102 #endif /* defined(ENABLE_INTRP) */
104 #if defined(ENABLE_STATISTICS)
105 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
108 if (stackdepth >= 10) \
109 count_store_depth[10]++; \
111 count_store_depth[stackdepth]++; \
114 #else /* !defined(ENABLE_STATISTICS) */
115 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
118 /* stackdata_t *****************************************************************
120 This struct holds internal data during stack analysis.
122 *******************************************************************************/
124 typedef struct stackdata_t stackdata_t;
127 basicblock *bptr; /* the current basic block being analysed */
128 stackptr new; /* next free stackelement */
129 s4 vartop; /* next free variable index */
130 s4 localcount; /* number of locals (at the start of var) */
131 s4 varcount; /* total number of variables allocated */
132 varinfo *var; /* variable array (same as jd->var) */
133 methodinfo *m; /* the method being analysed */
134 jitdata *jd; /* current jitdata */
135 basicblock *last_real_block; /* the last block before the empty one */
136 bool repeat; /* if true, iterate the analysis again */
137 exceptiontable **handlers; /* exception handlers for the current block */
138 exceptiontable *extableend; /* points to the last exception entry */
139 stackelement exstack; /* instack for exception handlers */
143 /* macros for allocating/releasing variable indices *****************/
145 #define GET_NEW_INDEX(sd, new_varindex) \
147 assert((sd).vartop < (sd).varcount); \
148 (new_varindex) = ((sd).vartop)++; \
151 /* Not implemented now - could be used to reuse varindices. */
152 /* Pay attention to not release a localvar once implementing it! */
153 #define RELEASE_INDEX(sd, varindex)
155 #define GET_NEW_VAR(sd, new_varindex, newtype) \
157 GET_NEW_INDEX((sd), (new_varindex)); \
158 (sd).var[new_index].type = (newtype); \
162 /* macros for querying variable properties **************************/
164 #define IS_INOUT(sp) \
165 (sd.var[(sp)->varnum].flags & INOUT)
167 #define IS_PREALLOC(sp) \
168 (sd.var[(sp)->varnum].flags & PREALLOC)
170 #define IS_TEMPVAR(sp) \
171 ( ((sp)->varnum >= sd.localcount) \
172 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
175 #define IS_LOCALVAR_SD(sd, sp) \
176 ((sp)->varnum < (sd).localcount)
178 #define IS_LOCALVAR(sp) \
179 IS_LOCALVAR_SD(sd, (sp))
182 /* macros for setting variable properties ****************************/
184 #define SET_TEMPVAR(sp) \
186 if (IS_LOCALVAR((sp))) { \
187 GET_NEW_VAR(sd, new_index, (sp)->type); \
188 sd.var[new_index].flags = (sp)->flags; \
189 (sp)->varnum = new_index; \
190 (sp)->varkind = TEMPVAR; \
192 (sp)->creator->dst.varindex = new_index; \
194 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
197 #define SET_PREALLOC(sp) \
199 assert(!IS_LOCALVAR((sp))); \
200 sd.var[(sp)->varnum].flags |= PREALLOC; \
204 /* macros for source operands ***************************************/
207 (iptr->s1.varindex = -1)
209 #define USE_S1(type1) \
212 CHECK_BASIC_TYPE(type1, curstack->type); \
213 iptr->s1.varindex = curstack->varnum; \
219 iptr->s1.varindex = curstack->varnum; \
222 #define USE_S1_S2(type1, type2) \
225 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
226 CHECK_BASIC_TYPE(type2, curstack->type); \
227 iptr->sx.s23.s2.varindex = curstack->varnum; \
228 iptr->s1.varindex = curstack->prev->varnum; \
231 #define USE_S1_S2_ANY_ANY \
234 iptr->sx.s23.s2.varindex = curstack->varnum; \
235 iptr->s1.varindex = curstack->prev->varnum; \
238 #define USE_S1_S2_S3(type1, type2, type3) \
241 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
242 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
243 CHECK_BASIC_TYPE(type3, curstack->type); \
244 iptr->sx.s23.s3.varindex = curstack->varnum; \
245 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
246 iptr->s1.varindex = curstack->prev->prev->varnum; \
249 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
252 if (curstack->varkind == UNDEFVAR) \
253 curstack->varkind = TEMPVAR; \
254 curstack = curstack->prev; \
257 #define POP_S1(type1) \
260 if (curstack->varkind == UNDEFVAR) \
261 curstack->varkind = TEMPVAR; \
262 curstack = curstack->prev; \
268 if (curstack->varkind == UNDEFVAR) \
269 curstack->varkind = TEMPVAR; \
270 curstack = curstack->prev; \
273 #define POP_S1_S2(type1, type2) \
275 USE_S1_S2(type1, type2); \
276 if (curstack->varkind == UNDEFVAR) \
277 curstack->varkind = TEMPVAR; \
278 if (curstack->prev->varkind == UNDEFVAR) \
279 curstack->prev->varkind = TEMPVAR; \
280 curstack = curstack->prev->prev; \
283 #define POP_S1_S2_ANY_ANY \
286 if (curstack->varkind == UNDEFVAR) \
287 curstack->varkind = TEMPVAR; \
288 if (curstack->prev->varkind == UNDEFVAR) \
289 curstack->prev->varkind = TEMPVAR; \
290 curstack = curstack->prev->prev; \
293 #define POP_S1_S2_S3(type1, type2, type3) \
295 USE_S1_S2_S3(type1, type2, type3); \
296 if (curstack->varkind == UNDEFVAR) \
297 curstack->varkind = TEMPVAR; \
298 if (curstack->prev->varkind == UNDEFVAR) \
299 curstack->prev->varkind = TEMPVAR; \
300 if (curstack->prev->prev->varkind == UNDEFVAR) \
301 curstack->prev->prev->varkind = TEMPVAR; \
302 curstack = curstack->prev->prev->prev; \
309 /* macros for setting the destination operand ***********************/
312 (iptr->dst.varindex = -1)
314 #define DST(typed, index) \
316 NEWSTACKn((typed),(index)); \
317 curstack->creator = iptr; \
318 iptr->dst.varindex = (index); \
321 #define DST_LOCALVAR(typed, index) \
323 NEWSTACK((typed), LOCALVAR, (index)); \
324 curstack->creator = iptr; \
325 iptr->dst.varindex = (index); \
329 /* macro for propagating constant values ****************************/
331 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
333 (sd).var[(dindex)].type = (sd).var[(sindex)].type; \
334 (sd).var[(dindex)].vv = (sd).var[(sindex)].vv; \
338 /* stack modelling macros *******************************************/
340 #define OP0_1(typed) \
343 GET_NEW_VAR(sd, new_index, (typed)); \
344 DST((typed), new_index); \
355 #define OP1_BRANCH(type1) \
361 #define OP1_1(type1, typed) \
364 GET_NEW_VAR(sd, new_index, (typed)); \
365 DST(typed, new_index); \
368 #define OP2_1(type1, type2, typed) \
370 POP_S1_S2(type1, type2); \
371 GET_NEW_VAR(sd, new_index, (typed)); \
372 DST(typed, new_index); \
387 #define OP1_0(type1) \
394 #define OP2_0(type1, type2) \
396 POP_S1_S2(type1, type2); \
401 #define OP2_BRANCH(type1, type2) \
403 POP_S1_S2(type1, type2); \
407 #define OP2_0_ANY_ANY \
414 #define OP3_0(type1, type2, type3) \
416 POP_S1_S2_S3(type1, type2, type3); \
421 #define LOAD(type1, index) \
423 DST_LOCALVAR(type1, index); \
427 #define STORE(type1, index) \
434 /* macros for DUP elimination ***************************************/
436 /* XXX replace NEW_VAR with NEW_INDEX */
437 #define DUP_SLOT(sp) \
439 GET_NEW_VAR(sd, new_index, (sp)->type); \
440 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
441 NEWSTACK((sp)->type, TEMPVAR, new_index); \
444 /* does not check input stackdepth */
445 #define MOVE_UP(sp) \
447 iptr->opc = ICMD_MOVE; \
448 iptr->s1.varindex = (sp)->varnum; \
450 curstack->creator = iptr; \
451 iptr->dst.varindex = curstack->varnum; \
455 /* does not check input stackdepth */
456 #define COPY_UP(sp) \
459 iptr->opc = ICMD_COPY; \
460 iptr->s1.varindex = (sp)->varnum; \
462 curstack->creator = iptr; \
463 iptr->dst.varindex = curstack->varnum; \
467 #define COPY_DOWN(s, d) \
470 iptr->opc = ICMD_COPY; \
471 iptr->s1.varindex = (s)->varnum; \
472 iptr->dst.varindex = (d)->varnum; \
473 (d)->creator = iptr; \
476 #define MOVE_TO_TEMP(sp) \
478 GET_NEW_INDEX(sd, new_index); \
479 iptr->opc = ICMD_MOVE; \
480 iptr->s1.varindex = (sp)->varnum; \
481 iptr->dst.varindex = new_index; \
482 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
483 (sp)->varnum = new_index; \
484 (sp)->varkind = TEMPVAR; \
487 /* macros for branching / reaching basic blocks *********************/
489 #define BRANCH_TARGET(bt, tempbptr) \
491 tempbptr = BLOCK_OF((bt).insindex); \
492 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
494 if (tempbptr == NULL) \
496 (bt).block = tempbptr; \
499 #define BRANCH(tempbptr) \
500 BRANCH_TARGET(iptr->dst, tempbptr)
503 /* forward declarations *******************************************************/
505 static void stack_create_invars(stackdata_t *sd, basicblock *b,
506 stackptr curstack, int stackdepth);
507 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
509 #if defined(STACK_VERBOSE)
510 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
511 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
512 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
513 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
514 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
518 /* stack_init ******************************************************************
520 Initialized the stack analysis subsystem (called by jit_init).
522 *******************************************************************************/
524 bool stack_init(void)
530 /* stack_grow_variable_array ***************************************************
532 Grow the variable array so the given number of additional variables fits in.
535 sd...........stack analysis data
536 num..........number of additional variables
538 *******************************************************************************/
540 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
549 /* XXX avoid too many reallocations */
550 newcount = sd->varcount + num;
552 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
553 sd->varcount = newcount;
554 sd->jd->var = sd->var;
555 sd->jd->varcount = newcount;
559 /* stack_append_block **********************************************************
561 Append the given block after the last real block of the method (before
562 the pseudo-block at the end).
565 sd...........stack analysis data
566 b............the block to append
568 *******************************************************************************/
570 static void stack_append_block(stackdata_t *sd, basicblock *b)
572 #if defined(STACK_VERBOSE)
573 printf("APPENDING BLOCK L%0d\n", b->nr);
576 b->next = sd->last_real_block->next;
577 sd->last_real_block->next = b;
578 sd->last_real_block = b;
579 sd->jd->basicblockcount++;
583 /* stack_clone_block ***********************************************************
585 Create a copy of the given block and insert it at the end of the method.
587 CAUTION: This function does not copy the any variables or the instruction
588 list. It _does_, however, reserve space for the block's invars in the
592 sd...........stack analysis data
593 b............the block to clone
596 a pointer to the copy
598 *******************************************************************************/
600 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
604 clone = DNEW(basicblock);
607 clone->iinstr = NULL;
608 clone->inlocals = NULL;
609 clone->invars = NULL;
611 clone->original = (b->original) ? b->original : b;
612 clone->copied_to = clone->original->copied_to;
613 clone->original->copied_to = clone;
614 clone->nr = sd->m->c_block_nr++;
616 clone->flags = BBREACHED;
618 stack_append_block(sd, clone);
620 /* allocate space for the invars of the clone */
622 stack_grow_variable_array(sd, b->indepth);
624 #if defined(STACK_VERBOSE)
625 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
632 /* stack_create_invars *********************************************************
634 Create the invars for the given basic block. Also make a copy of the locals.
637 sd...........stack analysis data
638 b............block to create the invars for
639 curstack.....current stack top
640 stackdepth...current stack depth
642 This function creates STACKDEPTH invars and sets their types to the
643 types to the types of the corresponding slot in the current stack.
645 *******************************************************************************/
647 static void stack_create_invars(stackdata_t *sd, basicblock *b,
648 stackptr curstack, int stackdepth)
655 assert(sd->vartop + stackdepth <= sd->varcount);
657 b->indepth = stackdepth;
658 b->invars = DMNEW(s4, stackdepth);
660 /* allocate the variable indices */
661 index = (sd->vartop += stackdepth);
664 for (sp = curstack; i--; sp = sp->prev) {
665 b->invars[i] = --index;
669 v->vv = sd->var[sp->varnum].vv;
670 #if defined(STACK_VERBOSE) && 0
671 printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
675 /* copy the current state of the local variables */
676 /* (one extra local is needed by the verifier) */
678 v = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
680 for (i=0; i<sd->localcount; ++i)
685 /* stack_create_invars_from_outvars ********************************************
687 Create the invars for the given basic block. Also make a copy of the locals.
688 Types are propagated from the outvars of the current block.
691 sd...........stack analysis data
692 b............block to create the invars for
694 *******************************************************************************/
696 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
702 n = sd->bptr->outdepth;
703 assert(sd->vartop + n <= sd->varcount);
706 b->invars = DMNEW(s4, n);
709 dv = sd->var + sd->vartop;
711 /* allocate the invars */
713 for (i=0; i<n; ++i, ++dv) {
714 sv = sd->var + sd->bptr->outvars[i];
715 b->invars[i] = sd->vartop++;
722 /* copy the current state of the local variables */
723 /* (one extra local is needed by the verifier) */
725 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
727 for (i=0; i<sd->localcount; ++i)
732 /* stack_check_invars **********************************************************
734 Check the current stack against the invars of the given basic block.
735 Depth and types must match.
738 sd...........stack analysis data
739 b............block which invars to check against
740 curstack.....current stack top
741 stackdepth...current stack depth
745 NULL.........a VerifyError has been thrown
747 *******************************************************************************/
749 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
750 stackptr curstack, int stackdepth)
757 #if defined(STACK_VERBOSE)
758 printf("stack_check_invars(L%03d)\n", b->nr);
761 /* find original of b */
766 #if defined(STACK_VERBOSE)
767 printf("original is L%03d\n", orig->nr);
772 if (i != stackdepth) {
773 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
780 #if defined(STACK_VERBOSE)
781 printf("checking against ");
782 stack_verbose_show_block(sd, b); printf("\n");
786 for (i = orig->indepth; i--; sp = sp->prev) {
787 if (sd->var[b->invars[i]].type != sp->type) {
788 exceptions_throw_verifyerror_for_stack(sd->m,
789 sd->var[b->invars[i]].type);
793 if (sp->type == TYPE_RET) {
794 if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
802 for (i=0; i<sd->localcount; ++i) {
803 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
804 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
813 /* XXX mark mixed type variables void */
814 /* XXX cascading collapse? */
815 #if defined(STACK_VERBOSE)
816 printf("------> using L%03d\n", b->nr);
820 } while ((b = b->copied_to) != NULL);
822 b = stack_clone_block(sd, orig);
826 stack_create_invars(sd, b, curstack, stackdepth);
831 /* stack_check_invars_from_outvars *********************************************
833 Check the outvars of the current block against the invars of the given block.
834 Depth and types must match.
837 sd...........stack analysis data
838 b............block which invars to check against
842 NULL.........a VerifyError has been thrown
844 *******************************************************************************/
846 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
854 #if defined(STACK_VERBOSE)
855 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
858 /* find original of b */
863 #if defined(STACK_VERBOSE)
864 printf("original is L%03d\n", orig->nr);
868 n = sd->bptr->outdepth;
871 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
878 #if defined(STACK_VERBOSE)
879 printf("checking against ");
880 stack_verbose_show_block(sd, b); printf("\n");
884 dv = sd->var + b->invars[0];
886 for (i=0; i<n; ++i, ++dv) {
887 sv = sd->var + sd->bptr->outvars[i];
888 if (sv->type != dv->type) {
889 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
893 if (dv->type == TYPE_RET) {
894 if (sv->vv.retaddr != dv->vv.retaddr) {
903 for (i=0; i<sd->localcount; ++i) {
904 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
905 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
914 /* XXX mark mixed type variables void */
915 /* XXX cascading collapse? */
916 #if defined(STACK_VERBOSE)
917 printf("------> using L%03d\n", b->nr);
921 } while ((b = b->copied_to) != NULL);
923 b = stack_clone_block(sd, orig);
927 stack_create_invars_from_outvars(sd, b);
932 /* stack_create_instack ********************************************************
934 Create the instack of the current basic block.
937 sd...........stack analysis data
940 the current stack top at the start of the basic block.
942 *******************************************************************************/
944 static stackptr stack_create_instack(stackdata_t *sd)
950 if ((depth = sd->bptr->indepth) == 0)
953 sp = (sd->new += depth);
957 index = sd->bptr->invars[depth];
959 sp->type = sd->var[index].type;
963 sp->varkind = STACKVAR;
967 /* return the top of the created stack */
972 /* stack_mark_reached **********************************************************
974 Mark the given block reached and propagate the current stack and locals to
975 it. This function specializes the target block, if necessary, and returns
976 a pointer to the specialized target.
979 sd...........stack analysis data
980 b............the block to reach
981 curstack.....the current stack top
982 stackdepth...the current stack depth
985 a pointer to (a specialized version of) the target
986 NULL.........a VerifyError has been thrown
988 *******************************************************************************/
990 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
992 #if defined(STACK_VERBOSE)
993 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
995 /* mark targets of backward branches */
997 b->bitflags |= BBFLAG_REPLACEMENT;
999 if (b->flags < BBREACHED) {
1000 /* b is reached for the first time. Create its invars. */
1002 #if defined(STACK_VERBOSE)
1003 printf("reached L%03d for the first time\n", b->nr);
1006 stack_create_invars(sd, b, curstack, stackdepth);
1008 b->flags = BBREACHED;
1013 /* b has been reached before. Check that its invars match. */
1015 return stack_check_invars(sd, b, curstack, stackdepth);
1020 /* stack_mark_reached_from_outvars *********************************************
1022 Mark the given block reached and propagate the outvars of the current block
1023 and the current locals to it. This function specializes the target block,
1024 if necessary, and returns a pointer to the specialized target.
1027 sd...........stack analysis data
1028 b............the block to reach
1031 a pointer to (a specialized version of) the target
1032 NULL.........a VerifyError has been thrown
1034 *******************************************************************************/
1036 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1038 #if defined(STACK_VERBOSE)
1039 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1041 /* mark targets of backward branches */
1043 b->bitflags |= BBFLAG_REPLACEMENT;
1045 if (b->flags < BBREACHED) {
1046 /* b is reached for the first time. Create its invars. */
1048 #if defined(STACK_VERBOSE)
1049 printf("reached L%03d for the first time\n", b->nr);
1052 stack_create_invars_from_outvars(sd, b);
1054 b->flags = BBREACHED;
1059 /* b has been reached before. Check that its invars match. */
1061 return stack_check_invars_from_outvars(sd, b);
1066 /* stack_reach_next_block ******************************************************
1068 Mark the following block reached and propagate the outvars of the current block
1069 and the current locals to it. This function specializes the target block,
1070 if necessary, and returns a pointer to the specialized target.
1073 sd...........stack analysis data
1076 a pointer to (a specialized version of) the following block
1077 NULL.........a VerifyError has been thrown
1079 *******************************************************************************/
1081 static bool stack_reach_next_block(stackdata_t *sd)
1086 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1087 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1091 if (tbptr != sd->bptr->next) {
1092 #if defined(STACK_VERBOSE)
1093 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1095 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1096 assert(iptr->opc == ICMD_NOP);
1097 iptr->opc = ICMD_GOTO;
1098 iptr->dst.block = tbptr;
1100 if (tbptr->flags < BBFINISHED)
1101 sd->repeat = true; /* XXX check if we really need to repeat */
1108 /* stack_reach_handlers ********************************************************
1110 Reach the exception handlers for the current block.
1113 sd...........stack analysis data
1116 true.........everything ok
1117 false........a VerifyError has been thrown
1119 *******************************************************************************/
1121 static bool stack_reach_handlers(stackdata_t *sd)
1126 #if defined(STACK_VERBOSE)
1127 printf("reaching exception handlers...\n");
1130 for (i=0; sd->handlers[i]; ++i) {
1131 tbptr = sd->handlers[i]->handler;
1133 tbptr->type = BBTYPE_EXH;
1134 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1136 /* reach (and specialize) the handler block */
1138 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1143 sd->handlers[i]->handler = tbptr;
1150 /* stack_reanalyse_block ******************************************************
1152 Re-analyse the current block. This is called if either the block itself
1153 has already been analysed before, or the current block is a clone of an
1154 already analysed block, and this clone is reached for the first time.
1155 In the latter case, this function does all that is necessary for fully
1156 cloning the block (cloning the instruction list and variables, etc.).
1159 sd...........stack analysis data
1162 true.........everything ok
1163 false........a VerifyError has been thrown
1165 *******************************************************************************/
1167 #define RELOCATE(index) \
1169 if ((index) >= blockvarstart) \
1170 (index) += blockvarshift; \
1171 else if ((index) >= invarstart) \
1172 (index) += invarshift; \
1175 bool stack_reanalyse_block(stackdata_t *sd)
1187 branch_target_t *table;
1188 lookup_target_t *lookup;
1191 bool cloneinstructions;
1194 #if defined(STACK_VERBOSE)
1195 stack_verbose_block_enter(sd, true);
1202 assert(orig != NULL);
1204 /* clone the instruction list */
1206 cloneinstructions = true;
1208 assert(orig->iinstr);
1210 iptr = DMNEW(instruction, len + 1);
1212 MCOPY(iptr, orig->iinstr, instruction, len);
1213 iptr[len].opc = ICMD_NOP;
1217 /* allocate space for the clone's block variables */
1219 stack_grow_variable_array(sd, orig->varcount);
1221 /* we already have the invars set */
1223 assert(b->indepth == orig->indepth);
1225 /* calculate relocation shifts for invars and block variables */
1227 if (orig->indepth) {
1228 invarstart = orig->invars[0];
1229 invarshift = b->invars[0] - invarstart;
1232 invarstart = INT_MAX;
1235 blockvarstart = orig->varstart;
1236 blockvarshift = sd->vartop - blockvarstart;
1238 /* copy block variables */
1240 b->varstart = sd->vartop;
1241 b->varcount = orig->varcount;
1242 sd->vartop += b->varcount;
1243 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1247 b->outdepth = orig->outdepth;
1248 b->outvars = DMNEW(s4, orig->outdepth);
1249 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1251 /* clone exception handlers */
1253 for (i=0; sd->handlers[i]; ++i) {
1254 ex = DNEW(exceptiontable);
1255 ex->handler = sd->handlers[i]->handler;
1257 ex->end = b; /* XXX hack, see end of stack_analyse */
1258 ex->catchtype = sd->handlers[i]->catchtype;
1261 assert(sd->extableend->down == NULL);
1262 sd->extableend->down = ex;
1263 sd->extableend = ex;
1264 sd->jd->cd->exceptiontablelength++;
1266 sd->handlers[i] = ex;
1270 cloneinstructions = false;
1273 invarstart = sd->vartop;
1274 blockvarstart = sd->vartop;
1279 /* find exception handlers for the cloned block */
1281 ex = sd->jd->cd->exceptiontable;
1282 for (; ex != NULL; ex = ex->down) {
1283 /* XXX the cloned exception handlers have identical */
1284 /* start end end blocks. */
1285 if ((ex->start == b) && (ex->end == b)) {
1286 sd->handlers[len++] = ex;
1289 sd->handlers[len] = NULL;
1292 #if defined(STACK_VERBOSE)
1293 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1294 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1297 /* mark block as finished */
1299 b->flags = BBFINISHED;
1301 /* initialize locals at the start of this block */
1304 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1306 /* reach exception handlers for this block */
1308 if (!stack_reach_handlers(sd))
1311 superblockend = false;
1313 for (len = b->icount; len--; iptr++) {
1314 #if defined(STACK_VERBOSE)
1315 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1321 switch (iptr->opc) {
1323 j = iptr->s1.varindex;
1325 if (sd->var[j].type != TYPE_RET) {
1326 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1330 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1331 superblockend = true;
1335 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1336 superblockend = true;
1340 superblockend = true;
1343 case ICMD_CHECKNULL:
1344 case ICMD_PUTSTATICCONST:
1350 case ICMD_INLINE_START:
1351 case ICMD_INLINE_END:
1352 case ICMD_INLINE_GOTO:
1356 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1357 superblockend = true;
1360 /* pop 0 push 1 const */
1369 /* pop 0 push 1 load */
1376 RELOCATE(iptr->dst.varindex);
1389 RELOCATE(iptr->sx.s23.s2.varindex);
1390 RELOCATE(iptr->s1.varindex);
1391 RELOCATE(iptr->dst.varindex);
1405 RELOCATE(iptr->sx.s23.s3.varindex);
1406 RELOCATE(iptr->sx.s23.s2.varindex);
1407 RELOCATE(iptr->s1.varindex);
1411 /* pop 1 push 0 store */
1418 RELOCATE(iptr->s1.varindex);
1420 j = iptr->dst.varindex;
1421 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1433 RELOCATE(iptr->s1.varindex);
1434 superblockend = true;
1437 case ICMD_PUTSTATIC:
1438 case ICMD_PUTFIELDCONST:
1441 RELOCATE(iptr->s1.varindex);
1444 /* pop 1 push 0 branch */
1447 case ICMD_IFNONNULL:
1462 RELOCATE(iptr->s1.varindex);
1463 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1466 /* pop 1 push 0 table branch */
1468 case ICMD_TABLESWITCH:
1469 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1471 if (cloneinstructions) {
1472 table = DMNEW(branch_target_t, i);
1473 MCOPY(table, iptr->dst.table, branch_target_t, i);
1474 iptr->dst.table = table;
1477 table = iptr->dst.table;
1480 RELOCATE(iptr->s1.varindex);
1482 table->block = stack_mark_reached_from_outvars(sd, table->block);
1485 superblockend = true;
1488 case ICMD_LOOKUPSWITCH:
1489 i = iptr->sx.s23.s2.lookupcount;
1490 if (cloneinstructions) {
1491 lookup = DMNEW(lookup_target_t, i);
1492 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1493 iptr->dst.lookup = lookup;
1496 lookup = iptr->dst.lookup;
1498 RELOCATE(iptr->s1.varindex);
1500 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1503 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1504 superblockend = true;
1507 case ICMD_MONITORENTER:
1508 case ICMD_MONITOREXIT:
1509 RELOCATE(iptr->s1.varindex);
1513 /* pop 2 push 0 branch */
1515 case ICMD_IF_ICMPEQ:
1516 case ICMD_IF_ICMPNE:
1517 case ICMD_IF_ICMPLT:
1518 case ICMD_IF_ICMPGE:
1519 case ICMD_IF_ICMPGT:
1520 case ICMD_IF_ICMPLE:
1522 case ICMD_IF_LCMPEQ:
1523 case ICMD_IF_LCMPNE:
1524 case ICMD_IF_LCMPLT:
1525 case ICMD_IF_LCMPGE:
1526 case ICMD_IF_LCMPGT:
1527 case ICMD_IF_LCMPLE:
1529 case ICMD_IF_FCMPEQ:
1530 case ICMD_IF_FCMPNE:
1532 case ICMD_IF_FCMPL_LT:
1533 case ICMD_IF_FCMPL_GE:
1534 case ICMD_IF_FCMPL_GT:
1535 case ICMD_IF_FCMPL_LE:
1537 case ICMD_IF_FCMPG_LT:
1538 case ICMD_IF_FCMPG_GE:
1539 case ICMD_IF_FCMPG_GT:
1540 case ICMD_IF_FCMPG_LE:
1542 case ICMD_IF_DCMPEQ:
1543 case ICMD_IF_DCMPNE:
1545 case ICMD_IF_DCMPL_LT:
1546 case ICMD_IF_DCMPL_GE:
1547 case ICMD_IF_DCMPL_GT:
1548 case ICMD_IF_DCMPL_LE:
1550 case ICMD_IF_DCMPG_LT:
1551 case ICMD_IF_DCMPG_GE:
1552 case ICMD_IF_DCMPG_GT:
1553 case ICMD_IF_DCMPG_LE:
1555 case ICMD_IF_ACMPEQ:
1556 case ICMD_IF_ACMPNE:
1557 RELOCATE(iptr->sx.s23.s2.varindex);
1558 RELOCATE(iptr->s1.varindex);
1559 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1565 case ICMD_IASTORECONST:
1566 case ICMD_LASTORECONST:
1567 case ICMD_AASTORECONST:
1568 case ICMD_BASTORECONST:
1569 case ICMD_CASTORECONST:
1570 case ICMD_SASTORECONST:
1573 RELOCATE(iptr->sx.s23.s2.varindex);
1574 RELOCATE(iptr->s1.varindex);
1577 /* pop 0 push 1 copy */
1581 RELOCATE(iptr->dst.varindex);
1582 RELOCATE(iptr->s1.varindex);
1583 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1626 RELOCATE(iptr->sx.s23.s2.varindex);
1627 RELOCATE(iptr->s1.varindex);
1628 RELOCATE(iptr->dst.varindex);
1633 case ICMD_CHECKCAST:
1634 case ICMD_ARRAYLENGTH:
1635 case ICMD_INSTANCEOF:
1637 case ICMD_ANEWARRAY:
1640 case ICMD_IADDCONST:
1641 case ICMD_ISUBCONST:
1642 case ICMD_IMULCONST:
1646 case ICMD_IANDCONST:
1648 case ICMD_IXORCONST:
1649 case ICMD_ISHLCONST:
1650 case ICMD_ISHRCONST:
1651 case ICMD_IUSHRCONST:
1652 case ICMD_LADDCONST:
1653 case ICMD_LSUBCONST:
1654 case ICMD_LMULCONST:
1658 case ICMD_LANDCONST:
1660 case ICMD_LXORCONST:
1661 case ICMD_LSHLCONST:
1662 case ICMD_LSHRCONST:
1663 case ICMD_LUSHRCONST:
1667 case ICMD_INT2SHORT:
1683 RELOCATE(iptr->s1.varindex);
1684 RELOCATE(iptr->dst.varindex);
1689 case ICMD_GETSTATIC:
1692 RELOCATE(iptr->dst.varindex);
1695 /* pop many push any */
1697 case ICMD_INVOKESTATIC:
1698 case ICMD_INVOKESPECIAL:
1699 case ICMD_INVOKEVIRTUAL:
1700 case ICMD_INVOKEINTERFACE:
1702 case ICMD_MULTIANEWARRAY:
1703 i = iptr->s1.argcount;
1704 if (cloneinstructions) {
1705 argp = DMNEW(s4, i);
1706 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1707 iptr->sx.s23.s2.args = argp;
1710 argp = iptr->sx.s23.s2.args;
1718 RELOCATE(iptr->dst.varindex);
1723 new_internalerror("Unknown ICMD %d during stack re-analysis",
1728 #if defined(STACK_VERBOSE)
1729 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1734 /* relocate outvars */
1736 for (i=0; i<b->outdepth; ++i) {
1737 RELOCATE(b->outvars[i]);
1740 #if defined(STACK_VERBOSE)
1741 stack_verbose_block_exit(sd, superblockend);
1744 /* propagate to the next block */
1747 if (!stack_reach_next_block(sd))
1754 /* stack_analyse ***************************************************************
1756 Analyse_stack uses the intermediate code created by parse.c to
1757 build a model of the JVM operand stack for the current method.
1759 The following checks are performed:
1760 - check for operand stack underflow (before each instruction)
1761 - check for operand stack overflow (after[1] each instruction)
1762 - check for matching stack depth at merging points
1763 - check for matching basic types[2] at merging points
1764 - check basic types for instruction input (except for BUILTIN*
1765 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1767 [1]) Checking this after the instruction should be ok. parse.c
1768 counts the number of required stack slots in such a way that it is
1769 only vital that we don't exceed `maxstack` at basic block
1772 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1773 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1774 types are not discerned.
1776 *******************************************************************************/
1778 bool stack_analyse(jitdata *jd)
1780 methodinfo *m; /* method being analyzed */
1785 #if defined(ENABLE_SSA)
1788 int b_index; /* basic block index */
1790 stackptr curstack; /* current stack top */
1792 int opcode; /* opcode of current instruction */
1795 int len; /* # of instructions after the current one */
1796 bool superblockend; /* if true, no fallthrough to next block */
1797 bool deadcode; /* true if no live code has been reached */
1798 instruction *iptr; /* the current instruction */
1800 basicblock *original;
1803 stackptr *last_store_boundary;
1804 stackptr coalescing_boundary;
1806 stackptr src1, src2, src3, src4, dst1, dst2;
1808 branch_target_t *table;
1809 lookup_target_t *lookup;
1810 #if defined(ENABLE_VERIFIER)
1811 int expectedtype; /* used by CHECK_BASIC_TYPE */
1813 builtintable_entry *bte;
1815 constant_FMIref *fmiref;
1816 #if defined(ENABLE_STATISTICS)
1817 int iteration_count; /* number of iterations of analysis */
1819 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1821 #if defined(STACK_VERBOSE)
1822 show_method(jd, SHOW_PARSE);
1825 /* get required compiler data - initialization */
1831 #if defined(ENABLE_SSA)
1835 /* initialize the stackdata_t struct */
1839 sd.varcount = jd->varcount;
1840 sd.vartop = jd->vartop;
1841 sd.localcount = jd->localcount;
1843 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1844 sd.exstack.type = TYPE_ADR;
1845 sd.exstack.prev = NULL;
1846 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1848 #if defined(ENABLE_LSRA)
1849 m->maxlifetimes = 0;
1852 #if defined(ENABLE_STATISTICS)
1853 iteration_count = 0;
1856 /* find the last real basic block */
1858 sd.last_real_block = NULL;
1859 tbptr = jd->basicblocks;
1860 while (tbptr->next) {
1861 sd.last_real_block = tbptr;
1862 tbptr = tbptr->next;
1864 assert(sd.last_real_block);
1866 /* find the last exception handler */
1868 if (cd->exceptiontablelength)
1869 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1871 sd.extableend = NULL;
1873 /* init jd->interface_map */
1875 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1876 for (i = 0; i < m->maxstack * 5; i++)
1877 jd->interface_map[i].flags = UNUSED;
1879 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1881 /* initialize flags and invars (none) of first block */
1883 jd->basicblocks[0].flags = BBREACHED;
1884 jd->basicblocks[0].invars = NULL;
1885 jd->basicblocks[0].indepth = 0;
1886 jd->basicblocks[0].inlocals =
1887 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
1888 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
1889 jd->localcount + VERIFIER_EXTRA_LOCALS);
1891 /* stack analysis loop (until fixpoint reached) **************************/
1894 #if defined(ENABLE_STATISTICS)
1898 /* initialize loop over basic blocks */
1900 sd.bptr = jd->basicblocks;
1901 superblockend = true;
1903 curstack = NULL; stackdepth = 0;
1906 /* iterate over basic blocks *****************************************/
1908 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1910 if (sd.bptr->flags == BBDELETED) {
1911 /* This block has been deleted - do nothing. */
1916 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1917 /* This block has not been reached so far, and we */
1918 /* don't fall into it, so we'll have to iterate again. */
1924 if (sd.bptr->flags > BBREACHED) {
1925 /* This block is already finished. */
1927 superblockend = true;
1931 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1932 /* This block is a clone and the original has not been */
1933 /* analysed, yet. Analyse it on the next iteration. */
1939 /* This block has to be analysed now. */
1941 /* XXX The rest of this block is still indented one level too */
1942 /* much in order to avoid a giant diff by changing that. */
1944 /* We know that sd.bptr->flags == BBREACHED. */
1945 /* This block has been reached before. */
1947 assert(sd.bptr->flags == BBREACHED);
1948 stackdepth = sd.bptr->indepth;
1950 /* find exception handlers for this block */
1952 /* determine the active exception handlers for this block */
1953 /* XXX could use a faster algorithm with sorted lists or */
1956 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1959 ex = cd->exceptiontable;
1960 for (; ex != NULL; ex = ex->down) {
1961 if ((ex->start <= original) && (ex->end > original)) {
1962 sd.handlers[len++] = ex;
1965 sd.handlers[len] = NULL;
1968 /* reanalyse cloned block */
1970 if (sd.bptr->original) {
1971 if (!stack_reanalyse_block(&sd))
1976 /* reset the new pointer for allocating stackslots */
1980 /* create the instack of this block */
1982 curstack = stack_create_instack(&sd);
1984 /* initialize locals at the start of this block */
1986 if (sd.bptr->inlocals)
1987 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1989 /* set up local variables for analyzing this block */
1992 superblockend = false;
1993 len = sd.bptr->icount;
1994 iptr = sd.bptr->iinstr;
1995 b_index = sd.bptr - jd->basicblocks;
1997 /* mark the block as analysed */
1999 sd.bptr->flags = BBFINISHED;
2001 /* reset variables for dependency checking */
2003 coalescing_boundary = sd.new;
2004 for( i = 0; i < cd->maxlocals; i++)
2005 last_store_boundary[i] = sd.new;
2007 /* remember the start of this block's variables */
2009 sd.bptr->varstart = sd.vartop;
2011 #if defined(STACK_VERBOSE)
2012 stack_verbose_block_enter(&sd, false);
2015 /* reach exception handlers for this block */
2017 if (!stack_reach_handlers(&sd))
2020 /* iterate over ICMDs ****************************************/
2022 while (--len >= 0) {
2024 #if defined(STACK_VERBOSE)
2025 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2026 for( copy = curstack; copy; copy = copy->prev ) {
2027 printf("%2d(%d", copy->varnum, copy->type);
2030 if (IS_PREALLOC(copy))
2037 /* fetch the current opcode */
2041 /* automatically replace some ICMDs with builtins */
2043 #if defined(USEBUILTINTABLE)
2045 bte = builtintable_get_automatic(opcode);
2047 if (bte && bte->opcode == opcode) {
2048 iptr->opc = ICMD_BUILTIN;
2049 iptr->flags.bits = 0;
2050 iptr->sx.s23.s3.bte = bte;
2051 /* iptr->line is already set */
2052 jd->isleafmethod = false;
2056 #endif /* defined(USEBUILTINTABLE) */
2058 /* main opcode switch *************************************/
2070 case ICMD_CHECKNULL:
2071 coalescing_boundary = sd.new;
2072 COUNT(count_check_null);
2075 CLR_DST; /* XXX live through? */
2079 j = iptr->s1.varindex =
2080 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2082 if (sd.var[j].type != TYPE_RET) {
2083 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2089 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2091 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
2093 superblockend = true;
2097 COUNT(count_pcmd_return);
2100 superblockend = true;
2104 /* pop 0 push 1 const */
2106 /************************** ICONST OPTIMIZATIONS **************************/
2109 COUNT(count_pcmd_load);
2113 switch (iptr[1].opc) {
2115 iptr->opc = ICMD_IADDCONST;
2119 iptr[1].opc = ICMD_NOP;
2120 OP1_1(TYPE_INT, TYPE_INT);
2121 COUNT(count_pcmd_op);
2125 iptr->opc = ICMD_ISUBCONST;
2126 goto icmd_iconst_tail;
2127 #if SUPPORT_CONST_MUL
2129 iptr->opc = ICMD_IMULCONST;
2130 goto icmd_iconst_tail;
2131 #else /* SUPPORT_CONST_MUL */
2133 if (iptr->sx.val.i == 0x00000002)
2135 else if (iptr->sx.val.i == 0x00000004)
2137 else if (iptr->sx.val.i == 0x00000008)
2139 else if (iptr->sx.val.i == 0x00000010)
2141 else if (iptr->sx.val.i == 0x00000020)
2143 else if (iptr->sx.val.i == 0x00000040)
2145 else if (iptr->sx.val.i == 0x00000080)
2147 else if (iptr->sx.val.i == 0x00000100)
2149 else if (iptr->sx.val.i == 0x00000200)
2151 else if (iptr->sx.val.i == 0x00000400)
2152 iptr->sx.val.i = 10;
2153 else if (iptr->sx.val.i == 0x00000800)
2154 iptr->sx.val.i = 11;
2155 else if (iptr->sx.val.i == 0x00001000)
2156 iptr->sx.val.i = 12;
2157 else if (iptr->sx.val.i == 0x00002000)
2158 iptr->sx.val.i = 13;
2159 else if (iptr->sx.val.i == 0x00004000)
2160 iptr->sx.val.i = 14;
2161 else if (iptr->sx.val.i == 0x00008000)
2162 iptr->sx.val.i = 15;
2163 else if (iptr->sx.val.i == 0x00010000)
2164 iptr->sx.val.i = 16;
2165 else if (iptr->sx.val.i == 0x00020000)
2166 iptr->sx.val.i = 17;
2167 else if (iptr->sx.val.i == 0x00040000)
2168 iptr->sx.val.i = 18;
2169 else if (iptr->sx.val.i == 0x00080000)
2170 iptr->sx.val.i = 19;
2171 else if (iptr->sx.val.i == 0x00100000)
2172 iptr->sx.val.i = 20;
2173 else if (iptr->sx.val.i == 0x00200000)
2174 iptr->sx.val.i = 21;
2175 else if (iptr->sx.val.i == 0x00400000)
2176 iptr->sx.val.i = 22;
2177 else if (iptr->sx.val.i == 0x00800000)
2178 iptr->sx.val.i = 23;
2179 else if (iptr->sx.val.i == 0x01000000)
2180 iptr->sx.val.i = 24;
2181 else if (iptr->sx.val.i == 0x02000000)
2182 iptr->sx.val.i = 25;
2183 else if (iptr->sx.val.i == 0x04000000)
2184 iptr->sx.val.i = 26;
2185 else if (iptr->sx.val.i == 0x08000000)
2186 iptr->sx.val.i = 27;
2187 else if (iptr->sx.val.i == 0x10000000)
2188 iptr->sx.val.i = 28;
2189 else if (iptr->sx.val.i == 0x20000000)
2190 iptr->sx.val.i = 29;
2191 else if (iptr->sx.val.i == 0x40000000)
2192 iptr->sx.val.i = 30;
2193 else if (iptr->sx.val.i == 0x80000000)
2194 iptr->sx.val.i = 31;
2198 iptr->opc = ICMD_IMULPOW2;
2199 goto icmd_iconst_tail;
2200 #endif /* SUPPORT_CONST_MUL */
2202 if (iptr->sx.val.i == 0x00000002)
2204 else if (iptr->sx.val.i == 0x00000004)
2206 else if (iptr->sx.val.i == 0x00000008)
2208 else if (iptr->sx.val.i == 0x00000010)
2210 else if (iptr->sx.val.i == 0x00000020)
2212 else if (iptr->sx.val.i == 0x00000040)
2214 else if (iptr->sx.val.i == 0x00000080)
2216 else if (iptr->sx.val.i == 0x00000100)
2218 else if (iptr->sx.val.i == 0x00000200)
2220 else if (iptr->sx.val.i == 0x00000400)
2221 iptr->sx.val.i = 10;
2222 else if (iptr->sx.val.i == 0x00000800)
2223 iptr->sx.val.i = 11;
2224 else if (iptr->sx.val.i == 0x00001000)
2225 iptr->sx.val.i = 12;
2226 else if (iptr->sx.val.i == 0x00002000)
2227 iptr->sx.val.i = 13;
2228 else if (iptr->sx.val.i == 0x00004000)
2229 iptr->sx.val.i = 14;
2230 else if (iptr->sx.val.i == 0x00008000)
2231 iptr->sx.val.i = 15;
2232 else if (iptr->sx.val.i == 0x00010000)
2233 iptr->sx.val.i = 16;
2234 else if (iptr->sx.val.i == 0x00020000)
2235 iptr->sx.val.i = 17;
2236 else if (iptr->sx.val.i == 0x00040000)
2237 iptr->sx.val.i = 18;
2238 else if (iptr->sx.val.i == 0x00080000)
2239 iptr->sx.val.i = 19;
2240 else if (iptr->sx.val.i == 0x00100000)
2241 iptr->sx.val.i = 20;
2242 else if (iptr->sx.val.i == 0x00200000)
2243 iptr->sx.val.i = 21;
2244 else if (iptr->sx.val.i == 0x00400000)
2245 iptr->sx.val.i = 22;
2246 else if (iptr->sx.val.i == 0x00800000)
2247 iptr->sx.val.i = 23;
2248 else if (iptr->sx.val.i == 0x01000000)
2249 iptr->sx.val.i = 24;
2250 else if (iptr->sx.val.i == 0x02000000)
2251 iptr->sx.val.i = 25;
2252 else if (iptr->sx.val.i == 0x04000000)
2253 iptr->sx.val.i = 26;
2254 else if (iptr->sx.val.i == 0x08000000)
2255 iptr->sx.val.i = 27;
2256 else if (iptr->sx.val.i == 0x10000000)
2257 iptr->sx.val.i = 28;
2258 else if (iptr->sx.val.i == 0x20000000)
2259 iptr->sx.val.i = 29;
2260 else if (iptr->sx.val.i == 0x40000000)
2261 iptr->sx.val.i = 30;
2262 else if (iptr->sx.val.i == 0x80000000)
2263 iptr->sx.val.i = 31;
2267 iptr->opc = ICMD_IDIVPOW2;
2268 goto icmd_iconst_tail;
2271 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2272 if ((iptr->sx.val.i == 0x00000002) ||
2273 (iptr->sx.val.i == 0x00000004) ||
2274 (iptr->sx.val.i == 0x00000008) ||
2275 (iptr->sx.val.i == 0x00000010) ||
2276 (iptr->sx.val.i == 0x00000020) ||
2277 (iptr->sx.val.i == 0x00000040) ||
2278 (iptr->sx.val.i == 0x00000080) ||
2279 (iptr->sx.val.i == 0x00000100) ||
2280 (iptr->sx.val.i == 0x00000200) ||
2281 (iptr->sx.val.i == 0x00000400) ||
2282 (iptr->sx.val.i == 0x00000800) ||
2283 (iptr->sx.val.i == 0x00001000) ||
2284 (iptr->sx.val.i == 0x00002000) ||
2285 (iptr->sx.val.i == 0x00004000) ||
2286 (iptr->sx.val.i == 0x00008000) ||
2287 (iptr->sx.val.i == 0x00010000) ||
2288 (iptr->sx.val.i == 0x00020000) ||
2289 (iptr->sx.val.i == 0x00040000) ||
2290 (iptr->sx.val.i == 0x00080000) ||
2291 (iptr->sx.val.i == 0x00100000) ||
2292 (iptr->sx.val.i == 0x00200000) ||
2293 (iptr->sx.val.i == 0x00400000) ||
2294 (iptr->sx.val.i == 0x00800000) ||
2295 (iptr->sx.val.i == 0x01000000) ||
2296 (iptr->sx.val.i == 0x02000000) ||
2297 (iptr->sx.val.i == 0x04000000) ||
2298 (iptr->sx.val.i == 0x08000000) ||
2299 (iptr->sx.val.i == 0x10000000) ||
2300 (iptr->sx.val.i == 0x20000000) ||
2301 (iptr->sx.val.i == 0x40000000) ||
2302 (iptr->sx.val.i == 0x80000000))
2304 iptr->opc = ICMD_IREMPOW2;
2305 iptr->sx.val.i -= 1;
2306 goto icmd_iconst_tail;
2309 #if SUPPORT_CONST_LOGICAL
2311 iptr->opc = ICMD_IANDCONST;
2312 goto icmd_iconst_tail;
2315 iptr->opc = ICMD_IORCONST;
2316 goto icmd_iconst_tail;
2319 iptr->opc = ICMD_IXORCONST;
2320 goto icmd_iconst_tail;
2322 #endif /* SUPPORT_CONST_LOGICAL */
2324 iptr->opc = ICMD_ISHLCONST;
2325 goto icmd_iconst_tail;
2328 iptr->opc = ICMD_ISHRCONST;
2329 goto icmd_iconst_tail;
2332 iptr->opc = ICMD_IUSHRCONST;
2333 goto icmd_iconst_tail;
2334 #if SUPPORT_LONG_SHIFT
2336 iptr->opc = ICMD_LSHLCONST;
2337 goto icmd_lconst_tail;
2340 iptr->opc = ICMD_LSHRCONST;
2341 goto icmd_lconst_tail;
2344 iptr->opc = ICMD_LUSHRCONST;
2345 goto icmd_lconst_tail;
2346 #endif /* SUPPORT_LONG_SHIFT */
2347 case ICMD_IF_ICMPEQ:
2348 iptr[1].opc = ICMD_IFEQ;
2352 /* set the constant for the following icmd */
2353 iptr[1].sx.val.i = iptr->sx.val.i;
2355 /* this instruction becomes a nop */
2356 iptr->opc = ICMD_NOP;
2359 case ICMD_IF_ICMPLT:
2360 iptr[1].opc = ICMD_IFLT;
2361 goto icmd_if_icmp_tail;
2363 case ICMD_IF_ICMPLE:
2364 iptr[1].opc = ICMD_IFLE;
2365 goto icmd_if_icmp_tail;
2367 case ICMD_IF_ICMPNE:
2368 iptr[1].opc = ICMD_IFNE;
2369 goto icmd_if_icmp_tail;
2371 case ICMD_IF_ICMPGT:
2372 iptr[1].opc = ICMD_IFGT;
2373 goto icmd_if_icmp_tail;
2375 case ICMD_IF_ICMPGE:
2376 iptr[1].opc = ICMD_IFGE;
2377 goto icmd_if_icmp_tail;
2379 #if SUPPORT_CONST_STORE
2384 IF_INTRP( goto normal_ICONST; )
2385 # if SUPPORT_CONST_STORE_ZERO_ONLY
2386 if (iptr->sx.val.i != 0)
2389 switch (iptr[1].opc) {
2391 iptr->opc = ICMD_IASTORECONST;
2392 iptr->flags.bits |= INS_FLAG_CHECK;
2395 iptr->opc = ICMD_BASTORECONST;
2396 iptr->flags.bits |= INS_FLAG_CHECK;
2399 iptr->opc = ICMD_CASTORECONST;
2400 iptr->flags.bits |= INS_FLAG_CHECK;
2403 iptr->opc = ICMD_SASTORECONST;
2404 iptr->flags.bits |= INS_FLAG_CHECK;
2408 iptr[1].opc = ICMD_NOP;
2410 /* copy the constant to s3 */
2411 /* XXX constval -> astoreconstval? */
2412 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2413 OP2_0(TYPE_ADR, TYPE_INT);
2414 COUNT(count_pcmd_op);
2417 case ICMD_PUTSTATIC:
2419 IF_INTRP( goto normal_ICONST; )
2420 # if SUPPORT_CONST_STORE_ZERO_ONLY
2421 if (iptr->sx.val.i != 0)
2424 /* XXX check field type? */
2426 /* copy the constant to s2 */
2427 /* XXX constval -> fieldconstval? */
2428 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2431 /* set the field reference (s3) */
2432 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2433 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2434 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2437 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2440 switch (iptr[1].opc) {
2441 case ICMD_PUTSTATIC:
2442 iptr->opc = ICMD_PUTSTATICCONST;
2446 iptr->opc = ICMD_PUTFIELDCONST;
2451 iptr[1].opc = ICMD_NOP;
2452 COUNT(count_pcmd_op);
2454 #endif /* SUPPORT_CONST_STORE */
2460 /* if we get here, the ICONST has been optimized */
2464 /* normal case of an unoptimized ICONST */
2468 /************************** LCONST OPTIMIZATIONS **************************/
2471 COUNT(count_pcmd_load);
2475 /* switch depending on the following instruction */
2477 switch (iptr[1].opc) {
2478 #if SUPPORT_LONG_ADD
2480 iptr->opc = ICMD_LADDCONST;
2484 /* instruction of type LONG -> LONG */
2485 iptr[1].opc = ICMD_NOP;
2486 OP1_1(TYPE_LNG, TYPE_LNG);
2487 COUNT(count_pcmd_op);
2491 iptr->opc = ICMD_LSUBCONST;
2492 goto icmd_lconst_tail;
2494 #endif /* SUPPORT_LONG_ADD */
2495 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2497 iptr->opc = ICMD_LMULCONST;
2498 goto icmd_lconst_tail;
2499 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2500 # if SUPPORT_LONG_SHIFT
2502 if (iptr->sx.val.l == 0x00000002)
2504 else if (iptr->sx.val.l == 0x00000004)
2506 else if (iptr->sx.val.l == 0x00000008)
2508 else if (iptr->sx.val.l == 0x00000010)
2510 else if (iptr->sx.val.l == 0x00000020)
2512 else if (iptr->sx.val.l == 0x00000040)
2514 else if (iptr->sx.val.l == 0x00000080)
2516 else if (iptr->sx.val.l == 0x00000100)
2518 else if (iptr->sx.val.l == 0x00000200)
2520 else if (iptr->sx.val.l == 0x00000400)
2521 iptr->sx.val.i = 10;
2522 else if (iptr->sx.val.l == 0x00000800)
2523 iptr->sx.val.i = 11;
2524 else if (iptr->sx.val.l == 0x00001000)
2525 iptr->sx.val.i = 12;
2526 else if (iptr->sx.val.l == 0x00002000)
2527 iptr->sx.val.i = 13;
2528 else if (iptr->sx.val.l == 0x00004000)
2529 iptr->sx.val.i = 14;
2530 else if (iptr->sx.val.l == 0x00008000)
2531 iptr->sx.val.i = 15;
2532 else if (iptr->sx.val.l == 0x00010000)
2533 iptr->sx.val.i = 16;
2534 else if (iptr->sx.val.l == 0x00020000)
2535 iptr->sx.val.i = 17;
2536 else if (iptr->sx.val.l == 0x00040000)
2537 iptr->sx.val.i = 18;
2538 else if (iptr->sx.val.l == 0x00080000)
2539 iptr->sx.val.i = 19;
2540 else if (iptr->sx.val.l == 0x00100000)
2541 iptr->sx.val.i = 20;
2542 else if (iptr->sx.val.l == 0x00200000)
2543 iptr->sx.val.i = 21;
2544 else if (iptr->sx.val.l == 0x00400000)
2545 iptr->sx.val.i = 22;
2546 else if (iptr->sx.val.l == 0x00800000)
2547 iptr->sx.val.i = 23;
2548 else if (iptr->sx.val.l == 0x01000000)
2549 iptr->sx.val.i = 24;
2550 else if (iptr->sx.val.l == 0x02000000)
2551 iptr->sx.val.i = 25;
2552 else if (iptr->sx.val.l == 0x04000000)
2553 iptr->sx.val.i = 26;
2554 else if (iptr->sx.val.l == 0x08000000)
2555 iptr->sx.val.i = 27;
2556 else if (iptr->sx.val.l == 0x10000000)
2557 iptr->sx.val.i = 28;
2558 else if (iptr->sx.val.l == 0x20000000)
2559 iptr->sx.val.i = 29;
2560 else if (iptr->sx.val.l == 0x40000000)
2561 iptr->sx.val.i = 30;
2562 else if (iptr->sx.val.l == 0x80000000)
2563 iptr->sx.val.i = 31;
2567 iptr->opc = ICMD_LMULPOW2;
2568 goto icmd_lconst_tail;
2569 # endif /* SUPPORT_LONG_SHIFT */
2570 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2571 #if SUPPORT_LONG_DIV_POW2
2573 if (iptr->sx.val.l == 0x00000002)
2575 else if (iptr->sx.val.l == 0x00000004)
2577 else if (iptr->sx.val.l == 0x00000008)
2579 else if (iptr->sx.val.l == 0x00000010)
2581 else if (iptr->sx.val.l == 0x00000020)
2583 else if (iptr->sx.val.l == 0x00000040)
2585 else if (iptr->sx.val.l == 0x00000080)
2587 else if (iptr->sx.val.l == 0x00000100)
2589 else if (iptr->sx.val.l == 0x00000200)
2591 else if (iptr->sx.val.l == 0x00000400)
2592 iptr->sx.val.i = 10;
2593 else if (iptr->sx.val.l == 0x00000800)
2594 iptr->sx.val.i = 11;
2595 else if (iptr->sx.val.l == 0x00001000)
2596 iptr->sx.val.i = 12;
2597 else if (iptr->sx.val.l == 0x00002000)
2598 iptr->sx.val.i = 13;
2599 else if (iptr->sx.val.l == 0x00004000)
2600 iptr->sx.val.i = 14;
2601 else if (iptr->sx.val.l == 0x00008000)
2602 iptr->sx.val.i = 15;
2603 else if (iptr->sx.val.l == 0x00010000)
2604 iptr->sx.val.i = 16;
2605 else if (iptr->sx.val.l == 0x00020000)
2606 iptr->sx.val.i = 17;
2607 else if (iptr->sx.val.l == 0x00040000)
2608 iptr->sx.val.i = 18;
2609 else if (iptr->sx.val.l == 0x00080000)
2610 iptr->sx.val.i = 19;
2611 else if (iptr->sx.val.l == 0x00100000)
2612 iptr->sx.val.i = 20;
2613 else if (iptr->sx.val.l == 0x00200000)
2614 iptr->sx.val.i = 21;
2615 else if (iptr->sx.val.l == 0x00400000)
2616 iptr->sx.val.i = 22;
2617 else if (iptr->sx.val.l == 0x00800000)
2618 iptr->sx.val.i = 23;
2619 else if (iptr->sx.val.l == 0x01000000)
2620 iptr->sx.val.i = 24;
2621 else if (iptr->sx.val.l == 0x02000000)
2622 iptr->sx.val.i = 25;
2623 else if (iptr->sx.val.l == 0x04000000)
2624 iptr->sx.val.i = 26;
2625 else if (iptr->sx.val.l == 0x08000000)
2626 iptr->sx.val.i = 27;
2627 else if (iptr->sx.val.l == 0x10000000)
2628 iptr->sx.val.i = 28;
2629 else if (iptr->sx.val.l == 0x20000000)
2630 iptr->sx.val.i = 29;
2631 else if (iptr->sx.val.l == 0x40000000)
2632 iptr->sx.val.i = 30;
2633 else if (iptr->sx.val.l == 0x80000000)
2634 iptr->sx.val.i = 31;
2638 iptr->opc = ICMD_LDIVPOW2;
2639 goto icmd_lconst_tail;
2640 #endif /* SUPPORT_LONG_DIV_POW2 */
2642 #if SUPPORT_LONG_REM_POW2
2644 if ((iptr->sx.val.l == 0x00000002) ||
2645 (iptr->sx.val.l == 0x00000004) ||
2646 (iptr->sx.val.l == 0x00000008) ||
2647 (iptr->sx.val.l == 0x00000010) ||
2648 (iptr->sx.val.l == 0x00000020) ||
2649 (iptr->sx.val.l == 0x00000040) ||
2650 (iptr->sx.val.l == 0x00000080) ||
2651 (iptr->sx.val.l == 0x00000100) ||
2652 (iptr->sx.val.l == 0x00000200) ||
2653 (iptr->sx.val.l == 0x00000400) ||
2654 (iptr->sx.val.l == 0x00000800) ||
2655 (iptr->sx.val.l == 0x00001000) ||
2656 (iptr->sx.val.l == 0x00002000) ||
2657 (iptr->sx.val.l == 0x00004000) ||
2658 (iptr->sx.val.l == 0x00008000) ||
2659 (iptr->sx.val.l == 0x00010000) ||
2660 (iptr->sx.val.l == 0x00020000) ||
2661 (iptr->sx.val.l == 0x00040000) ||
2662 (iptr->sx.val.l == 0x00080000) ||
2663 (iptr->sx.val.l == 0x00100000) ||
2664 (iptr->sx.val.l == 0x00200000) ||
2665 (iptr->sx.val.l == 0x00400000) ||
2666 (iptr->sx.val.l == 0x00800000) ||
2667 (iptr->sx.val.l == 0x01000000) ||
2668 (iptr->sx.val.l == 0x02000000) ||
2669 (iptr->sx.val.l == 0x04000000) ||
2670 (iptr->sx.val.l == 0x08000000) ||
2671 (iptr->sx.val.l == 0x10000000) ||
2672 (iptr->sx.val.l == 0x20000000) ||
2673 (iptr->sx.val.l == 0x40000000) ||
2674 (iptr->sx.val.l == 0x80000000))
2676 iptr->opc = ICMD_LREMPOW2;
2677 iptr->sx.val.l -= 1;
2678 goto icmd_lconst_tail;
2681 #endif /* SUPPORT_LONG_REM_POW2 */
2683 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2686 iptr->opc = ICMD_LANDCONST;
2687 goto icmd_lconst_tail;
2690 iptr->opc = ICMD_LORCONST;
2691 goto icmd_lconst_tail;
2694 iptr->opc = ICMD_LXORCONST;
2695 goto icmd_lconst_tail;
2696 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2698 #if SUPPORT_LONG_CMP_CONST
2700 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2703 /* switch on the instruction after LCONST - LCMP */
2705 switch (iptr[2].opc) {
2707 iptr->opc = ICMD_IF_LEQ;
2710 icmd_lconst_lcmp_tail:
2711 /* convert LCONST, LCMP, IFXX to IF_LXX */
2712 iptr->dst.insindex = iptr[2].dst.insindex;
2713 iptr[1].opc = ICMD_NOP;
2714 iptr[2].opc = ICMD_NOP;
2716 OP1_BRANCH(TYPE_LNG);
2718 COUNT(count_pcmd_bra);
2719 COUNT(count_pcmd_op);
2723 iptr->opc = ICMD_IF_LNE;
2724 goto icmd_lconst_lcmp_tail;
2727 iptr->opc = ICMD_IF_LLT;
2728 goto icmd_lconst_lcmp_tail;
2731 iptr->opc = ICMD_IF_LGT;
2732 goto icmd_lconst_lcmp_tail;
2735 iptr->opc = ICMD_IF_LLE;
2736 goto icmd_lconst_lcmp_tail;
2739 iptr->opc = ICMD_IF_LGE;
2740 goto icmd_lconst_lcmp_tail;
2744 } /* end switch on opcode after LCONST - LCMP */
2746 #endif /* SUPPORT_LONG_CMP_CONST */
2748 #if SUPPORT_CONST_STORE
2750 IF_INTRP( goto normal_LCONST; )
2751 # if SUPPORT_CONST_STORE_ZERO_ONLY
2752 if (iptr->sx.val.l != 0)
2755 #if SIZEOF_VOID_P == 4
2756 /* the constant must fit into a ptrint */
2757 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2760 /* move the constant to s3 */
2761 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2763 iptr->opc = ICMD_LASTORECONST;
2764 iptr->flags.bits |= INS_FLAG_CHECK;
2765 OP2_0(TYPE_ADR, TYPE_INT);
2767 iptr[1].opc = ICMD_NOP;
2768 COUNT(count_pcmd_op);
2771 case ICMD_PUTSTATIC:
2773 IF_INTRP( goto normal_LCONST; )
2774 # if SUPPORT_CONST_STORE_ZERO_ONLY
2775 if (iptr->sx.val.l != 0)
2778 #if SIZEOF_VOID_P == 4
2779 /* the constant must fit into a ptrint */
2780 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2783 /* XXX check field type? */
2785 /* copy the constant to s2 */
2786 /* XXX constval -> fieldconstval? */
2787 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2791 #endif /* SUPPORT_CONST_STORE */
2795 } /* end switch opcode after LCONST */
2797 /* if we get here, the LCONST has been optimized */
2801 /* the normal case of an unoptimized LCONST */
2805 /************************ END OF LCONST OPTIMIZATIONS *********************/
2808 COUNT(count_pcmd_load);
2813 COUNT(count_pcmd_load);
2817 /************************** ACONST OPTIMIZATIONS **************************/
2820 coalescing_boundary = sd.new;
2821 COUNT(count_pcmd_load);
2822 #if SUPPORT_CONST_STORE
2823 IF_INTRP( goto normal_ACONST; )
2825 /* We can only optimize if the ACONST is resolved
2826 * and there is an instruction after it. */
2828 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2831 switch (iptr[1].opc) {
2833 /* We can only optimize for NULL values
2834 * here because otherwise a checkcast is
2836 if (iptr->sx.val.anyptr != NULL)
2839 /* copy the constant (NULL) to s3 */
2840 iptr->sx.s23.s3.constval = 0;
2841 iptr->opc = ICMD_AASTORECONST;
2842 iptr->flags.bits |= INS_FLAG_CHECK;
2843 OP2_0(TYPE_ADR, TYPE_INT);
2845 iptr[1].opc = ICMD_NOP;
2846 COUNT(count_pcmd_op);
2849 case ICMD_PUTSTATIC:
2851 # if SUPPORT_CONST_STORE_ZERO_ONLY
2852 if (iptr->sx.val.anyptr != NULL)
2855 /* XXX check field type? */
2856 /* copy the constant to s2 */
2857 /* XXX constval -> fieldconstval? */
2858 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2866 /* if we get here the ACONST has been optimized */
2870 #endif /* SUPPORT_CONST_STORE */
2875 /* pop 0 push 1 load */
2882 COUNT(count_load_instruction);
2883 i = opcode - ICMD_ILOAD; /* type */
2885 j = iptr->s1.varindex =
2886 jd->local_map[iptr->s1.varindex * 5 + i];
2888 if (sd.var[j].type == TYPE_RET) {
2889 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
2893 #if defined(ENABLE_SSA)
2895 GET_NEW_VAR(sd, new_index, i);
2912 coalescing_boundary = sd.new;
2913 iptr->flags.bits |= INS_FLAG_CHECK;
2914 COUNT(count_check_null);
2915 COUNT(count_check_bound);
2916 COUNT(count_pcmd_mem);
2917 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
2924 coalescing_boundary = sd.new;
2925 iptr->flags.bits |= INS_FLAG_CHECK;
2926 COUNT(count_check_null);
2927 COUNT(count_check_bound);
2928 COUNT(count_pcmd_mem);
2929 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2932 /* pop 0 push 0 iinc */
2935 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2936 #if defined(ENABLE_SSA)
2939 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
2943 last_store_boundary[iptr->s1.varindex] = sd.new;
2946 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2951 if ((copy->varkind == LOCALVAR) &&
2952 (copy->varnum == iptr->s1.varindex))
2954 assert(IS_LOCALVAR(copy));
2960 #if defined(ENABLE_SSA)
2964 iptr->dst.varindex = iptr->s1.varindex;
2967 /* pop 1 push 0 store */
2976 i = opcode - ICMD_ISTORE; /* type */
2977 javaindex = iptr->dst.varindex;
2978 j = iptr->dst.varindex =
2979 jd->local_map[javaindex * 5 + i];
2981 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2983 #if defined(ENABLE_STATISTICS)
2986 i = sd.new - curstack;
2988 count_store_length[20]++;
2990 count_store_length[i]++;
2993 count_store_depth[10]++;
2995 count_store_depth[i]++;
2999 #if defined(ENABLE_SSA)
3002 /* check for conflicts as described in Figure 5.2 */
3004 copy = curstack->prev;
3007 if ((copy->varkind == LOCALVAR) &&
3008 (copy->varnum == j))
3010 copy->varkind = TEMPVAR;
3011 assert(IS_LOCALVAR(copy));
3018 /* if the variable is already coalesced, don't bother */
3020 /* We do not need to check against INOUT, as invars */
3021 /* are always before the coalescing boundary. */
3023 if (curstack->varkind == LOCALVAR)
3026 /* there is no STORE Lj while curstack is live */
3028 if (curstack < last_store_boundary[javaindex])
3029 goto assume_conflict;
3031 /* curstack must be after the coalescing boundary */
3033 if (curstack < coalescing_boundary)
3034 goto assume_conflict;
3036 /* there is no DEF LOCALVAR(j) while curstack is live */
3038 copy = sd.new; /* most recent stackslot created + 1 */
3039 while (--copy > curstack) {
3040 if (copy->varkind == LOCALVAR && copy->varnum == j)
3041 goto assume_conflict;
3044 /* coalesce the temporary variable with Lj */
3045 assert((curstack->varkind == TEMPVAR)
3046 || (curstack->varkind == UNDEFVAR));
3047 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3048 assert(!IS_INOUT(curstack));
3049 assert(!IS_PREALLOC(curstack));
3051 assert(curstack->creator);
3052 assert(curstack->creator->dst.varindex == curstack->varnum);
3053 RELEASE_INDEX(sd, curstack);
3054 curstack->varkind = LOCALVAR;
3055 curstack->varnum = j;
3056 curstack->creator->dst.varindex = j;
3059 /* revert the coalescing, if it has been done earlier */
3061 if ((curstack->varkind == LOCALVAR)
3062 && (curstack->varnum == j))
3064 assert(IS_LOCALVAR(curstack));
3065 SET_TEMPVAR(curstack);
3068 /* remember the stack boundary at this store */
3070 last_store_boundary[javaindex] = sd.new;
3071 #if defined(ENABLE_SSA)
3072 } /* if (ls != NULL) */
3075 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3078 STORE(opcode - ICMD_ISTORE, j);
3084 coalescing_boundary = sd.new;
3085 iptr->flags.bits |= INS_FLAG_CHECK;
3086 COUNT(count_check_null);
3087 COUNT(count_check_bound);
3088 COUNT(count_pcmd_mem);
3090 bte = builtintable_get_internal(BUILTIN_canstore);
3093 if (md->memuse > rd->memuse)
3094 rd->memuse = md->memuse;
3095 if (md->argintreguse > rd->argintreguse)
3096 rd->argintreguse = md->argintreguse;
3097 /* XXX non-leaf method? */
3099 /* make all stack variables saved */
3103 sd.var[copy->varnum].flags |= SAVEDVAR;
3104 /* in case copy->varnum is/will be a LOCALVAR */
3105 /* once and set back to a non LOCALVAR */
3106 /* the correct SAVEDVAR flag has to be */
3107 /* remembered in copy->flags, too */
3108 copy->flags |= SAVEDVAR;
3112 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3119 coalescing_boundary = sd.new;
3120 iptr->flags.bits |= INS_FLAG_CHECK;
3121 COUNT(count_check_null);
3122 COUNT(count_check_bound);
3123 COUNT(count_pcmd_mem);
3124 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3131 coalescing_boundary = sd.new;
3132 iptr->flags.bits |= INS_FLAG_CHECK;
3133 COUNT(count_check_null);
3134 COUNT(count_check_bound);
3135 COUNT(count_pcmd_mem);
3136 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3142 #ifdef ENABLE_VERIFIER
3145 if (IS_2_WORD_TYPE(curstack->type))
3146 goto throw_stack_category_error;
3157 coalescing_boundary = sd.new;
3158 /* Assert here that no LOCAL or INOUTS get */
3159 /* preallocated, since tha macros are not */
3160 /* available in md-abi.c! */
3161 IF_JIT( if (IS_TEMPVAR(curstack)) \
3162 md_return_alloc(jd, curstack); )
3163 COUNT(count_pcmd_return);
3164 OP1_0(opcode - ICMD_IRETURN);
3165 superblockend = true;
3169 coalescing_boundary = sd.new;
3170 COUNT(count_check_null);
3172 curstack = NULL; stackdepth = 0;
3173 superblockend = true;
3176 case ICMD_PUTSTATIC:
3177 coalescing_boundary = sd.new;
3178 COUNT(count_pcmd_mem);
3179 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3180 OP1_0(fmiref->parseddesc.fd->type);
3183 /* pop 1 push 0 branch */
3186 case ICMD_IFNONNULL:
3187 COUNT(count_pcmd_bra);
3188 OP1_BRANCH(TYPE_ADR);
3198 COUNT(count_pcmd_bra);
3199 /* iptr->sx.val.i is set implicitly in parse by
3200 clearing the memory or from IF_ICMPxx
3203 OP1_BRANCH(TYPE_INT);
3204 /* iptr->sx.val.i = 0; */
3208 /* pop 0 push 0 branch */
3211 COUNT(count_pcmd_bra);
3214 superblockend = true;
3217 /* pop 1 push 0 table branch */
3219 case ICMD_TABLESWITCH:
3220 COUNT(count_pcmd_table);
3221 OP1_BRANCH(TYPE_INT);
3223 table = iptr->dst.table;
3224 BRANCH_TARGET(*table, tbptr);
3227 i = iptr->sx.s23.s3.tablehigh
3228 - iptr->sx.s23.s2.tablelow + 1;
3231 BRANCH_TARGET(*table, tbptr);
3234 superblockend = true;
3237 /* pop 1 push 0 table branch */
3239 case ICMD_LOOKUPSWITCH:
3240 COUNT(count_pcmd_table);
3241 OP1_BRANCH(TYPE_INT);
3243 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3245 lookup = iptr->dst.lookup;
3247 i = iptr->sx.s23.s2.lookupcount;
3250 BRANCH_TARGET(lookup->target, tbptr);
3253 superblockend = true;
3256 case ICMD_MONITORENTER:
3257 case ICMD_MONITOREXIT:
3258 coalescing_boundary = sd.new;
3259 COUNT(count_check_null);
3263 /* pop 2 push 0 branch */
3265 case ICMD_IF_ICMPEQ:
3266 case ICMD_IF_ICMPNE:
3267 case ICMD_IF_ICMPLT:
3268 case ICMD_IF_ICMPGE:
3269 case ICMD_IF_ICMPGT:
3270 case ICMD_IF_ICMPLE:
3271 COUNT(count_pcmd_bra);
3272 OP2_BRANCH(TYPE_INT, TYPE_INT);
3276 case ICMD_IF_ACMPEQ:
3277 case ICMD_IF_ACMPNE:
3278 COUNT(count_pcmd_bra);
3279 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3286 coalescing_boundary = sd.new;
3287 COUNT(count_check_null);
3288 COUNT(count_pcmd_mem);
3289 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3290 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3295 if (!IS_2_WORD_TYPE(curstack->type)) {
3297 #ifdef ENABLE_VERIFIER
3300 if (IS_2_WORD_TYPE(curstack->prev->type))
3301 goto throw_stack_category_error;
3304 OP2_0_ANY_ANY; /* pop two slots */
3307 iptr->opc = ICMD_POP;
3308 OP1_0_ANY; /* pop one (two-word) slot */
3312 /* pop 0 push 1 dup */
3315 #ifdef ENABLE_VERIFIER
3318 if (IS_2_WORD_TYPE(curstack->type))
3319 goto throw_stack_category_error;
3322 COUNT(count_dup_instruction);
3328 coalescing_boundary = sd.new - 1;
3333 if (IS_2_WORD_TYPE(curstack->type)) {
3335 iptr->opc = ICMD_DUP;
3340 /* ..., ????, cat1 */
3341 #ifdef ENABLE_VERIFIER
3343 if (IS_2_WORD_TYPE(curstack->prev->type))
3344 goto throw_stack_category_error;
3347 src1 = curstack->prev;
3350 COPY_UP(src1); iptr++; len--;
3353 coalescing_boundary = sd.new;
3357 /* pop 2 push 3 dup */
3360 #ifdef ENABLE_VERIFIER
3363 if (IS_2_WORD_TYPE(curstack->type) ||
3364 IS_2_WORD_TYPE(curstack->prev->type))
3365 goto throw_stack_category_error;
3370 src1 = curstack->prev;
3375 /* move non-temporary sources out of the way */
3376 if (!IS_TEMPVAR(src2)) {
3377 MOVE_TO_TEMP(src2); iptr++; len--;
3380 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3382 MOVE_UP(src1); iptr++; len--;
3383 MOVE_UP(src2); iptr++; len--;
3385 COPY_DOWN(curstack, dst1);
3387 coalescing_boundary = sd.new;
3392 if (IS_2_WORD_TYPE(curstack->type)) {
3393 /* ..., ????, cat2 */
3394 #ifdef ENABLE_VERIFIER
3396 if (IS_2_WORD_TYPE(curstack->prev->type))
3397 goto throw_stack_category_error;
3400 iptr->opc = ICMD_DUP_X1;
3404 /* ..., ????, cat1 */
3405 #ifdef ENABLE_VERIFIER
3408 if (IS_2_WORD_TYPE(curstack->prev->type)
3409 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3410 goto throw_stack_category_error;
3415 src1 = curstack->prev->prev;
3416 src2 = curstack->prev;
3418 POPANY; POPANY; POPANY;
3421 /* move non-temporary sources out of the way */
3422 if (!IS_TEMPVAR(src2)) {
3423 MOVE_TO_TEMP(src2); iptr++; len--;
3425 if (!IS_TEMPVAR(src3)) {
3426 MOVE_TO_TEMP(src3); iptr++; len--;
3429 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3430 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3432 MOVE_UP(src1); iptr++; len--;
3433 MOVE_UP(src2); iptr++; len--;
3434 MOVE_UP(src3); iptr++; len--;
3436 COPY_DOWN(curstack, dst2); iptr++; len--;
3437 COPY_DOWN(curstack->prev, dst1);
3439 coalescing_boundary = sd.new;
3443 /* pop 3 push 4 dup */
3447 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3448 /* ..., cat2, ???? */
3449 #ifdef ENABLE_VERIFIER
3451 if (IS_2_WORD_TYPE(curstack->type))
3452 goto throw_stack_category_error;
3455 iptr->opc = ICMD_DUP_X1;
3459 /* ..., cat1, ???? */
3460 #ifdef ENABLE_VERIFIER
3463 if (IS_2_WORD_TYPE(curstack->type)
3464 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3465 goto throw_stack_category_error;
3469 src1 = curstack->prev->prev;
3470 src2 = curstack->prev;
3472 POPANY; POPANY; POPANY;
3475 /* move non-temporary sources out of the way */
3476 if (!IS_TEMPVAR(src2)) {
3477 MOVE_TO_TEMP(src2); iptr++; len--;
3479 if (!IS_TEMPVAR(src3)) {
3480 MOVE_TO_TEMP(src3); iptr++; len--;
3483 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3485 MOVE_UP(src1); iptr++; len--;
3486 MOVE_UP(src2); iptr++; len--;
3487 MOVE_UP(src3); iptr++; len--;
3489 COPY_DOWN(curstack, dst1);
3491 coalescing_boundary = sd.new;
3497 if (IS_2_WORD_TYPE(curstack->type)) {
3498 /* ..., ????, cat2 */
3499 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3500 /* ..., cat2, cat2 */
3501 iptr->opc = ICMD_DUP_X1;
3505 /* ..., cat1, cat2 */
3506 #ifdef ENABLE_VERIFIER
3509 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3510 goto throw_stack_category_error;
3513 iptr->opc = ICMD_DUP_X2;
3519 /* ..., ????, ????, cat1 */
3521 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3522 /* ..., cat2, ????, cat1 */
3523 #ifdef ENABLE_VERIFIER
3525 if (IS_2_WORD_TYPE(curstack->prev->type))
3526 goto throw_stack_category_error;
3529 iptr->opc = ICMD_DUP2_X1;
3533 /* ..., cat1, ????, cat1 */
3534 #ifdef ENABLE_VERIFIER
3537 if (IS_2_WORD_TYPE(curstack->prev->type)
3538 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3539 goto throw_stack_category_error;
3543 src1 = curstack->prev->prev->prev;
3544 src2 = curstack->prev->prev;
3545 src3 = curstack->prev;
3547 POPANY; POPANY; POPANY; POPANY;
3550 /* move non-temporary sources out of the way */
3551 if (!IS_TEMPVAR(src2)) {
3552 MOVE_TO_TEMP(src2); iptr++; len--;
3554 if (!IS_TEMPVAR(src3)) {
3555 MOVE_TO_TEMP(src3); iptr++; len--;
3557 if (!IS_TEMPVAR(src4)) {
3558 MOVE_TO_TEMP(src4); iptr++; len--;
3561 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3562 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3564 MOVE_UP(src1); iptr++; len--;
3565 MOVE_UP(src2); iptr++; len--;
3566 MOVE_UP(src3); iptr++; len--;
3567 MOVE_UP(src4); iptr++; len--;
3569 COPY_DOWN(curstack, dst2); iptr++; len--;
3570 COPY_DOWN(curstack->prev, dst1);
3572 coalescing_boundary = sd.new;
3576 /* pop 2 push 2 swap */
3579 #ifdef ENABLE_VERIFIER
3582 if (IS_2_WORD_TYPE(curstack->type)
3583 || IS_2_WORD_TYPE(curstack->prev->type))
3584 goto throw_stack_category_error;
3588 src1 = curstack->prev;
3593 /* move non-temporary sources out of the way */
3594 if (!IS_TEMPVAR(src1)) {
3595 MOVE_TO_TEMP(src1); iptr++; len--;
3598 MOVE_UP(src2); iptr++; len--;
3601 coalescing_boundary = sd.new;
3608 coalescing_boundary = sd.new;
3609 #if !SUPPORT_DIVISION
3610 bte = iptr->sx.s23.s3.bte;
3613 if (md->memuse > rd->memuse)
3614 rd->memuse = md->memuse;
3615 if (md->argintreguse > rd->argintreguse)
3616 rd->argintreguse = md->argintreguse;
3618 /* make all stack variables saved */
3622 sd.var[copy->varnum].flags |= SAVEDVAR;
3623 copy->flags |= SAVEDVAR;
3628 #endif /* !SUPPORT_DIVISION */
3639 COUNT(count_pcmd_op);
3640 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3645 coalescing_boundary = sd.new;
3646 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3647 bte = iptr->sx.s23.s3.bte;
3650 if (md->memuse > rd->memuse)
3651 rd->memuse = md->memuse;
3652 if (md->argintreguse > rd->argintreguse)
3653 rd->argintreguse = md->argintreguse;
3654 /* XXX non-leaf method? */
3656 /* make all stack variables saved */
3660 sd.var[copy->varnum].flags |= SAVEDVAR;
3661 copy->flags |= SAVEDVAR;
3666 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3671 #if SUPPORT_LONG_LOGICAL
3675 #endif /* SUPPORT_LONG_LOGICAL */
3676 COUNT(count_pcmd_op);
3677 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3683 COUNT(count_pcmd_op);
3684 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3692 COUNT(count_pcmd_op);
3693 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3701 COUNT(count_pcmd_op);
3702 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3706 COUNT(count_pcmd_op);
3707 #if SUPPORT_LONG_CMP_CONST
3708 if ((len == 0) || (iptr[1].sx.val.i != 0))
3711 switch (iptr[1].opc) {
3713 iptr->opc = ICMD_IF_LCMPEQ;
3715 iptr->dst.insindex = iptr[1].dst.insindex;
3716 iptr[1].opc = ICMD_NOP;
3718 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3721 COUNT(count_pcmd_bra);
3724 iptr->opc = ICMD_IF_LCMPNE;
3725 goto icmd_lcmp_if_tail;
3727 iptr->opc = ICMD_IF_LCMPLT;
3728 goto icmd_lcmp_if_tail;
3730 iptr->opc = ICMD_IF_LCMPGT;
3731 goto icmd_lcmp_if_tail;
3733 iptr->opc = ICMD_IF_LCMPLE;
3734 goto icmd_lcmp_if_tail;
3736 iptr->opc = ICMD_IF_LCMPGE;
3737 goto icmd_lcmp_if_tail;
3743 #endif /* SUPPORT_LONG_CMP_CONST */
3744 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3747 /* XXX why is this deactivated? */
3750 COUNT(count_pcmd_op);
3751 if ((len == 0) || (iptr[1].sx.val.i != 0))
3754 switch (iptr[1].opc) {
3756 iptr->opc = ICMD_IF_FCMPEQ;
3758 iptr->dst.insindex = iptr[1].dst.insindex;
3759 iptr[1].opc = ICMD_NOP;
3761 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3764 COUNT(count_pcmd_bra);
3767 iptr->opc = ICMD_IF_FCMPNE;
3768 goto icmd_if_fcmpl_tail;
3770 iptr->opc = ICMD_IF_FCMPL_LT;
3771 goto icmd_if_fcmpl_tail;
3773 iptr->opc = ICMD_IF_FCMPL_GT;
3774 goto icmd_if_fcmpl_tail;
3776 iptr->opc = ICMD_IF_FCMPL_LE;
3777 goto icmd_if_fcmpl_tail;
3779 iptr->opc = ICMD_IF_FCMPL_GE;
3780 goto icmd_if_fcmpl_tail;
3787 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3791 COUNT(count_pcmd_op);
3792 if ((len == 0) || (iptr[1].sx.val.i != 0))
3795 switch (iptr[1].opc) {
3797 iptr->opc = ICMD_IF_FCMPEQ;
3799 iptr->dst.insindex = iptr[1].dst.insindex;
3800 iptr[1].opc = ICMD_NOP;
3802 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3805 COUNT(count_pcmd_bra);
3808 iptr->opc = ICMD_IF_FCMPNE;
3809 goto icmd_if_fcmpg_tail;
3811 iptr->opc = ICMD_IF_FCMPG_LT;
3812 goto icmd_if_fcmpg_tail;
3814 iptr->opc = ICMD_IF_FCMPG_GT;
3815 goto icmd_if_fcmpg_tail;
3817 iptr->opc = ICMD_IF_FCMPG_LE;
3818 goto icmd_if_fcmpg_tail;
3820 iptr->opc = ICMD_IF_FCMPG_GE;
3821 goto icmd_if_fcmpg_tail;
3828 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3832 COUNT(count_pcmd_op);
3833 if ((len == 0) || (iptr[1].sx.val.i != 0))
3836 switch (iptr[1].opc) {
3838 iptr->opc = ICMD_IF_DCMPEQ;
3840 iptr->dst.insindex = iptr[1].dst.insindex;
3841 iptr[1].opc = ICMD_NOP;
3843 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3846 COUNT(count_pcmd_bra);
3849 iptr->opc = ICMD_IF_DCMPNE;
3850 goto icmd_if_dcmpl_tail;
3852 iptr->opc = ICMD_IF_DCMPL_LT;
3853 goto icmd_if_dcmpl_tail;
3855 iptr->opc = ICMD_IF_DCMPL_GT;
3856 goto icmd_if_dcmpl_tail;
3858 iptr->opc = ICMD_IF_DCMPL_LE;
3859 goto icmd_if_dcmpl_tail;
3861 iptr->opc = ICMD_IF_DCMPL_GE;
3862 goto icmd_if_dcmpl_tail;
3869 OPTT2_1(TYPE_DBL, TYPE_INT);
3873 COUNT(count_pcmd_op);
3874 if ((len == 0) || (iptr[1].sx.val.i != 0))
3877 switch (iptr[1].opc) {
3879 iptr->opc = ICMD_IF_DCMPEQ;
3881 iptr->dst.insindex = iptr[1].dst.insindex;
3882 iptr[1].opc = ICMD_NOP;
3884 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3887 COUNT(count_pcmd_bra);
3890 iptr->opc = ICMD_IF_DCMPNE;
3891 goto icmd_if_dcmpg_tail;
3893 iptr->opc = ICMD_IF_DCMPG_LT;
3894 goto icmd_if_dcmpg_tail;
3896 iptr->opc = ICMD_IF_DCMPG_GT;
3897 goto icmd_if_dcmpg_tail;
3899 iptr->opc = ICMD_IF_DCMPG_LE;
3900 goto icmd_if_dcmpg_tail;
3902 iptr->opc = ICMD_IF_DCMPG_GE;
3903 goto icmd_if_dcmpg_tail;
3910 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3915 COUNT(count_pcmd_op);
3916 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3921 COUNT(count_pcmd_op);
3922 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3931 case ICMD_INT2SHORT:
3932 COUNT(count_pcmd_op);
3933 OP1_1(TYPE_INT, TYPE_INT);
3936 COUNT(count_pcmd_op);
3937 OP1_1(TYPE_LNG, TYPE_LNG);
3940 COUNT(count_pcmd_op);
3941 OP1_1(TYPE_FLT, TYPE_FLT);
3944 COUNT(count_pcmd_op);
3945 OP1_1(TYPE_DBL, TYPE_DBL);
3949 COUNT(count_pcmd_op);
3950 OP1_1(TYPE_INT, TYPE_LNG);
3953 COUNT(count_pcmd_op);
3954 OP1_1(TYPE_INT, TYPE_FLT);
3957 COUNT(count_pcmd_op);
3958 OP1_1(TYPE_INT, TYPE_DBL);
3961 COUNT(count_pcmd_op);
3962 OP1_1(TYPE_LNG, TYPE_INT);
3965 COUNT(count_pcmd_op);
3966 OP1_1(TYPE_LNG, TYPE_FLT);
3969 COUNT(count_pcmd_op);
3970 OP1_1(TYPE_LNG, TYPE_DBL);
3973 COUNT(count_pcmd_op);
3974 OP1_1(TYPE_FLT, TYPE_INT);
3977 COUNT(count_pcmd_op);
3978 OP1_1(TYPE_FLT, TYPE_LNG);
3981 COUNT(count_pcmd_op);
3982 OP1_1(TYPE_FLT, TYPE_DBL);
3985 COUNT(count_pcmd_op);
3986 OP1_1(TYPE_DBL, TYPE_INT);
3989 COUNT(count_pcmd_op);
3990 OP1_1(TYPE_DBL, TYPE_LNG);
3993 COUNT(count_pcmd_op);
3994 OP1_1(TYPE_DBL, TYPE_FLT);
3997 case ICMD_CHECKCAST:
3998 coalescing_boundary = sd.new;
3999 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4000 /* array type cast-check */
4002 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4005 if (md->memuse > rd->memuse)
4006 rd->memuse = md->memuse;
4007 if (md->argintreguse > rd->argintreguse)
4008 rd->argintreguse = md->argintreguse;
4010 /* make all stack variables saved */
4014 sd.var[copy->varnum].flags |= SAVEDVAR;
4015 copy->flags |= SAVEDVAR;
4019 OP1_1(TYPE_ADR, TYPE_ADR);
4022 case ICMD_INSTANCEOF:
4023 case ICMD_ARRAYLENGTH:
4024 coalescing_boundary = sd.new;
4025 OP1_1(TYPE_ADR, TYPE_INT);
4029 case ICMD_ANEWARRAY:
4030 coalescing_boundary = sd.new;
4031 OP1_1(TYPE_INT, TYPE_ADR);
4035 coalescing_boundary = sd.new;
4036 COUNT(count_check_null);
4037 COUNT(count_pcmd_mem);
4038 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4039 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4044 case ICMD_GETSTATIC:
4045 coalescing_boundary = sd.new;
4046 COUNT(count_pcmd_mem);
4047 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4048 OP0_1(fmiref->parseddesc.fd->type);
4052 coalescing_boundary = sd.new;
4059 assert(sd.bptr->next); /* XXX exception */
4060 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4062 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4063 tbptr->type = BBTYPE_SBR;
4065 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4069 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4071 /* We need to check for overflow right here because
4072 * the pushed value is poped afterwards */
4075 superblockend = true;
4076 /* XXX should not be marked as interface, as it does not need to be */
4077 /* allocated. Same for the invar of the target. */
4080 /* pop many push any */
4084 bte = iptr->sx.s23.s3.bte;
4088 case ICMD_INVOKESTATIC:
4089 case ICMD_INVOKESPECIAL:
4090 case ICMD_INVOKEVIRTUAL:
4091 case ICMD_INVOKEINTERFACE:
4092 COUNT(count_pcmd_met);
4094 /* Check for functions to replace with builtin
4097 if (builtintable_replace_function(iptr))
4100 INSTRUCTION_GET_METHODDESC(iptr, md);
4101 /* XXX resurrect this COUNT? */
4102 /* if (lm->flags & ACC_STATIC) */
4103 /* {COUNT(count_check_null);} */
4107 coalescing_boundary = sd.new;
4111 if (md->memuse > rd->memuse)
4112 rd->memuse = md->memuse;
4113 if (md->argintreguse > rd->argintreguse)
4114 rd->argintreguse = md->argintreguse;
4115 if (md->argfltreguse > rd->argfltreguse)
4116 rd->argfltreguse = md->argfltreguse;
4120 /* XXX optimize for <= 2 args */
4121 /* XXX not for ICMD_BUILTIN */
4122 iptr->s1.argcount = stackdepth;
4123 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4126 for (i-- ; i >= 0; i--) {
4127 iptr->sx.s23.s2.args[i] = copy->varnum;
4129 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4130 /* -> won't help anyway */
4131 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4133 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4134 /* If we pass float arguments in integer argument registers, we
4135 * are not allowed to precolor them here. Floats have to be moved
4136 * to this regs explicitly in codegen().
4137 * Only arguments that are passed by stack anyway can be precolored
4138 * (michi 2005/07/24) */
4139 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4140 (!IS_FLT_DBL_TYPE(copy->type)
4141 || md->params[i].inmemory)) {
4143 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4148 #if defined(ENABLE_INTRP)
4151 if (md->params[i].inmemory) {
4152 sd.var[copy->varnum].vv.regoff =
4153 md->params[i].regoff;
4154 sd.var[copy->varnum].flags |=
4158 if (IS_FLT_DBL_TYPE(copy->type)) {
4159 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4160 assert(0); /* XXX is this assert ok? */
4162 sd.var[copy->varnum].vv.regoff =
4163 rd->argfltregs[md->params[i].regoff];
4164 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4167 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4168 if (IS_2_WORD_TYPE(copy->type))
4169 sd.var[copy->varnum].vv.regoff =
4170 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4171 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4174 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4175 sd.var[copy->varnum].vv.regoff =
4176 rd->argintregs[md->params[i].regoff];
4179 #if defined(ENABLE_INTRP)
4180 } /* end if (!opt_intrp) */
4187 /* deal with live-through stack slots "under" the */
4189 /* XXX not for ICMD_BUILTIN */
4195 iptr->sx.s23.s2.args[i++] = copy->varnum;
4196 sd.var[copy->varnum].flags |= SAVEDVAR;
4197 copy->flags |= SAVEDVAR;
4201 /* pop the arguments */
4210 /* push the return value */
4212 if (md->returntype.type != TYPE_VOID) {
4213 GET_NEW_VAR(sd, new_index, md->returntype.type);
4214 DST(md->returntype.type, new_index);
4219 case ICMD_INLINE_START:
4220 case ICMD_INLINE_END:
4225 case ICMD_MULTIANEWARRAY:
4226 coalescing_boundary = sd.new;
4227 if (rd->argintreguse < 3)
4228 rd->argintreguse = 3;
4230 i = iptr->s1.argcount;
4234 iptr->sx.s23.s2.args = DMNEW(s4, i);
4236 #if defined(SPECIALMEMUSE)
4237 # if defined(__DARWIN__)
4238 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4239 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4241 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4242 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4245 # if defined(__I386__)
4246 if (rd->memuse < i + 3)
4247 rd->memuse = i + 3; /* n integer args spilled on stack */
4248 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4249 if (rd->memuse < i + 2)
4250 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4253 rd->memuse = i; /* n integer args spilled on stack */
4254 # endif /* defined(__I386__) */
4258 /* check INT type here? Currently typecheck does this. */
4259 iptr->sx.s23.s2.args[i] = copy->varnum;
4260 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4261 && (!IS_INOUT(copy))
4262 && (!IS_LOCALVAR(copy)) ) {
4263 copy->varkind = ARGVAR;
4264 sd.var[copy->varnum].flags |=
4265 INMEMORY & PREALLOC;
4266 #if defined(SPECIALMEMUSE)
4267 # if defined(__DARWIN__)
4268 sd.var[copy->varnum].vv.regoff = i +
4269 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4271 sd.var[copy->varnum].vv.regoff = i +
4272 LA_SIZE_IN_POINTERS + 3;
4275 # if defined(__I386__)
4276 sd.var[copy->varnum].vv.regoff = i + 3;
4277 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4278 sd.var[copy->varnum].vv.regoff = i + 2;
4280 sd.var[copy->varnum].vv.regoff = i;
4281 # endif /* defined(__I386__) */
4282 #endif /* defined(SPECIALMEMUSE) */
4287 sd.var[copy->varnum].flags |= SAVEDVAR;
4288 copy->flags |= SAVEDVAR;
4292 i = iptr->s1.argcount;
4297 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4298 DST(TYPE_ADR, new_index);
4304 new_internalerror("Unknown ICMD %d", opcode);
4310 } /* while instructions */
4312 /* stack slots at basic block end become interfaces */
4314 sd.bptr->outdepth = stackdepth;
4315 sd.bptr->outvars = DMNEW(s4, stackdepth);
4318 for (copy = curstack; copy; i--, copy = copy->prev) {
4322 /* with the new vars rd->interfaces will be removed */
4323 /* and all in and outvars have to be STACKVARS! */
4324 /* in the moment i.e. SWAP with in and out vars can */
4325 /* create an unresolvable conflict */
4332 v = sd.var + copy->varnum;
4335 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4336 /* no interface var until now for this depth and */
4338 jd->interface_map[i*5 + t].flags = v->flags;
4341 jd->interface_map[i*5 + t].flags |= v->flags;
4344 sd.bptr->outvars[i] = copy->varnum;
4347 /* check if interface slots at basic block begin must be saved */
4349 for (i=0; i<sd.bptr->indepth; ++i) {
4350 varinfo *v = sd.var + sd.bptr->invars[i];
4357 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4358 /* no interface var until now for this depth and */
4360 jd->interface_map[i*5 + t].flags = v->flags;
4363 jd->interface_map[i*5 + t].flags |= v->flags;
4368 /* store the number of this block's variables */
4370 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4372 #if defined(STACK_VERBOSE)
4373 stack_verbose_block_exit(&sd, superblockend);
4376 /* reach the following block, if any */
4379 if (!stack_reach_next_block(&sd))
4384 } while (sd.repeat && !deadcode);
4386 /* XXX reset TYPE_RET to TYPE_ADR */
4388 for (i=0; i<sd.vartop; ++i) {
4389 if (sd.var[i].type == TYPE_RET)
4390 sd.var[i].type = TYPE_ADR;
4393 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4395 ex = cd->exceptiontable;
4396 for (; ex != NULL; ex = ex->down) {
4397 if (ex->start == ex->end) {
4398 assert(ex->end->next);
4399 ex->end = ex->end->next;
4403 /* gather statistics *****************************************************/
4405 #if defined(ENABLE_STATISTICS)
4407 if (jd->basicblockcount > count_max_basic_blocks)
4408 count_max_basic_blocks = jd->basicblockcount;
4409 count_basic_blocks += jd->basicblockcount;
4410 if (jd->instructioncount > count_max_javainstr)
4411 count_max_javainstr = jd->instructioncount;
4412 count_javainstr += jd->instructioncount;
4413 if (jd->stackcount > count_upper_bound_new_stack)
4414 count_upper_bound_new_stack = jd->stackcount;
4415 if ((sd.new - jd->stack) > count_max_new_stack)
4416 count_max_new_stack = (sd.new - jd->stack);
4418 sd.bptr = jd->basicblocks;
4419 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4420 if (sd.bptr->flags > BBREACHED) {
4421 if (sd.bptr->indepth >= 10)
4422 count_block_stack[10]++;
4424 count_block_stack[sd.bptr->indepth]++;
4425 len = sd.bptr->icount;
4427 count_block_size_distribution[len]++;
4429 count_block_size_distribution[10]++;
4431 count_block_size_distribution[11]++;
4433 count_block_size_distribution[12]++;
4435 count_block_size_distribution[13]++;
4437 count_block_size_distribution[14]++;
4439 count_block_size_distribution[15]++;
4441 count_block_size_distribution[16]++;
4443 count_block_size_distribution[17]++;
4447 if (iteration_count == 1)
4448 count_analyse_iterations[0]++;
4449 else if (iteration_count == 2)
4450 count_analyse_iterations[1]++;
4451 else if (iteration_count == 3)
4452 count_analyse_iterations[2]++;
4453 else if (iteration_count == 4)
4454 count_analyse_iterations[3]++;
4456 count_analyse_iterations[4]++;
4458 if (jd->basicblockcount <= 5)
4459 count_method_bb_distribution[0]++;
4460 else if (jd->basicblockcount <= 10)
4461 count_method_bb_distribution[1]++;
4462 else if (jd->basicblockcount <= 15)
4463 count_method_bb_distribution[2]++;
4464 else if (jd->basicblockcount <= 20)
4465 count_method_bb_distribution[3]++;
4466 else if (jd->basicblockcount <= 30)
4467 count_method_bb_distribution[4]++;
4468 else if (jd->basicblockcount <= 40)
4469 count_method_bb_distribution[5]++;
4470 else if (jd->basicblockcount <= 50)
4471 count_method_bb_distribution[6]++;
4472 else if (jd->basicblockcount <= 75)
4473 count_method_bb_distribution[7]++;
4475 count_method_bb_distribution[8]++;
4477 #endif /* defined(ENABLE_STATISTICS) */
4479 /* everything's ok *******************************************************/
4483 /* goto labels for throwing verifier exceptions **************************/
4485 #if defined(ENABLE_VERIFIER)
4487 throw_stack_underflow:
4488 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4491 throw_stack_overflow:
4492 exceptions_throw_verifyerror(m, "Stack size too large");
4495 throw_stack_type_error:
4496 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4499 throw_stack_category_error:
4500 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4507 /* functions for verbose stack analysis output ********************************/
4509 #if defined(STACK_VERBOSE)
4510 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4512 printf("%c", show_jit_type_letters[v->type]);
4513 if (v->type == TYPE_RET)
4514 printf("{L%03d}", v->vv.retaddr->nr);
4518 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4520 assert(index >= 0 && index < sd->vartop);
4521 stack_verbose_show_varinfo(sd, sd->var + index);
4525 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4529 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4531 for (i=0; i<bptr->indepth; ++i) {
4534 stack_verbose_show_variable(sd, bptr->invars[i]);
4539 printf("] inlocals [");
4540 if (bptr->inlocals) {
4541 for (i=0; i<sd->localcount; ++i) {
4544 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4549 printf("] out:%d [", bptr->outdepth);
4550 if (bptr->outvars) {
4551 for (i=0; i<bptr->outdepth; ++i) {
4554 stack_verbose_show_variable(sd, bptr->outvars[i]);
4562 printf(" (clone of L%03d)", bptr->original->nr);
4564 basicblock *b = bptr->copied_to;
4566 printf(" (copied to ");
4567 for (; b; b = b->copied_to)
4568 printf("L%03d ", b->nr);
4575 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4579 printf("======================================== STACK %sANALYSE BLOCK ",
4580 (reanalyse) ? "RE-" : "");
4581 stack_verbose_show_block(sd, sd->bptr);
4584 if (sd->handlers[0]) {
4585 printf("HANDLERS: ");
4586 for (i=0; sd->handlers[i]; ++i) {
4587 printf("L%03d ", sd->handlers[i]->handler->nr);
4595 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4597 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4598 stack_verbose_show_block(sd, sd->bptr);
4605 * These are local overrides for various environment variables in Emacs.
4606 * Please do not remove this and leave it at the end of the file, where
4607 * Emacs will automagically detect them.
4608 * ---------------------------------------------------------------------
4611 * indent-tabs-mode: t
4615 * vim:noexpandtab:sw=4:ts=4: