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 5517 2006-09-15 15:52:02Z 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_OUTVAR(sp) \
165 (sd.var[(sp)->varnum].flags & OUTVAR)
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 & (OUTVAR | 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 &= ~(OUTVAR | 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; \
477 /* macros for branching / reaching basic blocks *********************/
479 #define BRANCH_TARGET(bt, tempbptr) \
481 tempbptr = BLOCK_OF((bt).insindex); \
482 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
484 if (tempbptr == NULL) \
486 (bt).block = tempbptr; \
489 #define BRANCH(tempbptr) \
490 BRANCH_TARGET(iptr->dst, tempbptr)
493 /* forward declarations *******************************************************/
495 static void stack_create_invars(stackdata_t *sd, basicblock *b,
496 stackptr curstack, int stackdepth);
497 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
499 #if defined(STACK_VERBOSE)
500 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
501 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
502 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
503 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
504 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
508 /* stack_init ******************************************************************
510 Initialized the stack analysis subsystem (called by jit_init).
512 *******************************************************************************/
514 bool stack_init(void)
520 /* stack_grow_variable_array ***************************************************
522 Grow the variable array so the given number of additional variables fits in.
525 sd...........stack analysis data
526 num..........number of additional variables
528 *******************************************************************************/
530 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
539 /* XXX avoid too many reallocations */
540 newcount = sd->varcount + num;
542 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
543 sd->varcount = newcount;
544 sd->jd->var = sd->var;
545 sd->jd->varcount = newcount;
549 /* stack_append_block **********************************************************
551 Append the given block after the last real block of the method (before
552 the pseudo-block at the end).
555 sd...........stack analysis data
556 b............the block to append
558 *******************************************************************************/
560 static void stack_append_block(stackdata_t *sd, basicblock *b)
562 #if defined(STACK_VERBOSE)
563 printf("APPENDING BLOCK L%0d\n", b->nr);
566 b->next = sd->last_real_block->next;
567 sd->last_real_block->next = b;
568 sd->last_real_block = b;
569 sd->jd->new_basicblockcount++;
573 /* stack_clone_block ***********************************************************
575 Create a copy of the given block and insert it at the end of the method.
577 CAUTION: This function does not copy the any variables or the instruction
578 list. It _does_, however, reserve space for the block's invars in the
582 sd...........stack analysis data
583 b............the block to clone
586 a pointer to the copy
588 *******************************************************************************/
590 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
594 clone = DNEW(basicblock);
597 clone->iinstr = NULL;
598 clone->inlocals = NULL;
599 clone->invars = NULL;
601 clone->original = (b->original) ? b->original : b;
602 clone->copied_to = clone->original->copied_to;
603 clone->original->copied_to = clone;
604 clone->nr = sd->m->c_debug_nr++;
606 clone->flags = BBREACHED;
608 stack_append_block(sd, clone);
610 /* allocate space for the invars of the clone */
612 stack_grow_variable_array(sd, b->indepth);
614 #if defined(STACK_VERBOSE)
615 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
622 /* stack_create_invars *********************************************************
624 Create the invars for the given basic block. Also make a copy of the locals.
627 sd...........stack analysis data
628 b............block to create the invars for
629 curstack.....current stack top
630 stackdepth...current stack depth
632 This function creates STACKDEPTH invars and sets their types to the
633 types to the types of the corresponding slot in the current stack.
635 *******************************************************************************/
637 static void stack_create_invars(stackdata_t *sd, basicblock *b,
638 stackptr curstack, int stackdepth)
645 assert(sd->vartop + stackdepth <= sd->varcount);
647 b->indepth = stackdepth;
648 b->invars = DMNEW(s4, stackdepth);
650 /* allocate the variable indices */
651 index = (sd->vartop += stackdepth);
654 for (sp = curstack; i--; sp = sp->prev) {
655 b->invars[i] = --index;
659 v->vv = sd->var[sp->varnum].vv;
660 #if defined(STACK_VERBOSE) && 0
661 printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
665 /* copy the current state of the local variables */
666 /* (one extra local is needed by the verifier) */
668 v = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
670 for (i=0; i<sd->localcount; ++i)
675 /* stack_create_invars_from_outvars ********************************************
677 Create the invars for the given basic block. Also make a copy of the locals.
678 Types are propagated from the outvars of the current block.
681 sd...........stack analysis data
682 b............block to create the invars for
684 *******************************************************************************/
686 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
692 n = sd->bptr->outdepth;
693 assert(sd->vartop + n <= sd->varcount);
696 b->invars = DMNEW(s4, n);
699 dv = sd->var + sd->vartop;
701 /* allocate the invars */
703 for (i=0; i<n; ++i, ++dv) {
704 sv = sd->var + sd->bptr->outvars[i];
705 b->invars[i] = sd->vartop++;
712 /* copy the current state of the local variables */
713 /* (one extra local is needed by the verifier) */
715 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
717 for (i=0; i<sd->localcount; ++i)
722 /* stack_check_invars **********************************************************
724 Check the current stack against the invars of the given basic block.
725 Depth and types must match.
728 sd...........stack analysis data
729 b............block which invars to check against
730 curstack.....current stack top
731 stackdepth...current stack depth
735 NULL.........a VerifyError has been thrown
737 *******************************************************************************/
739 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
740 stackptr curstack, int stackdepth)
747 #if defined(STACK_VERBOSE)
748 printf("stack_check_invars(L%03d)\n", b->nr);
751 /* find original of b */
756 #if defined(STACK_VERBOSE)
757 printf("original is L%03d\n", orig->nr);
762 if (i != stackdepth) {
763 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
770 #if defined(STACK_VERBOSE)
771 printf("checking against ");
772 stack_verbose_show_block(sd, b); printf("\n");
776 for (i = orig->indepth; i--; sp = sp->prev) {
777 if (sd->var[b->invars[i]].type != sp->type) {
778 exceptions_throw_verifyerror_for_stack(sd->m,
779 sd->var[b->invars[i]].type);
783 if (sp->type == TYPE_RET) {
784 if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
792 for (i=0; i<sd->localcount; ++i) {
793 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
794 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
803 /* XXX mark mixed type variables void */
804 /* XXX cascading collapse? */
805 #if defined(STACK_VERBOSE)
806 printf("------> using L%03d\n", b->nr);
810 } while ((b = b->copied_to) != NULL);
812 b = stack_clone_block(sd, orig);
816 stack_create_invars(sd, b, curstack, stackdepth);
821 /* stack_check_invars_from_outvars *********************************************
823 Check the outvars of the current block against the invars of the given block.
824 Depth and types must match.
827 sd...........stack analysis data
828 b............block which invars to check against
832 NULL.........a VerifyError has been thrown
834 *******************************************************************************/
836 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
844 #if defined(STACK_VERBOSE)
845 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
848 /* find original of b */
853 #if defined(STACK_VERBOSE)
854 printf("original is L%03d\n", orig->nr);
858 n = sd->bptr->outdepth;
861 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
868 #if defined(STACK_VERBOSE)
869 printf("checking against ");
870 stack_verbose_show_block(sd, b); printf("\n");
874 dv = sd->var + b->invars[0];
876 for (i=0; i<n; ++i, ++dv) {
877 sv = sd->var + sd->bptr->outvars[i];
878 if (sv->type != dv->type) {
879 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
883 if (dv->type == TYPE_RET) {
884 if (sv->vv.retaddr != dv->vv.retaddr) {
893 for (i=0; i<sd->localcount; ++i) {
894 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
895 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
904 /* XXX mark mixed type variables void */
905 /* XXX cascading collapse? */
906 #if defined(STACK_VERBOSE)
907 printf("------> using L%03d\n", b->nr);
911 } while ((b = b->copied_to) != NULL);
913 b = stack_clone_block(sd, orig);
917 stack_create_invars_from_outvars(sd, b);
922 /* stack_create_instack ********************************************************
924 Create the instack of the current basic block.
927 sd...........stack analysis data
930 the current stack top at the start of the basic block.
932 *******************************************************************************/
934 static stackptr stack_create_instack(stackdata_t *sd)
940 if ((depth = sd->bptr->indepth) == 0)
943 sp = (sd->new += depth);
947 index = sd->bptr->invars[depth];
949 sp->type = sd->var[index].type;
953 sp->varkind = STACKVAR;
957 /* return the top of the created stack */
962 /* stack_mark_reached **********************************************************
964 Mark the given block reached and propagate the current stack and locals to
965 it. This function specializes the target block, if necessary, and returns
966 a pointer to the specialized target.
969 sd...........stack analysis data
970 b............the block to reach
971 curstack.....the current stack top
972 stackdepth...the current stack depth
975 a pointer to (a specialized version of) the target
976 NULL.........a VerifyError has been thrown
978 *******************************************************************************/
980 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
982 #if defined(STACK_VERBOSE)
983 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
985 /* mark targets of backward branches */
987 b->bitflags |= BBFLAG_REPLACEMENT;
989 if (b->flags < BBREACHED) {
990 /* b is reached for the first time. Create its invars. */
992 #if defined(STACK_VERBOSE)
993 printf("reached L%03d for the first time\n", b->nr);
996 stack_create_invars(sd, b, curstack, stackdepth);
998 b->flags = BBREACHED;
1003 /* b has been reached before. Check that its invars match. */
1005 return stack_check_invars(sd, b, curstack, stackdepth);
1010 /* stack_mark_reached_from_outvars *********************************************
1012 Mark the given block reached and propagate the outvars of the current block
1013 and the current locals to it. This function specializes the target block,
1014 if necessary, and returns a pointer to the specialized target.
1017 sd...........stack analysis data
1018 b............the block to reach
1021 a pointer to (a specialized version of) the target
1022 NULL.........a VerifyError has been thrown
1024 *******************************************************************************/
1026 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1028 #if defined(STACK_VERBOSE)
1029 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1031 /* mark targets of backward branches */
1033 b->bitflags |= BBFLAG_REPLACEMENT;
1035 if (b->flags < BBREACHED) {
1036 /* b is reached for the first time. Create its invars. */
1038 #if defined(STACK_VERBOSE)
1039 printf("reached L%03d for the first time\n", b->nr);
1042 stack_create_invars_from_outvars(sd, b);
1044 b->flags = BBREACHED;
1049 /* b has been reached before. Check that its invars match. */
1051 return stack_check_invars_from_outvars(sd, b);
1056 /* stack_reach_next_block ******************************************************
1058 Mark the following block reached and propagate the outvars of the current block
1059 and the current locals to it. This function specializes the target block,
1060 if necessary, and returns a pointer to the specialized target.
1063 sd...........stack analysis data
1066 a pointer to (a specialized version of) the following block
1067 NULL.........a VerifyError has been thrown
1069 *******************************************************************************/
1071 static bool stack_reach_next_block(stackdata_t *sd)
1076 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1077 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1081 if (tbptr != sd->bptr->next) {
1082 #if defined(STACK_VERBOSE)
1083 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1085 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1086 assert(iptr->opc == ICMD_NOP);
1087 iptr->opc = ICMD_GOTO;
1088 iptr->dst.block = tbptr;
1090 if (tbptr->flags < BBFINISHED)
1091 sd->repeat = true; /* XXX check if we really need to repeat */
1098 /* stack_reach_handlers ********************************************************
1100 Reach the exception handlers for the current block.
1103 sd...........stack analysis data
1106 true.........everything ok
1107 false........a VerifyError has been thrown
1109 *******************************************************************************/
1111 static bool stack_reach_handlers(stackdata_t *sd)
1116 #if defined(STACK_VERBOSE)
1117 printf("reaching exception handlers...\n");
1120 for (i=0; sd->handlers[i]; ++i) {
1121 tbptr = sd->handlers[i]->handler;
1123 tbptr->type = BBTYPE_EXH;
1124 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1126 /* reach (and specialize) the handler block */
1128 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1133 sd->handlers[i]->handler = tbptr;
1140 /* stack_reanalyse_block ******************************************************
1142 Re-analyse the current block. This is called if either the block itself
1143 has already been analysed before, or the current block is a clone of an
1144 already analysed block, and this clone is reached for the first time.
1145 In the latter case, this function does all that is necessary for fully
1146 cloning the block (cloning the instruction list and variables, etc.).
1149 sd...........stack analysis data
1152 true.........everything ok
1153 false........a VerifyError has been thrown
1155 *******************************************************************************/
1157 #define RELOCATE(index) \
1159 if ((index) >= blockvarstart) \
1160 (index) += blockvarshift; \
1161 else if ((index) >= invarstart) \
1162 (index) += invarshift; \
1165 bool stack_reanalyse_block(stackdata_t *sd)
1177 branch_target_t *table;
1178 lookup_target_t *lookup;
1181 bool cloneinstructions;
1184 #if defined(STACK_VERBOSE)
1185 stack_verbose_block_enter(sd, true);
1192 assert(orig != NULL);
1194 /* clone the instruction list */
1196 cloneinstructions = true;
1198 assert(orig->iinstr);
1200 iptr = DMNEW(instruction, len + 1);
1202 MCOPY(iptr, orig->iinstr, instruction, len);
1203 iptr[len].opc = ICMD_NOP;
1207 /* allocate space for the clone's block variables */
1209 stack_grow_variable_array(sd, orig->varcount);
1211 /* we already have the invars set */
1213 assert(b->indepth == orig->indepth);
1215 /* calculate relocation shifts for invars and block variables */
1217 if (orig->indepth) {
1218 invarstart = orig->invars[0];
1219 invarshift = b->invars[0] - invarstart;
1222 invarstart = INT_MAX;
1225 blockvarstart = orig->varstart;
1226 blockvarshift = sd->vartop - blockvarstart;
1228 /* copy block variables */
1230 b->varstart = sd->vartop;
1231 b->varcount = orig->varcount;
1232 sd->vartop += b->varcount;
1233 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1237 b->outdepth = orig->outdepth;
1238 b->outvars = DMNEW(s4, orig->outdepth);
1239 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1241 /* clone exception handlers */
1243 for (i=0; sd->handlers[i]; ++i) {
1244 ex = DNEW(exceptiontable);
1245 ex->handler = sd->handlers[i]->handler;
1247 ex->end = b; /* XXX hack, see end of new_stack_analyse */
1248 ex->catchtype = sd->handlers[i]->catchtype;
1251 assert(sd->extableend->down == NULL);
1252 sd->extableend->down = ex;
1253 sd->extableend = ex;
1254 sd->jd->cd->exceptiontablelength++;
1256 sd->handlers[i] = ex;
1260 cloneinstructions = false;
1263 invarstart = sd->vartop;
1264 blockvarstart = sd->vartop;
1269 /* find exception handlers for the cloned block */
1271 ex = sd->jd->cd->exceptiontable;
1272 for (; ex != NULL; ex = ex->down) {
1273 /* XXX the cloned exception handlers have identical */
1274 /* start end end blocks. */
1275 if ((ex->start == b) && (ex->end == b)) {
1276 sd->handlers[len++] = ex;
1279 sd->handlers[len] = NULL;
1282 #if defined(STACK_VERBOSE)
1283 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1284 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1287 /* mark block as finished */
1289 b->flags = BBFINISHED;
1291 /* initialize locals at the start of this block */
1294 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1296 /* reach exception handlers for this block */
1298 if (!stack_reach_handlers(sd))
1301 superblockend = false;
1303 for (len = b->icount; len--; iptr++) {
1304 #if defined(STACK_VERBOSE)
1305 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1311 switch (iptr->opc) {
1313 j = iptr->s1.varindex;
1315 if (sd->var[j].type != TYPE_RET) {
1316 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1320 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1321 superblockend = true;
1325 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1326 superblockend = true;
1330 superblockend = true;
1333 case ICMD_CHECKNULL:
1334 case ICMD_PUTSTATICCONST:
1340 case ICMD_INLINE_START:
1341 case ICMD_INLINE_END:
1342 case ICMD_INLINE_GOTO:
1346 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1347 superblockend = true;
1350 /* pop 0 push 1 const */
1359 /* pop 0 push 1 load */
1366 RELOCATE(iptr->dst.varindex);
1379 RELOCATE(iptr->sx.s23.s2.varindex);
1380 RELOCATE(iptr->s1.varindex);
1381 RELOCATE(iptr->dst.varindex);
1395 RELOCATE(iptr->sx.s23.s3.varindex);
1396 RELOCATE(iptr->sx.s23.s2.varindex);
1397 RELOCATE(iptr->s1.varindex);
1401 /* pop 1 push 0 store */
1408 RELOCATE(iptr->s1.varindex);
1410 j = iptr->dst.varindex;
1411 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1423 RELOCATE(iptr->s1.varindex);
1424 superblockend = true;
1427 case ICMD_PUTSTATIC:
1428 case ICMD_PUTFIELDCONST:
1431 RELOCATE(iptr->s1.varindex);
1434 /* pop 1 push 0 branch */
1437 case ICMD_IFNONNULL:
1452 RELOCATE(iptr->s1.varindex);
1453 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1456 /* pop 1 push 0 table branch */
1458 case ICMD_TABLESWITCH:
1459 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1461 if (cloneinstructions) {
1462 table = DMNEW(branch_target_t, i);
1463 MCOPY(table, iptr->dst.table, branch_target_t, i);
1464 iptr->dst.table = table;
1467 table = iptr->dst.table;
1470 RELOCATE(iptr->s1.varindex);
1472 table->block = stack_mark_reached_from_outvars(sd, table->block);
1475 superblockend = true;
1478 case ICMD_LOOKUPSWITCH:
1479 i = iptr->sx.s23.s2.lookupcount;
1480 if (cloneinstructions) {
1481 lookup = DMNEW(lookup_target_t, i);
1482 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1483 iptr->dst.lookup = lookup;
1486 lookup = iptr->dst.lookup;
1488 RELOCATE(iptr->s1.varindex);
1490 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1493 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1494 superblockend = true;
1497 case ICMD_MONITORENTER:
1498 case ICMD_MONITOREXIT:
1499 RELOCATE(iptr->s1.varindex);
1503 /* pop 2 push 0 branch */
1505 case ICMD_IF_ICMPEQ:
1506 case ICMD_IF_ICMPNE:
1507 case ICMD_IF_ICMPLT:
1508 case ICMD_IF_ICMPGE:
1509 case ICMD_IF_ICMPGT:
1510 case ICMD_IF_ICMPLE:
1512 case ICMD_IF_LCMPEQ:
1513 case ICMD_IF_LCMPNE:
1514 case ICMD_IF_LCMPLT:
1515 case ICMD_IF_LCMPGE:
1516 case ICMD_IF_LCMPGT:
1517 case ICMD_IF_LCMPLE:
1519 case ICMD_IF_FCMPEQ:
1520 case ICMD_IF_FCMPNE:
1522 case ICMD_IF_FCMPL_LT:
1523 case ICMD_IF_FCMPL_GE:
1524 case ICMD_IF_FCMPL_GT:
1525 case ICMD_IF_FCMPL_LE:
1527 case ICMD_IF_FCMPG_LT:
1528 case ICMD_IF_FCMPG_GE:
1529 case ICMD_IF_FCMPG_GT:
1530 case ICMD_IF_FCMPG_LE:
1532 case ICMD_IF_DCMPEQ:
1533 case ICMD_IF_DCMPNE:
1535 case ICMD_IF_DCMPL_LT:
1536 case ICMD_IF_DCMPL_GE:
1537 case ICMD_IF_DCMPL_GT:
1538 case ICMD_IF_DCMPL_LE:
1540 case ICMD_IF_DCMPG_LT:
1541 case ICMD_IF_DCMPG_GE:
1542 case ICMD_IF_DCMPG_GT:
1543 case ICMD_IF_DCMPG_LE:
1545 case ICMD_IF_ACMPEQ:
1546 case ICMD_IF_ACMPNE:
1547 RELOCATE(iptr->sx.s23.s2.varindex);
1548 RELOCATE(iptr->s1.varindex);
1549 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1555 case ICMD_IASTORECONST:
1556 case ICMD_LASTORECONST:
1557 case ICMD_AASTORECONST:
1558 case ICMD_BASTORECONST:
1559 case ICMD_CASTORECONST:
1560 case ICMD_SASTORECONST:
1563 RELOCATE(iptr->sx.s23.s2.varindex);
1564 RELOCATE(iptr->s1.varindex);
1567 /* pop 0 push 1 copy */
1571 RELOCATE(iptr->dst.varindex);
1572 RELOCATE(iptr->s1.varindex);
1573 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1616 RELOCATE(iptr->sx.s23.s2.varindex);
1617 RELOCATE(iptr->s1.varindex);
1618 RELOCATE(iptr->dst.varindex);
1623 case ICMD_CHECKCAST:
1624 case ICMD_ARRAYLENGTH:
1625 case ICMD_INSTANCEOF:
1627 case ICMD_ANEWARRAY:
1630 case ICMD_IADDCONST:
1631 case ICMD_ISUBCONST:
1632 case ICMD_IMULCONST:
1636 case ICMD_IANDCONST:
1638 case ICMD_IXORCONST:
1639 case ICMD_ISHLCONST:
1640 case ICMD_ISHRCONST:
1641 case ICMD_IUSHRCONST:
1642 case ICMD_LADDCONST:
1643 case ICMD_LSUBCONST:
1644 case ICMD_LMULCONST:
1648 case ICMD_LANDCONST:
1650 case ICMD_LXORCONST:
1651 case ICMD_LSHLCONST:
1652 case ICMD_LSHRCONST:
1653 case ICMD_LUSHRCONST:
1657 case ICMD_INT2SHORT:
1673 RELOCATE(iptr->s1.varindex);
1674 RELOCATE(iptr->dst.varindex);
1679 case ICMD_GETSTATIC:
1682 RELOCATE(iptr->dst.varindex);
1685 /* pop many push any */
1687 case ICMD_INVOKESTATIC:
1688 case ICMD_INVOKESPECIAL:
1689 case ICMD_INVOKEVIRTUAL:
1690 case ICMD_INVOKEINTERFACE:
1692 case ICMD_MULTIANEWARRAY:
1693 i = iptr->s1.argcount;
1694 if (cloneinstructions) {
1695 argp = DMNEW(s4, i);
1696 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1697 iptr->sx.s23.s2.args = argp;
1700 argp = iptr->sx.s23.s2.args;
1708 RELOCATE(iptr->dst.varindex);
1713 new_internalerror("Unknown ICMD %d during stack re-analysis",
1718 #if defined(STACK_VERBOSE)
1719 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1724 /* relocate outvars */
1726 for (i=0; i<b->outdepth; ++i) {
1727 RELOCATE(b->outvars[i]);
1730 #if defined(STACK_VERBOSE)
1731 stack_verbose_block_exit(sd, superblockend);
1734 /* propagate to the next block */
1737 if (!stack_reach_next_block(sd))
1744 /* stack_analyse ***************************************************************
1746 Analyse_stack uses the intermediate code created by parse.c to
1747 build a model of the JVM operand stack for the current method.
1749 The following checks are performed:
1750 - check for operand stack underflow (before each instruction)
1751 - check for operand stack overflow (after[1] each instruction)
1752 - check for matching stack depth at merging points
1753 - check for matching basic types[2] at merging points
1754 - check basic types for instruction input (except for BUILTIN*
1755 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1757 [1]) Checking this after the instruction should be ok. parse.c
1758 counts the number of required stack slots in such a way that it is
1759 only vital that we don't exceed `maxstack` at basic block
1762 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1763 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1764 types are not discerned.
1766 *******************************************************************************/
1768 bool new_stack_analyse(jitdata *jd)
1770 methodinfo *m; /* method being analyzed */
1775 #if defined(ENABLE_SSA)
1778 int b_index; /* basic block index */
1780 stackptr curstack; /* current stack top */
1782 int opcode; /* opcode of current instruction */
1785 int len; /* # of instructions after the current one */
1786 bool superblockend; /* if true, no fallthrough to next block */
1787 bool deadcode; /* true if no live code has been reached */
1788 instruction *iptr; /* the current instruction */
1790 basicblock *original;
1793 stackptr *last_store_boundary;
1794 stackptr coalescing_boundary;
1796 stackptr src1, src2, src3, src4, dst1, dst2;
1798 branch_target_t *table;
1799 lookup_target_t *lookup;
1800 #if defined(ENABLE_VERIFIER)
1801 int expectedtype; /* used by CHECK_BASIC_TYPE */
1803 builtintable_entry *bte;
1805 constant_FMIref *fmiref;
1806 #if defined(ENABLE_STATISTICS)
1807 int iteration_count; /* number of iterations of analysis */
1809 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1811 #if defined(STACK_VERBOSE)
1812 new_show_method(jd, SHOW_PARSE);
1815 /* get required compiler data - initialization */
1821 #if defined(ENABLE_SSA)
1825 /* initialize the stackdata_t struct */
1829 sd.varcount = jd->varcount;
1830 sd.vartop = jd->vartop;
1831 sd.localcount = jd->localcount;
1833 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1834 sd.exstack.type = TYPE_ADR;
1835 sd.exstack.prev = NULL;
1836 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1838 #if defined(ENABLE_LSRA)
1839 m->maxlifetimes = 0;
1842 #if defined(ENABLE_STATISTICS)
1843 iteration_count = 0;
1846 /* find the last real basic block */
1848 sd.last_real_block = NULL;
1849 tbptr = jd->new_basicblocks;
1850 while (tbptr->next) {
1851 sd.last_real_block = tbptr;
1852 tbptr = tbptr->next;
1854 assert(sd.last_real_block);
1856 /* find the last exception handler */
1858 if (cd->exceptiontablelength)
1859 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1861 sd.extableend = NULL;
1863 /* init jd->interface_map */
1865 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1866 for (i = 0; i < m->maxstack * 5; i++)
1867 jd->interface_map[i].flags = UNUSED;
1869 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1871 /* initialize flags and invars (none) of first block */
1873 jd->new_basicblocks[0].flags = BBREACHED;
1874 jd->new_basicblocks[0].invars = NULL;
1875 jd->new_basicblocks[0].indepth = 0;
1876 jd->new_basicblocks[0].inlocals =
1877 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
1878 MCOPY(jd->new_basicblocks[0].inlocals, jd->var, varinfo,
1879 jd->localcount + VERIFIER_EXTRA_LOCALS);
1881 /* stack analysis loop (until fixpoint reached) **************************/
1884 #if defined(ENABLE_STATISTICS)
1888 /* initialize loop over basic blocks */
1890 sd.bptr = jd->new_basicblocks;
1891 superblockend = true;
1893 curstack = NULL; stackdepth = 0;
1896 /* iterate over basic blocks *****************************************/
1898 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1900 if (sd.bptr->flags == BBDELETED) {
1901 /* This block has been deleted - do nothing. */
1906 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1907 /* This block has not been reached so far, and we */
1908 /* don't fall into it, so we'll have to iterate again. */
1914 if (sd.bptr->flags > BBREACHED) {
1915 /* This block is already finished. */
1917 superblockend = true;
1921 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1922 /* This block is a clone and the original has not been */
1923 /* analysed, yet. Analyse it on the next iteration. */
1929 /* This block has to be analysed now. */
1931 /* XXX The rest of this block is still indented one level too */
1932 /* much in order to avoid a giant diff by changing that. */
1934 /* We know that sd.bptr->flags == BBREACHED. */
1935 /* This block has been reached before. */
1937 assert(sd.bptr->flags == BBREACHED);
1938 stackdepth = sd.bptr->indepth;
1940 /* find exception handlers for this block */
1942 /* determine the active exception handlers for this block */
1943 /* XXX could use a faster algorithm with sorted lists or */
1946 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1949 ex = cd->exceptiontable;
1950 for (; ex != NULL; ex = ex->down) {
1951 if ((ex->start <= original) && (ex->end > original)) {
1952 sd.handlers[len++] = ex;
1955 sd.handlers[len] = NULL;
1958 /* reanalyse cloned block */
1960 if (sd.bptr->original) {
1961 if (!stack_reanalyse_block(&sd))
1966 /* reset the new pointer for allocating stackslots */
1968 sd.new = jd->new_stack;
1970 /* create the instack of this block */
1972 curstack = stack_create_instack(&sd);
1974 /* initialize locals at the start of this block */
1976 if (sd.bptr->inlocals)
1977 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1979 /* set up local variables for analyzing this block */
1982 superblockend = false;
1983 len = sd.bptr->icount;
1984 iptr = sd.bptr->iinstr;
1985 b_index = sd.bptr - jd->new_basicblocks;
1987 /* mark the block as analysed */
1989 sd.bptr->flags = BBFINISHED;
1991 /* reset variables for dependency checking */
1993 coalescing_boundary = sd.new;
1994 for( i = 0; i < cd->maxlocals; i++)
1995 last_store_boundary[i] = sd.new;
1997 /* remember the start of this block's variables */
1999 sd.bptr->varstart = sd.vartop;
2001 #if defined(STACK_VERBOSE)
2002 stack_verbose_block_enter(&sd, false);
2005 /* reach exception handlers for this block */
2007 if (!stack_reach_handlers(&sd))
2010 /* iterate over ICMDs ****************************************/
2012 while (--len >= 0) {
2014 #if defined(STACK_VERBOSE)
2015 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2016 for( copy = curstack; copy; copy = copy->prev ) {
2017 printf("%2d(%d", copy->varnum, copy->type);
2018 if (IS_OUTVAR(copy))
2020 if (IS_PREALLOC(copy))
2027 /* fetch the current opcode */
2031 /* automatically replace some ICMDs with builtins */
2033 #if defined(USEBUILTINTABLE)
2035 bte = builtintable_get_automatic(opcode);
2037 if (bte && bte->opcode == opcode) {
2038 iptr->opc = ICMD_BUILTIN;
2039 iptr->flags.bits = 0;
2040 iptr->sx.s23.s3.bte = bte;
2041 /* iptr->line is already set */
2042 jd->isleafmethod = false;
2046 #endif /* defined(USEBUILTINTABLE) */
2048 /* main opcode switch *************************************/
2060 case ICMD_CHECKNULL:
2061 coalescing_boundary = sd.new;
2062 COUNT(count_check_null);
2065 CLR_DST; /* XXX live through? */
2069 j = iptr->s1.varindex =
2070 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2072 if (sd.var[j].type != TYPE_RET) {
2073 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2079 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2081 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
2083 superblockend = true;
2087 COUNT(count_pcmd_return);
2090 superblockend = true;
2094 /* pop 0 push 1 const */
2096 /************************** ICONST OPTIMIZATIONS **************************/
2099 COUNT(count_pcmd_load);
2103 switch (iptr[1].opc) {
2105 iptr->opc = ICMD_IADDCONST;
2109 iptr[1].opc = ICMD_NOP;
2110 OP1_1(TYPE_INT, TYPE_INT);
2111 COUNT(count_pcmd_op);
2115 iptr->opc = ICMD_ISUBCONST;
2116 goto icmd_iconst_tail;
2117 #if SUPPORT_CONST_MUL
2119 iptr->opc = ICMD_IMULCONST;
2120 goto icmd_iconst_tail;
2121 #else /* SUPPORT_CONST_MUL */
2123 if (iptr->sx.val.i == 0x00000002)
2125 else if (iptr->sx.val.i == 0x00000004)
2127 else if (iptr->sx.val.i == 0x00000008)
2129 else if (iptr->sx.val.i == 0x00000010)
2131 else if (iptr->sx.val.i == 0x00000020)
2133 else if (iptr->sx.val.i == 0x00000040)
2135 else if (iptr->sx.val.i == 0x00000080)
2137 else if (iptr->sx.val.i == 0x00000100)
2139 else if (iptr->sx.val.i == 0x00000200)
2141 else if (iptr->sx.val.i == 0x00000400)
2142 iptr->sx.val.i = 10;
2143 else if (iptr->sx.val.i == 0x00000800)
2144 iptr->sx.val.i = 11;
2145 else if (iptr->sx.val.i == 0x00001000)
2146 iptr->sx.val.i = 12;
2147 else if (iptr->sx.val.i == 0x00002000)
2148 iptr->sx.val.i = 13;
2149 else if (iptr->sx.val.i == 0x00004000)
2150 iptr->sx.val.i = 14;
2151 else if (iptr->sx.val.i == 0x00008000)
2152 iptr->sx.val.i = 15;
2153 else if (iptr->sx.val.i == 0x00010000)
2154 iptr->sx.val.i = 16;
2155 else if (iptr->sx.val.i == 0x00020000)
2156 iptr->sx.val.i = 17;
2157 else if (iptr->sx.val.i == 0x00040000)
2158 iptr->sx.val.i = 18;
2159 else if (iptr->sx.val.i == 0x00080000)
2160 iptr->sx.val.i = 19;
2161 else if (iptr->sx.val.i == 0x00100000)
2162 iptr->sx.val.i = 20;
2163 else if (iptr->sx.val.i == 0x00200000)
2164 iptr->sx.val.i = 21;
2165 else if (iptr->sx.val.i == 0x00400000)
2166 iptr->sx.val.i = 22;
2167 else if (iptr->sx.val.i == 0x00800000)
2168 iptr->sx.val.i = 23;
2169 else if (iptr->sx.val.i == 0x01000000)
2170 iptr->sx.val.i = 24;
2171 else if (iptr->sx.val.i == 0x02000000)
2172 iptr->sx.val.i = 25;
2173 else if (iptr->sx.val.i == 0x04000000)
2174 iptr->sx.val.i = 26;
2175 else if (iptr->sx.val.i == 0x08000000)
2176 iptr->sx.val.i = 27;
2177 else if (iptr->sx.val.i == 0x10000000)
2178 iptr->sx.val.i = 28;
2179 else if (iptr->sx.val.i == 0x20000000)
2180 iptr->sx.val.i = 29;
2181 else if (iptr->sx.val.i == 0x40000000)
2182 iptr->sx.val.i = 30;
2183 else if (iptr->sx.val.i == 0x80000000)
2184 iptr->sx.val.i = 31;
2188 iptr->opc = ICMD_IMULPOW2;
2189 goto icmd_iconst_tail;
2190 #endif /* SUPPORT_CONST_MUL */
2192 if (iptr->sx.val.i == 0x00000002)
2194 else if (iptr->sx.val.i == 0x00000004)
2196 else if (iptr->sx.val.i == 0x00000008)
2198 else if (iptr->sx.val.i == 0x00000010)
2200 else if (iptr->sx.val.i == 0x00000020)
2202 else if (iptr->sx.val.i == 0x00000040)
2204 else if (iptr->sx.val.i == 0x00000080)
2206 else if (iptr->sx.val.i == 0x00000100)
2208 else if (iptr->sx.val.i == 0x00000200)
2210 else if (iptr->sx.val.i == 0x00000400)
2211 iptr->sx.val.i = 10;
2212 else if (iptr->sx.val.i == 0x00000800)
2213 iptr->sx.val.i = 11;
2214 else if (iptr->sx.val.i == 0x00001000)
2215 iptr->sx.val.i = 12;
2216 else if (iptr->sx.val.i == 0x00002000)
2217 iptr->sx.val.i = 13;
2218 else if (iptr->sx.val.i == 0x00004000)
2219 iptr->sx.val.i = 14;
2220 else if (iptr->sx.val.i == 0x00008000)
2221 iptr->sx.val.i = 15;
2222 else if (iptr->sx.val.i == 0x00010000)
2223 iptr->sx.val.i = 16;
2224 else if (iptr->sx.val.i == 0x00020000)
2225 iptr->sx.val.i = 17;
2226 else if (iptr->sx.val.i == 0x00040000)
2227 iptr->sx.val.i = 18;
2228 else if (iptr->sx.val.i == 0x00080000)
2229 iptr->sx.val.i = 19;
2230 else if (iptr->sx.val.i == 0x00100000)
2231 iptr->sx.val.i = 20;
2232 else if (iptr->sx.val.i == 0x00200000)
2233 iptr->sx.val.i = 21;
2234 else if (iptr->sx.val.i == 0x00400000)
2235 iptr->sx.val.i = 22;
2236 else if (iptr->sx.val.i == 0x00800000)
2237 iptr->sx.val.i = 23;
2238 else if (iptr->sx.val.i == 0x01000000)
2239 iptr->sx.val.i = 24;
2240 else if (iptr->sx.val.i == 0x02000000)
2241 iptr->sx.val.i = 25;
2242 else if (iptr->sx.val.i == 0x04000000)
2243 iptr->sx.val.i = 26;
2244 else if (iptr->sx.val.i == 0x08000000)
2245 iptr->sx.val.i = 27;
2246 else if (iptr->sx.val.i == 0x10000000)
2247 iptr->sx.val.i = 28;
2248 else if (iptr->sx.val.i == 0x20000000)
2249 iptr->sx.val.i = 29;
2250 else if (iptr->sx.val.i == 0x40000000)
2251 iptr->sx.val.i = 30;
2252 else if (iptr->sx.val.i == 0x80000000)
2253 iptr->sx.val.i = 31;
2257 iptr->opc = ICMD_IDIVPOW2;
2258 goto icmd_iconst_tail;
2261 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2262 if ((iptr->sx.val.i == 0x00000002) ||
2263 (iptr->sx.val.i == 0x00000004) ||
2264 (iptr->sx.val.i == 0x00000008) ||
2265 (iptr->sx.val.i == 0x00000010) ||
2266 (iptr->sx.val.i == 0x00000020) ||
2267 (iptr->sx.val.i == 0x00000040) ||
2268 (iptr->sx.val.i == 0x00000080) ||
2269 (iptr->sx.val.i == 0x00000100) ||
2270 (iptr->sx.val.i == 0x00000200) ||
2271 (iptr->sx.val.i == 0x00000400) ||
2272 (iptr->sx.val.i == 0x00000800) ||
2273 (iptr->sx.val.i == 0x00001000) ||
2274 (iptr->sx.val.i == 0x00002000) ||
2275 (iptr->sx.val.i == 0x00004000) ||
2276 (iptr->sx.val.i == 0x00008000) ||
2277 (iptr->sx.val.i == 0x00010000) ||
2278 (iptr->sx.val.i == 0x00020000) ||
2279 (iptr->sx.val.i == 0x00040000) ||
2280 (iptr->sx.val.i == 0x00080000) ||
2281 (iptr->sx.val.i == 0x00100000) ||
2282 (iptr->sx.val.i == 0x00200000) ||
2283 (iptr->sx.val.i == 0x00400000) ||
2284 (iptr->sx.val.i == 0x00800000) ||
2285 (iptr->sx.val.i == 0x01000000) ||
2286 (iptr->sx.val.i == 0x02000000) ||
2287 (iptr->sx.val.i == 0x04000000) ||
2288 (iptr->sx.val.i == 0x08000000) ||
2289 (iptr->sx.val.i == 0x10000000) ||
2290 (iptr->sx.val.i == 0x20000000) ||
2291 (iptr->sx.val.i == 0x40000000) ||
2292 (iptr->sx.val.i == 0x80000000))
2294 iptr->opc = ICMD_IREMPOW2;
2295 iptr->sx.val.i -= 1;
2296 goto icmd_iconst_tail;
2299 #if SUPPORT_CONST_LOGICAL
2301 iptr->opc = ICMD_IANDCONST;
2302 goto icmd_iconst_tail;
2305 iptr->opc = ICMD_IORCONST;
2306 goto icmd_iconst_tail;
2309 iptr->opc = ICMD_IXORCONST;
2310 goto icmd_iconst_tail;
2312 #endif /* SUPPORT_CONST_LOGICAL */
2314 iptr->opc = ICMD_ISHLCONST;
2315 goto icmd_iconst_tail;
2318 iptr->opc = ICMD_ISHRCONST;
2319 goto icmd_iconst_tail;
2322 iptr->opc = ICMD_IUSHRCONST;
2323 goto icmd_iconst_tail;
2324 #if SUPPORT_LONG_SHIFT
2326 iptr->opc = ICMD_LSHLCONST;
2327 goto icmd_lconst_tail;
2330 iptr->opc = ICMD_LSHRCONST;
2331 goto icmd_lconst_tail;
2334 iptr->opc = ICMD_LUSHRCONST;
2335 goto icmd_lconst_tail;
2336 #endif /* SUPPORT_LONG_SHIFT */
2337 case ICMD_IF_ICMPEQ:
2338 iptr[1].opc = ICMD_IFEQ;
2342 /* set the constant for the following icmd */
2343 iptr[1].sx.val.i = iptr->sx.val.i;
2345 /* this instruction becomes a nop */
2346 iptr->opc = ICMD_NOP;
2349 case ICMD_IF_ICMPLT:
2350 iptr[1].opc = ICMD_IFLT;
2351 goto icmd_if_icmp_tail;
2353 case ICMD_IF_ICMPLE:
2354 iptr[1].opc = ICMD_IFLE;
2355 goto icmd_if_icmp_tail;
2357 case ICMD_IF_ICMPNE:
2358 iptr[1].opc = ICMD_IFNE;
2359 goto icmd_if_icmp_tail;
2361 case ICMD_IF_ICMPGT:
2362 iptr[1].opc = ICMD_IFGT;
2363 goto icmd_if_icmp_tail;
2365 case ICMD_IF_ICMPGE:
2366 iptr[1].opc = ICMD_IFGE;
2367 goto icmd_if_icmp_tail;
2369 #if SUPPORT_CONST_STORE
2374 IF_INTRP( goto normal_ICONST; )
2375 # if SUPPORT_CONST_STORE_ZERO_ONLY
2376 if (iptr->sx.val.i != 0)
2379 switch (iptr[1].opc) {
2381 iptr->opc = ICMD_IASTORECONST;
2382 iptr->flags.bits |= INS_FLAG_CHECK;
2385 iptr->opc = ICMD_BASTORECONST;
2386 iptr->flags.bits |= INS_FLAG_CHECK;
2389 iptr->opc = ICMD_CASTORECONST;
2390 iptr->flags.bits |= INS_FLAG_CHECK;
2393 iptr->opc = ICMD_SASTORECONST;
2394 iptr->flags.bits |= INS_FLAG_CHECK;
2398 iptr[1].opc = ICMD_NOP;
2400 /* copy the constant to s3 */
2401 /* XXX constval -> astoreconstval? */
2402 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2403 OP2_0(TYPE_ADR, TYPE_INT);
2404 COUNT(count_pcmd_op);
2407 case ICMD_PUTSTATIC:
2409 IF_INTRP( goto normal_ICONST; )
2410 # if SUPPORT_CONST_STORE_ZERO_ONLY
2411 if (iptr->sx.val.i != 0)
2414 /* XXX check field type? */
2416 /* copy the constant to s2 */
2417 /* XXX constval -> fieldconstval? */
2418 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2421 /* set the field reference (s3) */
2422 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2423 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2424 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2427 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2430 switch (iptr[1].opc) {
2431 case ICMD_PUTSTATIC:
2432 iptr->opc = ICMD_PUTSTATICCONST;
2436 iptr->opc = ICMD_PUTFIELDCONST;
2441 iptr[1].opc = ICMD_NOP;
2442 COUNT(count_pcmd_op);
2444 #endif /* SUPPORT_CONST_STORE */
2450 /* if we get here, the ICONST has been optimized */
2454 /* normal case of an unoptimized ICONST */
2458 /************************** LCONST OPTIMIZATIONS **************************/
2461 COUNT(count_pcmd_load);
2465 /* switch depending on the following instruction */
2467 switch (iptr[1].opc) {
2468 #if SUPPORT_LONG_ADD
2470 iptr->opc = ICMD_LADDCONST;
2474 /* instruction of type LONG -> LONG */
2475 iptr[1].opc = ICMD_NOP;
2476 OP1_1(TYPE_LNG, TYPE_LNG);
2477 COUNT(count_pcmd_op);
2481 iptr->opc = ICMD_LSUBCONST;
2482 goto icmd_lconst_tail;
2484 #endif /* SUPPORT_LONG_ADD */
2485 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2487 iptr->opc = ICMD_LMULCONST;
2488 goto icmd_lconst_tail;
2489 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2490 # if SUPPORT_LONG_SHIFT
2492 if (iptr->sx.val.l == 0x00000002)
2494 else if (iptr->sx.val.l == 0x00000004)
2496 else if (iptr->sx.val.l == 0x00000008)
2498 else if (iptr->sx.val.l == 0x00000010)
2500 else if (iptr->sx.val.l == 0x00000020)
2502 else if (iptr->sx.val.l == 0x00000040)
2504 else if (iptr->sx.val.l == 0x00000080)
2506 else if (iptr->sx.val.l == 0x00000100)
2508 else if (iptr->sx.val.l == 0x00000200)
2510 else if (iptr->sx.val.l == 0x00000400)
2511 iptr->sx.val.i = 10;
2512 else if (iptr->sx.val.l == 0x00000800)
2513 iptr->sx.val.i = 11;
2514 else if (iptr->sx.val.l == 0x00001000)
2515 iptr->sx.val.i = 12;
2516 else if (iptr->sx.val.l == 0x00002000)
2517 iptr->sx.val.i = 13;
2518 else if (iptr->sx.val.l == 0x00004000)
2519 iptr->sx.val.i = 14;
2520 else if (iptr->sx.val.l == 0x00008000)
2521 iptr->sx.val.i = 15;
2522 else if (iptr->sx.val.l == 0x00010000)
2523 iptr->sx.val.i = 16;
2524 else if (iptr->sx.val.l == 0x00020000)
2525 iptr->sx.val.i = 17;
2526 else if (iptr->sx.val.l == 0x00040000)
2527 iptr->sx.val.i = 18;
2528 else if (iptr->sx.val.l == 0x00080000)
2529 iptr->sx.val.i = 19;
2530 else if (iptr->sx.val.l == 0x00100000)
2531 iptr->sx.val.i = 20;
2532 else if (iptr->sx.val.l == 0x00200000)
2533 iptr->sx.val.i = 21;
2534 else if (iptr->sx.val.l == 0x00400000)
2535 iptr->sx.val.i = 22;
2536 else if (iptr->sx.val.l == 0x00800000)
2537 iptr->sx.val.i = 23;
2538 else if (iptr->sx.val.l == 0x01000000)
2539 iptr->sx.val.i = 24;
2540 else if (iptr->sx.val.l == 0x02000000)
2541 iptr->sx.val.i = 25;
2542 else if (iptr->sx.val.l == 0x04000000)
2543 iptr->sx.val.i = 26;
2544 else if (iptr->sx.val.l == 0x08000000)
2545 iptr->sx.val.i = 27;
2546 else if (iptr->sx.val.l == 0x10000000)
2547 iptr->sx.val.i = 28;
2548 else if (iptr->sx.val.l == 0x20000000)
2549 iptr->sx.val.i = 29;
2550 else if (iptr->sx.val.l == 0x40000000)
2551 iptr->sx.val.i = 30;
2552 else if (iptr->sx.val.l == 0x80000000)
2553 iptr->sx.val.i = 31;
2557 iptr->opc = ICMD_LMULPOW2;
2558 goto icmd_lconst_tail;
2559 # endif /* SUPPORT_LONG_SHIFT */
2560 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2561 #if SUPPORT_LONG_DIV_POW2
2563 if (iptr->sx.val.l == 0x00000002)
2565 else if (iptr->sx.val.l == 0x00000004)
2567 else if (iptr->sx.val.l == 0x00000008)
2569 else if (iptr->sx.val.l == 0x00000010)
2571 else if (iptr->sx.val.l == 0x00000020)
2573 else if (iptr->sx.val.l == 0x00000040)
2575 else if (iptr->sx.val.l == 0x00000080)
2577 else if (iptr->sx.val.l == 0x00000100)
2579 else if (iptr->sx.val.l == 0x00000200)
2581 else if (iptr->sx.val.l == 0x00000400)
2582 iptr->sx.val.i = 10;
2583 else if (iptr->sx.val.l == 0x00000800)
2584 iptr->sx.val.i = 11;
2585 else if (iptr->sx.val.l == 0x00001000)
2586 iptr->sx.val.i = 12;
2587 else if (iptr->sx.val.l == 0x00002000)
2588 iptr->sx.val.i = 13;
2589 else if (iptr->sx.val.l == 0x00004000)
2590 iptr->sx.val.i = 14;
2591 else if (iptr->sx.val.l == 0x00008000)
2592 iptr->sx.val.i = 15;
2593 else if (iptr->sx.val.l == 0x00010000)
2594 iptr->sx.val.i = 16;
2595 else if (iptr->sx.val.l == 0x00020000)
2596 iptr->sx.val.i = 17;
2597 else if (iptr->sx.val.l == 0x00040000)
2598 iptr->sx.val.i = 18;
2599 else if (iptr->sx.val.l == 0x00080000)
2600 iptr->sx.val.i = 19;
2601 else if (iptr->sx.val.l == 0x00100000)
2602 iptr->sx.val.i = 20;
2603 else if (iptr->sx.val.l == 0x00200000)
2604 iptr->sx.val.i = 21;
2605 else if (iptr->sx.val.l == 0x00400000)
2606 iptr->sx.val.i = 22;
2607 else if (iptr->sx.val.l == 0x00800000)
2608 iptr->sx.val.i = 23;
2609 else if (iptr->sx.val.l == 0x01000000)
2610 iptr->sx.val.i = 24;
2611 else if (iptr->sx.val.l == 0x02000000)
2612 iptr->sx.val.i = 25;
2613 else if (iptr->sx.val.l == 0x04000000)
2614 iptr->sx.val.i = 26;
2615 else if (iptr->sx.val.l == 0x08000000)
2616 iptr->sx.val.i = 27;
2617 else if (iptr->sx.val.l == 0x10000000)
2618 iptr->sx.val.i = 28;
2619 else if (iptr->sx.val.l == 0x20000000)
2620 iptr->sx.val.i = 29;
2621 else if (iptr->sx.val.l == 0x40000000)
2622 iptr->sx.val.i = 30;
2623 else if (iptr->sx.val.l == 0x80000000)
2624 iptr->sx.val.i = 31;
2628 iptr->opc = ICMD_LDIVPOW2;
2629 goto icmd_lconst_tail;
2630 #endif /* SUPPORT_LONG_DIV_POW2 */
2632 #if SUPPORT_LONG_REM_POW2
2634 if ((iptr->sx.val.l == 0x00000002) ||
2635 (iptr->sx.val.l == 0x00000004) ||
2636 (iptr->sx.val.l == 0x00000008) ||
2637 (iptr->sx.val.l == 0x00000010) ||
2638 (iptr->sx.val.l == 0x00000020) ||
2639 (iptr->sx.val.l == 0x00000040) ||
2640 (iptr->sx.val.l == 0x00000080) ||
2641 (iptr->sx.val.l == 0x00000100) ||
2642 (iptr->sx.val.l == 0x00000200) ||
2643 (iptr->sx.val.l == 0x00000400) ||
2644 (iptr->sx.val.l == 0x00000800) ||
2645 (iptr->sx.val.l == 0x00001000) ||
2646 (iptr->sx.val.l == 0x00002000) ||
2647 (iptr->sx.val.l == 0x00004000) ||
2648 (iptr->sx.val.l == 0x00008000) ||
2649 (iptr->sx.val.l == 0x00010000) ||
2650 (iptr->sx.val.l == 0x00020000) ||
2651 (iptr->sx.val.l == 0x00040000) ||
2652 (iptr->sx.val.l == 0x00080000) ||
2653 (iptr->sx.val.l == 0x00100000) ||
2654 (iptr->sx.val.l == 0x00200000) ||
2655 (iptr->sx.val.l == 0x00400000) ||
2656 (iptr->sx.val.l == 0x00800000) ||
2657 (iptr->sx.val.l == 0x01000000) ||
2658 (iptr->sx.val.l == 0x02000000) ||
2659 (iptr->sx.val.l == 0x04000000) ||
2660 (iptr->sx.val.l == 0x08000000) ||
2661 (iptr->sx.val.l == 0x10000000) ||
2662 (iptr->sx.val.l == 0x20000000) ||
2663 (iptr->sx.val.l == 0x40000000) ||
2664 (iptr->sx.val.l == 0x80000000))
2666 iptr->opc = ICMD_LREMPOW2;
2667 iptr->sx.val.l -= 1;
2668 goto icmd_lconst_tail;
2671 #endif /* SUPPORT_LONG_REM_POW2 */
2673 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2676 iptr->opc = ICMD_LANDCONST;
2677 goto icmd_lconst_tail;
2680 iptr->opc = ICMD_LORCONST;
2681 goto icmd_lconst_tail;
2684 iptr->opc = ICMD_LXORCONST;
2685 goto icmd_lconst_tail;
2686 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2688 #if SUPPORT_LONG_CMP_CONST
2690 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2693 /* switch on the instruction after LCONST - LCMP */
2695 switch (iptr[2].opc) {
2697 iptr->opc = ICMD_IF_LEQ;
2700 icmd_lconst_lcmp_tail:
2701 /* convert LCONST, LCMP, IFXX to IF_LXX */
2702 iptr->dst.insindex = iptr[2].dst.insindex;
2703 iptr[1].opc = ICMD_NOP;
2704 iptr[2].opc = ICMD_NOP;
2706 OP1_BRANCH(TYPE_LNG);
2708 COUNT(count_pcmd_bra);
2709 COUNT(count_pcmd_op);
2713 iptr->opc = ICMD_IF_LNE;
2714 goto icmd_lconst_lcmp_tail;
2717 iptr->opc = ICMD_IF_LLT;
2718 goto icmd_lconst_lcmp_tail;
2721 iptr->opc = ICMD_IF_LGT;
2722 goto icmd_lconst_lcmp_tail;
2725 iptr->opc = ICMD_IF_LLE;
2726 goto icmd_lconst_lcmp_tail;
2729 iptr->opc = ICMD_IF_LGE;
2730 goto icmd_lconst_lcmp_tail;
2734 } /* end switch on opcode after LCONST - LCMP */
2736 #endif /* SUPPORT_LONG_CMP_CONST */
2738 #if SUPPORT_CONST_STORE
2740 IF_INTRP( goto normal_LCONST; )
2741 # if SUPPORT_CONST_STORE_ZERO_ONLY
2742 if (iptr->sx.val.l != 0)
2745 #if SIZEOF_VOID_P == 4
2746 /* the constant must fit into a ptrint */
2747 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2750 /* move the constant to s3 */
2751 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2753 iptr->opc = ICMD_LASTORECONST;
2754 iptr->flags.bits |= INS_FLAG_CHECK;
2755 OP2_0(TYPE_ADR, TYPE_INT);
2757 iptr[1].opc = ICMD_NOP;
2758 COUNT(count_pcmd_op);
2761 case ICMD_PUTSTATIC:
2763 IF_INTRP( goto normal_LCONST; )
2764 # if SUPPORT_CONST_STORE_ZERO_ONLY
2765 if (iptr->sx.val.l != 0)
2768 #if SIZEOF_VOID_P == 4
2769 /* the constant must fit into a ptrint */
2770 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2773 /* XXX check field type? */
2775 /* copy the constant to s2 */
2776 /* XXX constval -> fieldconstval? */
2777 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2781 #endif /* SUPPORT_CONST_STORE */
2785 } /* end switch opcode after LCONST */
2787 /* if we get here, the LCONST has been optimized */
2791 /* the normal case of an unoptimized LCONST */
2795 /************************ END OF LCONST OPTIMIZATIONS *********************/
2798 COUNT(count_pcmd_load);
2803 COUNT(count_pcmd_load);
2807 /************************** ACONST OPTIMIZATIONS **************************/
2810 coalescing_boundary = sd.new;
2811 COUNT(count_pcmd_load);
2812 #if SUPPORT_CONST_STORE
2813 IF_INTRP( goto normal_ACONST; )
2815 /* We can only optimize if the ACONST is resolved
2816 * and there is an instruction after it. */
2818 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2821 switch (iptr[1].opc) {
2823 /* We can only optimize for NULL values
2824 * here because otherwise a checkcast is
2826 if (iptr->sx.val.anyptr != NULL)
2829 /* copy the constant (NULL) to s3 */
2830 iptr->sx.s23.s3.constval = 0;
2831 iptr->opc = ICMD_AASTORECONST;
2832 iptr->flags.bits |= INS_FLAG_CHECK;
2833 OP2_0(TYPE_ADR, TYPE_INT);
2835 iptr[1].opc = ICMD_NOP;
2836 COUNT(count_pcmd_op);
2839 case ICMD_PUTSTATIC:
2841 # if SUPPORT_CONST_STORE_ZERO_ONLY
2842 if (iptr->sx.val.anyptr != NULL)
2845 /* XXX check field type? */
2846 /* copy the constant to s2 */
2847 /* XXX constval -> fieldconstval? */
2848 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2856 /* if we get here the ACONST has been optimized */
2860 #endif /* SUPPORT_CONST_STORE */
2865 /* pop 0 push 1 load */
2872 COUNT(count_load_instruction);
2873 i = opcode - ICMD_ILOAD; /* type */
2875 j = iptr->s1.varindex =
2876 jd->local_map[iptr->s1.varindex * 5 + i];
2878 if (sd.var[j].type == TYPE_RET) {
2879 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
2883 #if defined(ENABLE_SSA)
2885 GET_NEW_VAR(sd, new_index, i);
2902 coalescing_boundary = sd.new;
2903 iptr->flags.bits |= INS_FLAG_CHECK;
2904 COUNT(count_check_null);
2905 COUNT(count_check_bound);
2906 COUNT(count_pcmd_mem);
2907 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
2914 coalescing_boundary = sd.new;
2915 iptr->flags.bits |= INS_FLAG_CHECK;
2916 COUNT(count_check_null);
2917 COUNT(count_check_bound);
2918 COUNT(count_pcmd_mem);
2919 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2922 /* pop 0 push 0 iinc */
2925 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2926 #if defined(ENABLE_SSA)
2929 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
2933 last_store_boundary[iptr->s1.varindex] = sd.new;
2936 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2941 if ((copy->varkind == LOCALVAR) &&
2942 (copy->varnum == iptr->s1.varindex))
2944 assert(IS_LOCALVAR(copy));
2950 #if defined(ENABLE_SSA)
2954 iptr->dst.varindex = iptr->s1.varindex;
2957 /* pop 1 push 0 store */
2966 i = opcode - ICMD_ISTORE; /* type */
2967 javaindex = iptr->dst.varindex;
2968 j = iptr->dst.varindex =
2969 jd->local_map[javaindex * 5 + i];
2971 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2973 #if defined(ENABLE_STATISTICS)
2976 i = sd.new - curstack;
2978 count_store_length[20]++;
2980 count_store_length[i]++;
2983 count_store_depth[10]++;
2985 count_store_depth[i]++;
2989 #if defined(ENABLE_SSA)
2992 /* check for conflicts as described in Figure 5.2 */
2994 copy = curstack->prev;
2997 if ((copy->varkind == LOCALVAR) &&
2998 (copy->varnum == j))
3000 copy->varkind = TEMPVAR;
3001 assert(IS_LOCALVAR(copy));
3008 /* if the variable is already coalesced, don't bother */
3010 /* We do not need to check against OUTVAR, as invars */
3011 /* are always before the coalescing boundary. */
3013 if (curstack->varkind == LOCALVAR)
3016 /* there is no STORE Lj while curstack is live */
3018 if (curstack < last_store_boundary[javaindex])
3019 goto assume_conflict;
3021 /* curstack must be after the coalescing boundary */
3023 if (curstack < coalescing_boundary)
3024 goto assume_conflict;
3026 /* there is no DEF LOCALVAR(j) while curstack is live */
3028 copy = sd.new; /* most recent stackslot created + 1 */
3029 while (--copy > curstack) {
3030 if (copy->varkind == LOCALVAR && copy->varnum == j)
3031 goto assume_conflict;
3034 /* coalesce the temporary variable with Lj */
3035 assert((curstack->varkind == TEMPVAR)
3036 || (curstack->varkind == UNDEFVAR));
3037 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3038 assert(!IS_OUTVAR(curstack));
3039 assert(!IS_PREALLOC(curstack));
3041 assert(curstack->creator);
3042 assert(curstack->creator->dst.varindex == curstack->varnum);
3043 RELEASE_INDEX(sd, curstack);
3044 curstack->varkind = LOCALVAR;
3045 curstack->varnum = j;
3046 curstack->creator->dst.varindex = j;
3049 /* revert the coalescing, if it has been done earlier */
3051 if ((curstack->varkind == LOCALVAR)
3052 && (curstack->varnum == j))
3054 assert(IS_LOCALVAR(curstack));
3055 SET_TEMPVAR(curstack);
3058 /* remember the stack boundary at this store */
3060 last_store_boundary[javaindex] = sd.new;
3061 #if defined(ENABLE_SSA)
3062 } /* if (ls != NULL) */
3065 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3068 STORE(opcode - ICMD_ISTORE, j);
3074 coalescing_boundary = sd.new;
3075 iptr->flags.bits |= INS_FLAG_CHECK;
3076 COUNT(count_check_null);
3077 COUNT(count_check_bound);
3078 COUNT(count_pcmd_mem);
3080 bte = builtintable_get_internal(BUILTIN_canstore);
3083 if (md->memuse > rd->memuse)
3084 rd->memuse = md->memuse;
3085 if (md->argintreguse > rd->argintreguse)
3086 rd->argintreguse = md->argintreguse;
3087 /* XXX non-leaf method? */
3089 /* make all stack variables saved */
3093 sd.var[copy->varnum].flags |= SAVEDVAR;
3094 /* in case copy->varnum is/will be a LOCALVAR */
3095 /* once and set back to a non LOCALVAR */
3096 /* the correct SAVEDVAR flag has to be */
3097 /* remembered in copy->flags, too */
3098 copy->flags |= SAVEDVAR;
3102 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3109 coalescing_boundary = sd.new;
3110 iptr->flags.bits |= INS_FLAG_CHECK;
3111 COUNT(count_check_null);
3112 COUNT(count_check_bound);
3113 COUNT(count_pcmd_mem);
3114 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3121 coalescing_boundary = sd.new;
3122 iptr->flags.bits |= INS_FLAG_CHECK;
3123 COUNT(count_check_null);
3124 COUNT(count_check_bound);
3125 COUNT(count_pcmd_mem);
3126 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3132 #ifdef ENABLE_VERIFIER
3135 if (IS_2_WORD_TYPE(curstack->type))
3136 goto throw_stack_category_error;
3147 coalescing_boundary = sd.new;
3148 /* Assert here that no LOCAL or OUTVARS get */
3149 /* preallocated, since tha macros are not */
3150 /* available in md-abi.c! */
3151 IF_JIT( if (IS_TEMPVAR(curstack)) \
3152 md_return_alloc(jd, curstack); )
3153 COUNT(count_pcmd_return);
3154 OP1_0(opcode - ICMD_IRETURN);
3155 superblockend = true;
3159 coalescing_boundary = sd.new;
3160 COUNT(count_check_null);
3162 curstack = NULL; stackdepth = 0;
3163 superblockend = true;
3166 case ICMD_PUTSTATIC:
3167 coalescing_boundary = sd.new;
3168 COUNT(count_pcmd_mem);
3169 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3170 OP1_0(fmiref->parseddesc.fd->type);
3173 /* pop 1 push 0 branch */
3176 case ICMD_IFNONNULL:
3177 COUNT(count_pcmd_bra);
3178 OP1_BRANCH(TYPE_ADR);
3188 COUNT(count_pcmd_bra);
3189 /* iptr->sx.val.i is set implicitly in parse by
3190 clearing the memory or from IF_ICMPxx
3193 OP1_BRANCH(TYPE_INT);
3194 /* iptr->sx.val.i = 0; */
3198 /* pop 0 push 0 branch */
3201 COUNT(count_pcmd_bra);
3204 superblockend = true;
3207 /* pop 1 push 0 table branch */
3209 case ICMD_TABLESWITCH:
3210 COUNT(count_pcmd_table);
3211 OP1_BRANCH(TYPE_INT);
3213 table = iptr->dst.table;
3214 BRANCH_TARGET(*table, tbptr);
3217 i = iptr->sx.s23.s3.tablehigh
3218 - iptr->sx.s23.s2.tablelow + 1;
3221 BRANCH_TARGET(*table, tbptr);
3224 superblockend = true;
3227 /* pop 1 push 0 table branch */
3229 case ICMD_LOOKUPSWITCH:
3230 COUNT(count_pcmd_table);
3231 OP1_BRANCH(TYPE_INT);
3233 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3235 lookup = iptr->dst.lookup;
3237 i = iptr->sx.s23.s2.lookupcount;
3240 BRANCH_TARGET(lookup->target, tbptr);
3243 superblockend = true;
3246 case ICMD_MONITORENTER:
3247 case ICMD_MONITOREXIT:
3248 coalescing_boundary = sd.new;
3249 COUNT(count_check_null);
3253 /* pop 2 push 0 branch */
3255 case ICMD_IF_ICMPEQ:
3256 case ICMD_IF_ICMPNE:
3257 case ICMD_IF_ICMPLT:
3258 case ICMD_IF_ICMPGE:
3259 case ICMD_IF_ICMPGT:
3260 case ICMD_IF_ICMPLE:
3261 COUNT(count_pcmd_bra);
3262 OP2_BRANCH(TYPE_INT, TYPE_INT);
3266 case ICMD_IF_ACMPEQ:
3267 case ICMD_IF_ACMPNE:
3268 COUNT(count_pcmd_bra);
3269 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3276 coalescing_boundary = sd.new;
3277 COUNT(count_check_null);
3278 COUNT(count_pcmd_mem);
3279 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3280 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3285 if (!IS_2_WORD_TYPE(curstack->type)) {
3287 #ifdef ENABLE_VERIFIER
3290 if (IS_2_WORD_TYPE(curstack->prev->type))
3291 goto throw_stack_category_error;
3294 OP2_0_ANY_ANY; /* pop two slots */
3297 iptr->opc = ICMD_POP;
3298 OP1_0_ANY; /* pop one (two-word) slot */
3302 /* pop 0 push 1 dup */
3305 #ifdef ENABLE_VERIFIER
3308 if (IS_2_WORD_TYPE(curstack->type))
3309 goto throw_stack_category_error;
3312 COUNT(count_dup_instruction);
3318 coalescing_boundary = sd.new - 1;
3323 if (IS_2_WORD_TYPE(curstack->type)) {
3325 iptr->opc = ICMD_DUP;
3330 /* ..., ????, cat1 */
3331 #ifdef ENABLE_VERIFIER
3333 if (IS_2_WORD_TYPE(curstack->prev->type))
3334 goto throw_stack_category_error;
3337 src1 = curstack->prev;
3340 COPY_UP(src1); iptr++; len--;
3343 coalescing_boundary = sd.new;
3347 /* pop 2 push 3 dup */
3350 #ifdef ENABLE_VERIFIER
3353 if (IS_2_WORD_TYPE(curstack->type) ||
3354 IS_2_WORD_TYPE(curstack->prev->type))
3355 goto throw_stack_category_error;
3360 src1 = curstack->prev;
3365 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3367 MOVE_UP(src1); iptr++; len--;
3368 MOVE_UP(src2); iptr++; len--;
3370 COPY_DOWN(curstack, dst1);
3372 coalescing_boundary = sd.new;
3377 if (IS_2_WORD_TYPE(curstack->type)) {
3378 /* ..., ????, cat2 */
3379 #ifdef ENABLE_VERIFIER
3381 if (IS_2_WORD_TYPE(curstack->prev->type))
3382 goto throw_stack_category_error;
3385 iptr->opc = ICMD_DUP_X1;
3389 /* ..., ????, cat1 */
3390 #ifdef ENABLE_VERIFIER
3393 if (IS_2_WORD_TYPE(curstack->prev->type)
3394 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3395 goto throw_stack_category_error;
3400 src1 = curstack->prev->prev;
3401 src2 = curstack->prev;
3403 POPANY; POPANY; POPANY;
3406 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3407 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3409 MOVE_UP(src1); iptr++; len--;
3410 MOVE_UP(src2); iptr++; len--;
3411 MOVE_UP(src3); iptr++; len--;
3413 COPY_DOWN(curstack, dst2); iptr++; len--;
3414 COPY_DOWN(curstack->prev, dst1);
3416 coalescing_boundary = sd.new;
3420 /* pop 3 push 4 dup */
3424 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3425 /* ..., cat2, ???? */
3426 #ifdef ENABLE_VERIFIER
3428 if (IS_2_WORD_TYPE(curstack->type))
3429 goto throw_stack_category_error;
3432 iptr->opc = ICMD_DUP_X1;
3436 /* ..., cat1, ???? */
3437 #ifdef ENABLE_VERIFIER
3440 if (IS_2_WORD_TYPE(curstack->type)
3441 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3442 goto throw_stack_category_error;
3446 src1 = curstack->prev->prev;
3447 src2 = curstack->prev;
3449 POPANY; POPANY; POPANY;
3452 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3454 MOVE_UP(src1); iptr++; len--;
3455 MOVE_UP(src2); iptr++; len--;
3456 MOVE_UP(src3); iptr++; len--;
3458 COPY_DOWN(curstack, dst1);
3460 coalescing_boundary = sd.new;
3466 if (IS_2_WORD_TYPE(curstack->type)) {
3467 /* ..., ????, cat2 */
3468 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3469 /* ..., cat2, cat2 */
3470 iptr->opc = ICMD_DUP_X1;
3474 /* ..., cat1, cat2 */
3475 #ifdef ENABLE_VERIFIER
3478 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3479 goto throw_stack_category_error;
3482 iptr->opc = ICMD_DUP_X2;
3488 /* ..., ????, ????, cat1 */
3490 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3491 /* ..., cat2, ????, cat1 */
3492 #ifdef ENABLE_VERIFIER
3494 if (IS_2_WORD_TYPE(curstack->prev->type))
3495 goto throw_stack_category_error;
3498 iptr->opc = ICMD_DUP2_X1;
3502 /* ..., cat1, ????, cat1 */
3503 #ifdef ENABLE_VERIFIER
3506 if (IS_2_WORD_TYPE(curstack->prev->type)
3507 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3508 goto throw_stack_category_error;
3512 src1 = curstack->prev->prev->prev;
3513 src2 = curstack->prev->prev;
3514 src3 = curstack->prev;
3516 POPANY; POPANY; POPANY; POPANY;
3519 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3520 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3522 MOVE_UP(src1); iptr++; len--;
3523 MOVE_UP(src2); iptr++; len--;
3524 MOVE_UP(src3); iptr++; len--;
3525 MOVE_UP(src4); iptr++; len--;
3527 COPY_DOWN(curstack, dst2); iptr++; len--;
3528 COPY_DOWN(curstack->prev, dst1);
3530 coalescing_boundary = sd.new;
3534 /* pop 2 push 2 swap */
3537 #ifdef ENABLE_VERIFIER
3540 if (IS_2_WORD_TYPE(curstack->type)
3541 || IS_2_WORD_TYPE(curstack->prev->type))
3542 goto throw_stack_category_error;
3546 src1 = curstack->prev;
3551 if (!IS_TEMPVAR(src1)) {
3552 /* move src1 out of the way into a temporary */
3553 GET_NEW_INDEX(sd, new_index);
3554 iptr->opc = ICMD_MOVE;
3555 iptr->s1.varindex = src1->varnum;
3556 iptr->dst.varindex = new_index;
3557 COPY_VAL_AND_TYPE(sd, src1->varnum, new_index);
3559 src1->varnum = new_index;
3562 MOVE_UP(src2); iptr++; len--;
3565 coalescing_boundary = sd.new;
3572 coalescing_boundary = sd.new;
3573 #if !SUPPORT_DIVISION
3574 bte = iptr->sx.s23.s3.bte;
3577 if (md->memuse > rd->memuse)
3578 rd->memuse = md->memuse;
3579 if (md->argintreguse > rd->argintreguse)
3580 rd->argintreguse = md->argintreguse;
3582 /* make all stack variables saved */
3586 sd.var[copy->varnum].flags |= SAVEDVAR;
3587 copy->flags |= SAVEDVAR;
3592 #endif /* !SUPPORT_DIVISION */
3603 COUNT(count_pcmd_op);
3604 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3609 coalescing_boundary = sd.new;
3610 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3611 bte = iptr->sx.s23.s3.bte;
3614 if (md->memuse > rd->memuse)
3615 rd->memuse = md->memuse;
3616 if (md->argintreguse > rd->argintreguse)
3617 rd->argintreguse = md->argintreguse;
3618 /* XXX non-leaf method? */
3620 /* make all stack variables saved */
3624 sd.var[copy->varnum].flags |= SAVEDVAR;
3625 copy->flags |= SAVEDVAR;
3630 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3635 #if SUPPORT_LONG_LOGICAL
3639 #endif /* SUPPORT_LONG_LOGICAL */
3640 COUNT(count_pcmd_op);
3641 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3647 COUNT(count_pcmd_op);
3648 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3656 COUNT(count_pcmd_op);
3657 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3665 COUNT(count_pcmd_op);
3666 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3670 COUNT(count_pcmd_op);
3671 #if SUPPORT_LONG_CMP_CONST
3672 if ((len == 0) || (iptr[1].sx.val.i != 0))
3675 switch (iptr[1].opc) {
3677 iptr->opc = ICMD_IF_LCMPEQ;
3679 iptr->dst.insindex = iptr[1].dst.insindex;
3680 iptr[1].opc = ICMD_NOP;
3682 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3685 COUNT(count_pcmd_bra);
3688 iptr->opc = ICMD_IF_LCMPNE;
3689 goto icmd_lcmp_if_tail;
3691 iptr->opc = ICMD_IF_LCMPLT;
3692 goto icmd_lcmp_if_tail;
3694 iptr->opc = ICMD_IF_LCMPGT;
3695 goto icmd_lcmp_if_tail;
3697 iptr->opc = ICMD_IF_LCMPLE;
3698 goto icmd_lcmp_if_tail;
3700 iptr->opc = ICMD_IF_LCMPGE;
3701 goto icmd_lcmp_if_tail;
3707 #endif /* SUPPORT_LONG_CMP_CONST */
3708 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3711 /* XXX why is this deactivated? */
3714 COUNT(count_pcmd_op);
3715 if ((len == 0) || (iptr[1].sx.val.i != 0))
3718 switch (iptr[1].opc) {
3720 iptr->opc = ICMD_IF_FCMPEQ;
3722 iptr->dst.insindex = iptr[1].dst.insindex;
3723 iptr[1].opc = ICMD_NOP;
3725 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3728 COUNT(count_pcmd_bra);
3731 iptr->opc = ICMD_IF_FCMPNE;
3732 goto icmd_if_fcmpl_tail;
3734 iptr->opc = ICMD_IF_FCMPL_LT;
3735 goto icmd_if_fcmpl_tail;
3737 iptr->opc = ICMD_IF_FCMPL_GT;
3738 goto icmd_if_fcmpl_tail;
3740 iptr->opc = ICMD_IF_FCMPL_LE;
3741 goto icmd_if_fcmpl_tail;
3743 iptr->opc = ICMD_IF_FCMPL_GE;
3744 goto icmd_if_fcmpl_tail;
3751 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3755 COUNT(count_pcmd_op);
3756 if ((len == 0) || (iptr[1].sx.val.i != 0))
3759 switch (iptr[1].opc) {
3761 iptr->opc = ICMD_IF_FCMPEQ;
3763 iptr->dst.insindex = iptr[1].dst.insindex;
3764 iptr[1].opc = ICMD_NOP;
3766 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3769 COUNT(count_pcmd_bra);
3772 iptr->opc = ICMD_IF_FCMPNE;
3773 goto icmd_if_fcmpg_tail;
3775 iptr->opc = ICMD_IF_FCMPG_LT;
3776 goto icmd_if_fcmpg_tail;
3778 iptr->opc = ICMD_IF_FCMPG_GT;
3779 goto icmd_if_fcmpg_tail;
3781 iptr->opc = ICMD_IF_FCMPG_LE;
3782 goto icmd_if_fcmpg_tail;
3784 iptr->opc = ICMD_IF_FCMPG_GE;
3785 goto icmd_if_fcmpg_tail;
3792 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3796 COUNT(count_pcmd_op);
3797 if ((len == 0) || (iptr[1].sx.val.i != 0))
3800 switch (iptr[1].opc) {
3802 iptr->opc = ICMD_IF_DCMPEQ;
3804 iptr->dst.insindex = iptr[1].dst.insindex;
3805 iptr[1].opc = ICMD_NOP;
3807 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3810 COUNT(count_pcmd_bra);
3813 iptr->opc = ICMD_IF_DCMPNE;
3814 goto icmd_if_dcmpl_tail;
3816 iptr->opc = ICMD_IF_DCMPL_LT;
3817 goto icmd_if_dcmpl_tail;
3819 iptr->opc = ICMD_IF_DCMPL_GT;
3820 goto icmd_if_dcmpl_tail;
3822 iptr->opc = ICMD_IF_DCMPL_LE;
3823 goto icmd_if_dcmpl_tail;
3825 iptr->opc = ICMD_IF_DCMPL_GE;
3826 goto icmd_if_dcmpl_tail;
3833 OPTT2_1(TYPE_DBL, TYPE_INT);
3837 COUNT(count_pcmd_op);
3838 if ((len == 0) || (iptr[1].sx.val.i != 0))
3841 switch (iptr[1].opc) {
3843 iptr->opc = ICMD_IF_DCMPEQ;
3845 iptr->dst.insindex = iptr[1].dst.insindex;
3846 iptr[1].opc = ICMD_NOP;
3848 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3851 COUNT(count_pcmd_bra);
3854 iptr->opc = ICMD_IF_DCMPNE;
3855 goto icmd_if_dcmpg_tail;
3857 iptr->opc = ICMD_IF_DCMPG_LT;
3858 goto icmd_if_dcmpg_tail;
3860 iptr->opc = ICMD_IF_DCMPG_GT;
3861 goto icmd_if_dcmpg_tail;
3863 iptr->opc = ICMD_IF_DCMPG_LE;
3864 goto icmd_if_dcmpg_tail;
3866 iptr->opc = ICMD_IF_DCMPG_GE;
3867 goto icmd_if_dcmpg_tail;
3874 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3879 COUNT(count_pcmd_op);
3880 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3885 COUNT(count_pcmd_op);
3886 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3895 case ICMD_INT2SHORT:
3896 COUNT(count_pcmd_op);
3897 OP1_1(TYPE_INT, TYPE_INT);
3900 COUNT(count_pcmd_op);
3901 OP1_1(TYPE_LNG, TYPE_LNG);
3904 COUNT(count_pcmd_op);
3905 OP1_1(TYPE_FLT, TYPE_FLT);
3908 COUNT(count_pcmd_op);
3909 OP1_1(TYPE_DBL, TYPE_DBL);
3913 COUNT(count_pcmd_op);
3914 OP1_1(TYPE_INT, TYPE_LNG);
3917 COUNT(count_pcmd_op);
3918 OP1_1(TYPE_INT, TYPE_FLT);
3921 COUNT(count_pcmd_op);
3922 OP1_1(TYPE_INT, TYPE_DBL);
3925 COUNT(count_pcmd_op);
3926 OP1_1(TYPE_LNG, TYPE_INT);
3929 COUNT(count_pcmd_op);
3930 OP1_1(TYPE_LNG, TYPE_FLT);
3933 COUNT(count_pcmd_op);
3934 OP1_1(TYPE_LNG, TYPE_DBL);
3937 COUNT(count_pcmd_op);
3938 OP1_1(TYPE_FLT, TYPE_INT);
3941 COUNT(count_pcmd_op);
3942 OP1_1(TYPE_FLT, TYPE_LNG);
3945 COUNT(count_pcmd_op);
3946 OP1_1(TYPE_FLT, TYPE_DBL);
3949 COUNT(count_pcmd_op);
3950 OP1_1(TYPE_DBL, TYPE_INT);
3953 COUNT(count_pcmd_op);
3954 OP1_1(TYPE_DBL, TYPE_LNG);
3957 COUNT(count_pcmd_op);
3958 OP1_1(TYPE_DBL, TYPE_FLT);
3961 case ICMD_CHECKCAST:
3962 coalescing_boundary = sd.new;
3963 if (iptr->flags.bits & INS_FLAG_ARRAY) {
3964 /* array type cast-check */
3966 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
3969 if (md->memuse > rd->memuse)
3970 rd->memuse = md->memuse;
3971 if (md->argintreguse > rd->argintreguse)
3972 rd->argintreguse = md->argintreguse;
3974 /* make all stack variables saved */
3978 sd.var[copy->varnum].flags |= SAVEDVAR;
3979 copy->flags |= SAVEDVAR;
3983 OP1_1(TYPE_ADR, TYPE_ADR);
3986 case ICMD_INSTANCEOF:
3987 case ICMD_ARRAYLENGTH:
3988 coalescing_boundary = sd.new;
3989 OP1_1(TYPE_ADR, TYPE_INT);
3993 case ICMD_ANEWARRAY:
3994 coalescing_boundary = sd.new;
3995 OP1_1(TYPE_INT, TYPE_ADR);
3999 coalescing_boundary = sd.new;
4000 COUNT(count_check_null);
4001 COUNT(count_pcmd_mem);
4002 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4003 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4008 case ICMD_GETSTATIC:
4009 coalescing_boundary = sd.new;
4010 COUNT(count_pcmd_mem);
4011 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4012 OP0_1(fmiref->parseddesc.fd->type);
4016 coalescing_boundary = sd.new;
4023 assert(sd.bptr->next); /* XXX exception */
4024 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4026 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4027 tbptr->type = BBTYPE_SBR;
4029 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4033 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4035 /* We need to check for overflow right here because
4036 * the pushed value is poped afterwards */
4039 superblockend = true;
4040 /* XXX should not be marked as interface, as it does not need to be */
4041 /* allocated. Same for the invar of the target. */
4044 /* pop many push any */
4048 bte = iptr->sx.s23.s3.bte;
4052 case ICMD_INVOKESTATIC:
4053 case ICMD_INVOKESPECIAL:
4054 case ICMD_INVOKEVIRTUAL:
4055 case ICMD_INVOKEINTERFACE:
4056 COUNT(count_pcmd_met);
4058 /* Check for functions to replace with builtin
4061 if (builtintable_replace_function(iptr))
4064 INSTRUCTION_GET_METHODDESC(iptr, md);
4065 /* XXX resurrect this COUNT? */
4066 /* if (lm->flags & ACC_STATIC) */
4067 /* {COUNT(count_check_null);} */
4071 coalescing_boundary = sd.new;
4075 if (md->memuse > rd->memuse)
4076 rd->memuse = md->memuse;
4077 if (md->argintreguse > rd->argintreguse)
4078 rd->argintreguse = md->argintreguse;
4079 if (md->argfltreguse > rd->argfltreguse)
4080 rd->argfltreguse = md->argfltreguse;
4084 /* XXX optimize for <= 2 args */
4085 /* XXX not for ICMD_BUILTIN */
4086 iptr->s1.argcount = stackdepth;
4087 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4090 for (i-- ; i >= 0; i--) {
4091 iptr->sx.s23.s2.args[i] = copy->varnum;
4093 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4094 /* -> won't help anyway */
4095 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
4097 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4098 /* If we pass float arguments in integer argument registers, we
4099 * are not allowed to precolor them here. Floats have to be moved
4100 * to this regs explicitly in codegen().
4101 * Only arguments that are passed by stack anyway can be precolored
4102 * (michi 2005/07/24) */
4103 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4104 (!IS_FLT_DBL_TYPE(copy->type)
4105 || md->params[i].inmemory)) {
4107 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4112 #if defined(ENABLE_INTRP)
4115 if (md->params[i].inmemory) {
4116 sd.var[copy->varnum].vv.regoff =
4117 md->params[i].regoff;
4118 sd.var[copy->varnum].flags |=
4122 if (IS_FLT_DBL_TYPE(copy->type)) {
4123 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4124 assert(0); /* XXX is this assert ok? */
4126 sd.var[copy->varnum].vv.regoff =
4127 rd->argfltregs[md->params[i].regoff];
4128 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4131 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4132 if (IS_2_WORD_TYPE(copy->type))
4133 sd.var[copy->varnum].vv.regoff =
4134 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4135 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4138 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4139 sd.var[copy->varnum].vv.regoff =
4140 rd->argintregs[md->params[i].regoff];
4143 #if defined(ENABLE_INTRP)
4144 } /* end if (!opt_intrp) */
4151 /* deal with live-through stack slots "under" the */
4153 /* XXX not for ICMD_BUILTIN */
4159 iptr->sx.s23.s2.args[i++] = copy->varnum;
4160 sd.var[copy->varnum].flags |= SAVEDVAR;
4161 copy->flags |= SAVEDVAR;
4165 /* pop the arguments */
4174 /* push the return value */
4176 if (md->returntype.type != TYPE_VOID) {
4177 GET_NEW_VAR(sd, new_index, md->returntype.type);
4178 DST(md->returntype.type, new_index);
4183 case ICMD_INLINE_START:
4184 case ICMD_INLINE_END:
4189 case ICMD_MULTIANEWARRAY:
4190 coalescing_boundary = sd.new;
4191 if (rd->argintreguse < 3)
4192 rd->argintreguse = 3;
4194 i = iptr->s1.argcount;
4198 iptr->sx.s23.s2.args = DMNEW(s4, i);
4200 #if defined(SPECIALMEMUSE)
4201 # if defined(__DARWIN__)
4202 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4203 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4205 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4206 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4209 # if defined(__I386__)
4210 if (rd->memuse < i + 3)
4211 rd->memuse = i + 3; /* n integer args spilled on stack */
4212 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4213 if (rd->memuse < i + 2)
4214 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4217 rd->memuse = i; /* n integer args spilled on stack */
4218 # endif /* defined(__I386__) */
4222 /* check INT type here? Currently typecheck does this. */
4223 iptr->sx.s23.s2.args[i] = copy->varnum;
4224 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4225 && (!IS_OUTVAR(copy))
4226 && (!IS_LOCALVAR(copy)) ) {
4227 copy->varkind = ARGVAR;
4228 sd.var[copy->varnum].flags |=
4229 INMEMORY & PREALLOC;
4230 #if defined(SPECIALMEMUSE)
4231 # if defined(__DARWIN__)
4232 sd.var[copy->varnum].vv.regoff = i +
4233 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4235 sd.var[copy->varnum].vv.regoff = i +
4236 LA_SIZE_IN_POINTERS + 3;
4239 # if defined(__I386__)
4240 sd.var[copy->varnum].vv.regoff = i + 3;
4241 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4242 sd.var[copy->varnum].vv.regoff = i + 2;
4244 sd.var[copy->varnum].vv.regoff = i;
4245 # endif /* defined(__I386__) */
4246 #endif /* defined(SPECIALMEMUSE) */
4251 sd.var[copy->varnum].flags |= SAVEDVAR;
4255 i = iptr->s1.argcount;
4260 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4261 DST(TYPE_ADR, new_index);
4267 new_internalerror("Unknown ICMD %d", opcode);
4273 } /* while instructions */
4275 /* stack slots at basic block end become interfaces */
4277 sd.bptr->outdepth = stackdepth;
4278 sd.bptr->outvars = DMNEW(s4, stackdepth);
4281 for (copy = curstack; copy; i--, copy = copy->prev) {
4285 /* with the new vars rd->interfaces will be removed */
4286 /* and all in and outvars have to be STACKVARS! */
4287 /* in the moment i.e. SWAP with in and out vars can */
4288 /* create an unresolvable conflict */
4295 v = sd.var + copy->varnum;
4298 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4299 /* no interface var until now for this depth and */
4301 jd->interface_map[i*5 + t].flags = v->flags;
4304 jd->interface_map[i*5 + t].flags |= v->flags;
4307 sd.bptr->outvars[i] = copy->varnum;
4310 /* check if interface slots at basic block begin must be saved */
4312 for (i=0; i<sd.bptr->indepth; ++i) {
4313 varinfo *v = sd.var + sd.bptr->invars[i];
4320 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4321 /* no interface var until now for this depth and */
4323 jd->interface_map[i*5 + t].flags = v->flags;
4326 jd->interface_map[i*5 + t].flags |= v->flags;
4331 /* store the number of this block's variables */
4333 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4335 #if defined(STACK_VERBOSE)
4336 stack_verbose_block_exit(&sd, superblockend);
4339 /* reach the following block, if any */
4342 if (!stack_reach_next_block(&sd))
4347 } while (sd.repeat && !deadcode);
4349 /* XXX reset TYPE_RET to TYPE_ADR */
4351 for (i=0; i<sd.vartop; ++i) {
4352 if (sd.var[i].type == TYPE_RET)
4353 sd.var[i].type = TYPE_ADR;
4356 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4358 ex = cd->exceptiontable;
4359 for (; ex != NULL; ex = ex->down) {
4360 if (ex->start == ex->end) {
4361 assert(ex->end->next);
4362 ex->end = ex->end->next;
4366 /* gather statistics *****************************************************/
4368 #if defined(ENABLE_STATISTICS)
4370 if (jd->new_basicblockcount > count_max_basic_blocks)
4371 count_max_basic_blocks = jd->new_basicblockcount;
4372 count_basic_blocks += jd->new_basicblockcount;
4373 if (jd->new_instructioncount > count_max_javainstr)
4374 count_max_javainstr = jd->new_instructioncount;
4375 count_javainstr += jd->new_instructioncount;
4376 if (jd->new_stackcount > count_upper_bound_new_stack)
4377 count_upper_bound_new_stack = jd->new_stackcount;
4378 if ((sd.new - jd->new_stack) > count_max_new_stack)
4379 count_max_new_stack = (sd.new - jd->new_stack);
4381 sd.bptr = jd->new_basicblocks;
4382 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4383 if (sd.bptr->flags > BBREACHED) {
4384 if (sd.bptr->indepth >= 10)
4385 count_block_stack[10]++;
4387 count_block_stack[sd.bptr->indepth]++;
4388 len = sd.bptr->icount;
4390 count_block_size_distribution[len]++;
4392 count_block_size_distribution[10]++;
4394 count_block_size_distribution[11]++;
4396 count_block_size_distribution[12]++;
4398 count_block_size_distribution[13]++;
4400 count_block_size_distribution[14]++;
4402 count_block_size_distribution[15]++;
4404 count_block_size_distribution[16]++;
4406 count_block_size_distribution[17]++;
4410 if (iteration_count == 1)
4411 count_analyse_iterations[0]++;
4412 else if (iteration_count == 2)
4413 count_analyse_iterations[1]++;
4414 else if (iteration_count == 3)
4415 count_analyse_iterations[2]++;
4416 else if (iteration_count == 4)
4417 count_analyse_iterations[3]++;
4419 count_analyse_iterations[4]++;
4421 if (jd->new_basicblockcount <= 5)
4422 count_method_bb_distribution[0]++;
4423 else if (jd->new_basicblockcount <= 10)
4424 count_method_bb_distribution[1]++;
4425 else if (jd->new_basicblockcount <= 15)
4426 count_method_bb_distribution[2]++;
4427 else if (jd->new_basicblockcount <= 20)
4428 count_method_bb_distribution[3]++;
4429 else if (jd->new_basicblockcount <= 30)
4430 count_method_bb_distribution[4]++;
4431 else if (jd->new_basicblockcount <= 40)
4432 count_method_bb_distribution[5]++;
4433 else if (jd->new_basicblockcount <= 50)
4434 count_method_bb_distribution[6]++;
4435 else if (jd->new_basicblockcount <= 75)
4436 count_method_bb_distribution[7]++;
4438 count_method_bb_distribution[8]++;
4440 #endif /* defined(ENABLE_STATISTICS) */
4442 /* everything's ok *******************************************************/
4446 /* goto labels for throwing verifier exceptions **************************/
4448 #if defined(ENABLE_VERIFIER)
4450 throw_stack_underflow:
4451 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4454 throw_stack_overflow:
4455 exceptions_throw_verifyerror(m, "Stack size too large");
4458 throw_stack_depth_error:
4459 exceptions_throw_verifyerror(m,"Stack depth mismatch");
4462 throw_stack_type_error:
4463 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4466 throw_stack_category_error:
4467 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4474 /* functions for verbose stack analysis output ********************************/
4476 #if defined(STACK_VERBOSE)
4477 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4479 printf("%c", show_jit_type_letters[v->type]);
4480 if (v->type == TYPE_RET)
4481 printf("{L%03d}", v->vv.retaddr->nr);
4485 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4487 assert(index >= 0 && index < sd->vartop);
4488 stack_verbose_show_varinfo(sd, sd->var + index);
4492 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4496 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4498 for (i=0; i<bptr->indepth; ++i) {
4501 stack_verbose_show_variable(sd, bptr->invars[i]);
4506 printf("] inlocals [");
4507 if (bptr->inlocals) {
4508 for (i=0; i<sd->localcount; ++i) {
4511 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4516 printf("] out:%d [", bptr->outdepth);
4517 if (bptr->outvars) {
4518 for (i=0; i<bptr->outdepth; ++i) {
4521 stack_verbose_show_variable(sd, bptr->outvars[i]);
4529 printf(" (clone of L%03d)", bptr->original->nr);
4531 basicblock *b = bptr->copied_to;
4533 printf(" (copied to ");
4534 for (; b; b = b->copied_to)
4535 printf("L%03d ", b->nr);
4542 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4546 printf("======================================== STACK %sANALYSE BLOCK ",
4547 (reanalyse) ? "RE-" : "");
4548 stack_verbose_show_block(sd, sd->bptr);
4551 if (sd->handlers[0]) {
4552 printf("HANDLERS: ");
4553 for (i=0; sd->handlers[i]; ++i) {
4554 printf("L%03d ", sd->handlers[i]->handler->nr);
4562 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4564 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4565 stack_verbose_show_block(sd, sd->bptr);
4572 * These are local overrides for various environment variables in Emacs.
4573 * Please do not remove this and leave it at the end of the file, where
4574 * Emacs will automagically detect them.
4575 * ---------------------------------------------------------------------
4578 * indent-tabs-mode: t
4582 * vim:noexpandtab:sw=4:ts=4: