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 5481 2006-09-12 21:23:56Z edwin $
50 #include "mm/memory.h"
51 #include "native/native.h"
52 #include "toolbox/logging.h"
53 #include "vm/global.h"
54 #include "vm/builtin.h"
55 #include "vm/options.h"
56 #include "vm/resolve.h"
57 #include "vm/statistics.h"
58 #include "vm/stringlocal.h"
59 #include "vm/jit/cfg.h"
60 #include "vm/jit/codegen-common.h"
61 #include "vm/jit/abi.h"
62 #include "vm/jit/show.h"
64 #if defined(ENABLE_DISASSEMBLER)
65 # include "vm/jit/disass.h"
68 #include "vm/jit/jit.h"
69 #include "vm/jit/stack.h"
71 #if defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
75 /*#define STACK_VERBOSE*/
78 /* macro for saving #ifdefs ***************************************************/
80 #if defined(ENABLE_INTRP)
81 #define IF_INTRP(x) if (opt_intrp) { x }
82 #define IF_NO_INTRP(x) if (!opt_intrp) { x }
85 #define IF_NO_INTRP(x) { x }
88 #if defined(ENABLE_INTRP)
89 #if defined(ENABLE_JIT)
90 #define IF_JIT(x) if (!opt_intrp) { x }
94 #else /* !defined(ENABLE_INTRP) */
95 #define IF_JIT(x) { x }
96 #endif /* defined(ENABLE_INTRP) */
98 #if defined(ENABLE_STATISTICS)
99 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
102 if (stackdepth >= 10) \
103 count_store_depth[10]++; \
105 count_store_depth[stackdepth]++; \
108 #else /* !defined(ENABLE_STATISTICS) */
109 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
112 /* stackdata_t *****************************************************************
114 This struct holds internal data during stack analysis.
116 *******************************************************************************/
118 typedef struct stackdata_t stackdata_t;
121 basicblock *bptr; /* the current basic block being analysed */
122 stackptr new; /* next free stackelement */
123 s4 vartop; /* next free variable index */
124 s4 localcount; /* number of locals (at the start of var) */
125 s4 varcount; /* total number of variables allocated */
126 varinfo *var; /* variable array (same as jd->var) */
127 methodinfo *m; /* the method being analysed */
128 jitdata *jd; /* current jitdata */
129 basicblock *last_real_block; /* the last block before the empty one */
130 bool repeat; /* if true, iterate the analysis again */
131 exceptiontable **handlers; /* exception handlers for the current block */
132 exceptiontable *extableend; /* points to the last exception entry */
133 stackelement exstack; /* instack for exception handlers */
137 /* macros for allocating/releasing variable indices *****************/
139 #define GET_NEW_INDEX(sd, new_varindex) \
141 assert((sd).vartop < (sd).varcount); \
142 (new_varindex) = ((sd).vartop)++; \
145 /* Not implemented now - could be used to reuse varindices. */
146 /* Pay attention to not release a localvar once implementing it! */
147 #define RELEASE_INDEX(sd, varindex)
149 #define GET_NEW_VAR(sd, new_varindex, newtype) \
151 GET_NEW_INDEX((sd), (new_varindex)); \
152 (sd).var[new_index].type = (newtype); \
156 /* macros for querying variable properties **************************/
158 #define IS_OUTVAR(sp) \
159 (sd.var[(sp)->varnum].flags & OUTVAR)
161 #define IS_PREALLOC(sp) \
162 (sd.var[(sp)->varnum].flags & PREALLOC)
164 #define IS_TEMPVAR(sp) \
165 ( ((sp)->varnum >= sd.localcount) \
166 && !(sd.var[(sp)->varnum].flags & (OUTVAR | PREALLOC)) )
168 #define IS_LOCALVAR_SD(sd, sp) \
169 ((sp)->varnum < (sd).localcount)
171 #define IS_LOCALVAR(sp) \
172 IS_LOCALVAR_SD(sd, (sp))
175 /* macros for setting variable properties ****************************/
177 #define SET_TEMPVAR(sp) \
179 if (IS_LOCALVAR((sp))) { \
180 GET_NEW_VAR(sd, new_index, (sp)->type); \
181 sd.var[new_index].flags = (sp)->flags; \
182 (sp)->varnum = new_index; \
183 (sp)->varkind = TEMPVAR; \
185 (sp)->creator->dst.varindex = new_index; \
187 sd.var[(sp)->varnum].flags &= ~(OUTVAR | PREALLOC); \
190 #define SET_PREALLOC(sp) \
192 assert(!IS_LOCALVAR((sp))); \
193 sd.var[(sp)->varnum].flags |= PREALLOC; \
197 /* macros for source operands ***************************************/
200 (iptr->s1.varindex = -1)
202 #define USE_S1(type1) \
205 CHECK_BASIC_TYPE(type1, curstack->type); \
206 iptr->s1.varindex = curstack->varnum; \
212 iptr->s1.varindex = curstack->varnum; \
215 #define USE_S1_S2(type1, type2) \
218 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
219 CHECK_BASIC_TYPE(type2, curstack->type); \
220 iptr->sx.s23.s2.varindex = curstack->varnum; \
221 iptr->s1.varindex = curstack->prev->varnum; \
224 #define USE_S1_S2_ANY_ANY \
227 iptr->sx.s23.s2.varindex = curstack->varnum; \
228 iptr->s1.varindex = curstack->prev->varnum; \
231 #define USE_S1_S2_S3(type1, type2, type3) \
234 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
235 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
236 CHECK_BASIC_TYPE(type3, curstack->type); \
237 iptr->sx.s23.s3.varindex = curstack->varnum; \
238 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
239 iptr->s1.varindex = curstack->prev->prev->varnum; \
242 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
245 if (curstack->varkind == UNDEFVAR) \
246 curstack->varkind = TEMPVAR; \
247 curstack = curstack->prev; \
250 #define POP_S1(type1) \
253 if (curstack->varkind == UNDEFVAR) \
254 curstack->varkind = TEMPVAR; \
255 curstack = curstack->prev; \
261 if (curstack->varkind == UNDEFVAR) \
262 curstack->varkind = TEMPVAR; \
263 curstack = curstack->prev; \
266 #define POP_S1_S2(type1, type2) \
268 USE_S1_S2(type1, type2); \
269 if (curstack->varkind == UNDEFVAR) \
270 curstack->varkind = TEMPVAR; \
271 if (curstack->prev->varkind == UNDEFVAR) \
272 curstack->prev->varkind = TEMPVAR; \
273 curstack = curstack->prev->prev; \
276 #define POP_S1_S2_ANY_ANY \
279 if (curstack->varkind == UNDEFVAR) \
280 curstack->varkind = TEMPVAR; \
281 if (curstack->prev->varkind == UNDEFVAR) \
282 curstack->prev->varkind = TEMPVAR; \
283 curstack = curstack->prev->prev; \
286 #define POP_S1_S2_S3(type1, type2, type3) \
288 USE_S1_S2_S3(type1, type2, type3); \
289 if (curstack->varkind == UNDEFVAR) \
290 curstack->varkind = TEMPVAR; \
291 if (curstack->prev->varkind == UNDEFVAR) \
292 curstack->prev->varkind = TEMPVAR; \
293 if (curstack->prev->prev->varkind == UNDEFVAR) \
294 curstack->prev->prev->varkind = TEMPVAR; \
295 curstack = curstack->prev->prev->prev; \
302 /* macros for setting the destination operand ***********************/
305 (iptr->dst.varindex = -1)
307 #define DST(typed, index) \
309 NEWSTACKn((typed),(index)); \
310 curstack->creator = iptr; \
311 iptr->dst.varindex = (index); \
314 #define DST_LOCALVAR(typed, index) \
316 NEWSTACK((typed), LOCALVAR, (index)); \
317 curstack->creator = iptr; \
318 iptr->dst.varindex = (index); \
322 /* macro for propagating constant values ****************************/
324 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
326 (sd).var[(dindex)].type = (sd).var[(sindex)].type; \
327 (sd).var[(dindex)].vv = (sd).var[(sindex)].vv; \
331 /* stack modelling macros *******************************************/
333 #define OP0_1(typed) \
336 GET_NEW_VAR(sd, new_index, (typed)); \
337 DST(typed, new_index); \
348 #define OP1_BRANCH(type1) \
354 #define OP1_1(type1, typed) \
357 GET_NEW_VAR(sd, new_index, (typed)); \
358 DST(typed, new_index); \
361 #define OP2_1(type1, type2, typed) \
363 POP_S1_S2(type1, type2); \
364 GET_NEW_VAR(sd, new_index, (typed)); \
365 DST(typed, new_index); \
380 #define OP1_0(type1) \
387 #define OP2_0(type1, type2) \
389 POP_S1_S2(type1, type2); \
394 #define OP2_BRANCH(type1, type2) \
396 POP_S1_S2(type1, type2); \
400 #define OP2_0_ANY_ANY \
407 #define OP3_0(type1, type2, type3) \
409 POP_S1_S2_S3(type1, type2, type3); \
414 #define LOAD(type1, index) \
416 DST_LOCALVAR(type1, index); \
420 #define STORE(type1, index) \
427 /* macros for DUP elimination ***************************************/
429 /* XXX replace NEW_VAR with NEW_INDEX */
430 #define DUP_SLOT(sp) \
432 GET_NEW_VAR(sd, new_index, (sp)->type); \
433 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
434 NEWSTACK((sp)->type, TEMPVAR, new_index); \
437 /* does not check input stackdepth */
438 #define MOVE_UP(sp) \
440 iptr->opc = ICMD_MOVE; \
441 iptr->s1.varindex = (sp)->varnum; \
443 curstack->creator = iptr; \
444 iptr->dst.varindex = curstack->varnum; \
448 /* does not check input stackdepth */
449 #define COPY_UP(sp) \
452 iptr->opc = ICMD_COPY; \
453 iptr->s1.varindex = (sp)->varnum; \
455 curstack->creator = iptr; \
456 iptr->dst.varindex = curstack->varnum; \
460 #define COPY_DOWN(s, d) \
463 iptr->opc = ICMD_COPY; \
464 iptr->s1.varindex = (s)->varnum; \
465 iptr->dst.varindex = (d)->varnum; \
466 (d)->creator = iptr; \
470 /* macros for branching / reaching basic blocks *********************/
472 #define BRANCH_TARGET(bt, tempbptr) \
474 tempbptr = BLOCK_OF((bt).insindex); \
475 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
477 if (tempbptr == NULL) \
479 (bt).block = tempbptr; \
482 #define BRANCH(tempbptr) \
483 BRANCH_TARGET(iptr->dst, tempbptr)
486 /* forward declarations *******************************************************/
488 static void stack_create_invars(stackdata_t *sd, basicblock *b,
489 stackptr curstack, int stackdepth);
490 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
492 #if defined(STACK_VERBOSE)
493 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
494 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
495 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
496 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
497 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
501 /* stack_init ******************************************************************
503 Initialized the stack analysis subsystem (called by jit_init).
505 *******************************************************************************/
507 bool stack_init(void)
513 /* stack_grow_variable_array ***************************************************
515 Grow the variable array so the given number of additional variables fits in.
518 sd...........stack analysis data
519 num..........number of additional variables
521 *******************************************************************************/
523 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
532 /* XXX avoid too many reallocations */
533 newcount = sd->varcount + num;
535 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
536 sd->varcount = newcount;
537 sd->jd->var = sd->var;
538 sd->jd->varcount = newcount;
542 /* stack_append_block **********************************************************
544 Append the given block after the last real block of the method (before
545 the pseudo-block at the end).
548 sd...........stack analysis data
549 b............the block to append
551 *******************************************************************************/
553 static void stack_append_block(stackdata_t *sd, basicblock *b)
555 #if defined(STACK_VERBOSE)
556 printf("APPENDING BLOCK L%0d\n", b->nr);
559 b->next = sd->last_real_block->next;
560 sd->last_real_block->next = b;
561 sd->last_real_block = b;
562 sd->jd->new_basicblockcount++;
566 /* stack_clone_block ***********************************************************
568 Create a copy of the given block and insert it at the end of the method.
570 CAUTION: This function does not copy the any variables or the instruction
571 list. It _does_, however, reserve space for the block's invars in the
575 sd...........stack analysis data
576 b............the block to clone
579 a pointer to the copy
581 *******************************************************************************/
583 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
587 clone = DNEW(basicblock);
590 clone->iinstr = NULL;
591 clone->inlocals = NULL;
592 clone->invars = NULL;
594 clone->original = (b->original) ? b->original : b;
595 clone->copied_to = clone->original->copied_to;
596 clone->original->copied_to = clone;
597 clone->nr = sd->m->c_debug_nr++;
599 clone->flags = BBREACHED;
601 stack_append_block(sd, clone);
603 /* allocate space for the invars of the clone */
605 stack_grow_variable_array(sd, b->indepth);
607 #if defined(STACK_VERBOSE)
608 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
615 /* stack_create_invars *********************************************************
617 Create the invars for the given basic block. Also make a copy of the locals.
620 sd...........stack analysis data
621 b............block to create the invars for
622 curstack.....current stack top
623 stackdepth...current stack depth
625 This function creates STACKDEPTH invars and sets their types to the
626 types to the types of the corresponding slot in the current stack.
628 *******************************************************************************/
630 static void stack_create_invars(stackdata_t *sd, basicblock *b,
631 stackptr curstack, int stackdepth)
638 assert(sd->vartop + stackdepth <= sd->varcount);
640 b->indepth = stackdepth;
641 b->invars = DMNEW(s4, stackdepth);
643 /* allocate the variable indices */
644 index = (sd->vartop += stackdepth);
647 for (sp = curstack; i--; sp = sp->prev) {
648 b->invars[i] = --index;
652 v->vv = sd->var[sp->varnum].vv;
653 #if defined(STACK_VERBOSE) && 0
654 printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
658 /* copy the current state of the local variables */
660 v = DMNEW(varinfo, sd->localcount);
662 for (i=0; i<sd->localcount; ++i)
667 /* stack_create_invars_from_outvars ********************************************
669 Create the invars for the given basic block. Also make a copy of the locals.
670 Types are propagated from the outvars of the current block.
673 sd...........stack analysis data
674 b............block to create the invars for
676 *******************************************************************************/
678 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
684 n = sd->bptr->outdepth;
685 assert(sd->vartop + n <= sd->varcount);
688 b->invars = DMNEW(s4, n);
691 dv = sd->var + sd->vartop;
693 /* allocate the invars */
695 for (i=0; i<n; ++i, ++dv) {
696 sv = sd->var + sd->bptr->outvars[i];
697 b->invars[i] = sd->vartop++;
704 /* copy the current state of the local variables */
706 dv = DMNEW(varinfo, sd->localcount);
708 for (i=0; i<sd->localcount; ++i)
713 /* stack_check_invars **********************************************************
715 Check the current stack against the invars of the given basic block.
716 Depth and types must match.
719 sd...........stack analysis data
720 b............block which invars to check against
721 curstack.....current stack top
722 stackdepth...current stack depth
726 NULL.........a VerifyError has been thrown
728 *******************************************************************************/
730 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
731 stackptr curstack, int stackdepth)
738 #if defined(STACK_VERBOSE)
739 printf("stack_check_invars(L%03d)\n", b->nr);
742 /* find original of b */
747 #if defined(STACK_VERBOSE)
748 printf("original is L%03d\n", orig->nr);
753 if (i != stackdepth) {
754 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
761 #if defined(STACK_VERBOSE)
762 printf("checking against ");
763 stack_verbose_show_block(sd, b); printf("\n");
767 for (i = orig->indepth; i--; sp = sp->prev) {
768 if (sd->var[b->invars[i]].type != sp->type) {
769 exceptions_throw_verifyerror_for_stack(sd->m,
770 sd->var[b->invars[i]].type);
774 if (sp->type == TYPE_RET) {
775 if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
783 for (i=0; i<sd->localcount; ++i) {
784 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
785 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
794 /* XXX mark mixed type variables void */
795 /* XXX cascading collapse? */
796 #if defined(STACK_VERBOSE)
797 printf("------> using L%03d\n", b->nr);
801 } while ((b = b->copied_to) != NULL);
803 b = stack_clone_block(sd, orig);
807 stack_create_invars(sd, b, curstack, stackdepth);
812 /* stack_check_invars_from_outvars *********************************************
814 Check the outvars of the current block against the invars of the given block.
815 Depth and types must match.
818 sd...........stack analysis data
819 b............block which invars to check against
823 NULL.........a VerifyError has been thrown
825 *******************************************************************************/
827 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
835 #if defined(STACK_VERBOSE)
836 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
839 /* find original of b */
844 #if defined(STACK_VERBOSE)
845 printf("original is L%03d\n", orig->nr);
849 n = sd->bptr->outdepth;
852 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
859 #if defined(STACK_VERBOSE)
860 printf("checking against ");
861 stack_verbose_show_block(sd, b); printf("\n");
865 dv = sd->var + b->invars[0];
867 for (i=0; i<n; ++i, ++dv) {
868 sv = sd->var + sd->bptr->outvars[i];
869 if (sv->type != dv->type) {
870 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
874 if (dv->type == TYPE_RET) {
875 if (sv->vv.retaddr != dv->vv.retaddr) {
884 for (i=0; i<sd->localcount; ++i) {
885 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
886 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
895 /* XXX mark mixed type variables void */
896 /* XXX cascading collapse? */
897 #if defined(STACK_VERBOSE)
898 printf("------> using L%03d\n", b->nr);
902 } while ((b = b->copied_to) != NULL);
904 b = stack_clone_block(sd, orig);
908 stack_create_invars_from_outvars(sd, b);
913 /* stack_create_instack ********************************************************
915 Create the instack of the current basic block.
918 sd...........stack analysis data
921 the current stack top at the start of the basic block.
923 *******************************************************************************/
925 static stackptr stack_create_instack(stackdata_t *sd)
931 if ((depth = sd->bptr->indepth) == 0)
934 sp = (sd->new += depth);
938 index = sd->bptr->invars[depth];
940 sp->type = sd->var[index].type;
944 sp->varkind = STACKVAR;
948 /* return the top of the created stack */
953 /* stack_mark_reached **********************************************************
955 Mark the given block reached and propagate the current stack and locals to
956 it. This function specializes the target block, if necessary, and returns
957 a pointer to the specialized target.
960 sd...........stack analysis data
961 b............the block to reach
962 curstack.....the current stack top
963 stackdepth...the current stack depth
966 a pointer to (a specialized version of) the target
967 NULL.........a VerifyError has been thrown
969 *******************************************************************************/
971 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
973 #if defined(STACK_VERBOSE)
974 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
976 /* mark targets of backward branches */
978 b->bitflags |= BBFLAG_REPLACEMENT;
980 if (b->flags < BBREACHED) {
981 /* b is reached for the first time. Create its invars. */
983 #if defined(STACK_VERBOSE)
984 printf("reached L%03d for the first time\n", b->nr);
987 stack_create_invars(sd, b, curstack, stackdepth);
989 b->flags = BBREACHED;
994 /* b has been reached before. Check that its invars match. */
996 return stack_check_invars(sd, b, curstack, stackdepth);
1001 /* stack_mark_reached_from_outvars *********************************************
1003 Mark the given block reached and propagate the outvars of the current block
1004 and the current locals to it. This function specializes the target block,
1005 if necessary, and returns a pointer to the specialized target.
1008 sd...........stack analysis data
1009 b............the block to reach
1012 a pointer to (a specialized version of) the target
1013 NULL.........a VerifyError has been thrown
1015 *******************************************************************************/
1017 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1019 #if defined(STACK_VERBOSE)
1020 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1022 /* mark targets of backward branches */
1024 b->bitflags |= BBFLAG_REPLACEMENT;
1026 if (b->flags < BBREACHED) {
1027 /* b is reached for the first time. Create its invars. */
1029 #if defined(STACK_VERBOSE)
1030 printf("reached L%03d for the first time\n", b->nr);
1033 stack_create_invars_from_outvars(sd, b);
1035 b->flags = BBREACHED;
1040 /* b has been reached before. Check that its invars match. */
1042 return stack_check_invars_from_outvars(sd, b);
1047 /* stack_reach_next_block ******************************************************
1049 Mark the following block reached and propagate the outvars of the current block
1050 and the current locals to it. This function specializes the target block,
1051 if necessary, and returns a pointer to the specialized target.
1054 sd...........stack analysis data
1057 a pointer to (a specialized version of) the following block
1058 NULL.........a VerifyError has been thrown
1060 *******************************************************************************/
1062 static bool stack_reach_next_block(stackdata_t *sd)
1067 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1068 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1072 if (tbptr != sd->bptr->next) {
1073 #if defined(STACK_VERBOSE)
1074 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1076 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1077 assert(iptr->opc == ICMD_NOP);
1078 iptr->opc = ICMD_GOTO;
1079 iptr->dst.block = tbptr;
1081 if (tbptr->flags < BBFINISHED)
1082 sd->repeat = true; /* XXX check if we really need to repeat */
1089 /* stack_reach_handlers ********************************************************
1091 Reach the exception handlers for the current block.
1094 sd...........stack analysis data
1097 true.........everything ok
1098 false........a VerifyError has been thrown
1100 *******************************************************************************/
1102 static bool stack_reach_handlers(stackdata_t *sd)
1107 #if defined(STACK_VERBOSE)
1108 printf("reaching exception handlers...\n");
1111 for (i=0; sd->handlers[i]; ++i) {
1112 tbptr = sd->handlers[i]->handler;
1114 tbptr->type = BBTYPE_EXH;
1115 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1117 /* reach (and specialize) the handler block */
1119 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1124 sd->handlers[i]->handler = tbptr;
1131 /* stack_reanalyse_block ******************************************************
1133 Re-analyse the current block. This is called if either the block itself
1134 has already been analysed before, or the current block is a clone of an
1135 already analysed block, and this clone is reached for the first time.
1136 In the latter case, this function does all that is necessary for fully
1137 cloning the block (cloning the instruction list and variables, etc.).
1140 sd...........stack analysis data
1143 true.........everything ok
1144 false........a VerifyError has been thrown
1146 *******************************************************************************/
1148 #define RELOCATE(index) \
1150 if ((index) >= blockvarstart) \
1151 (index) += blockvarshift; \
1152 else if ((index) >= invarstart) \
1153 (index) += invarshift; \
1156 bool stack_reanalyse_block(stackdata_t *sd)
1168 branch_target_t *table;
1169 lookup_target_t *lookup;
1172 bool cloneinstructions;
1175 #if defined(STACK_VERBOSE)
1176 stack_verbose_block_enter(sd, true);
1183 assert(orig != NULL);
1185 /* clone the instruction list */
1187 cloneinstructions = true;
1189 assert(orig->iinstr);
1191 iptr = DMNEW(instruction, len + 1);
1193 MCOPY(iptr, orig->iinstr, instruction, len);
1194 iptr[len].opc = ICMD_NOP;
1198 /* allocate space for the clone's block variables */
1200 stack_grow_variable_array(sd, orig->varcount);
1202 /* we already have the invars set */
1204 assert(b->indepth == orig->indepth);
1206 /* calculate relocation shifts for invars and block variables */
1208 if (orig->indepth) {
1209 invarstart = orig->invars[0];
1210 invarshift = b->invars[0] - invarstart;
1213 invarstart = INT_MAX;
1216 blockvarstart = orig->varstart;
1217 blockvarshift = sd->vartop - blockvarstart;
1219 /* copy block variables */
1221 b->varstart = sd->vartop;
1222 b->varcount = orig->varcount;
1223 sd->vartop += b->varcount;
1224 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1228 b->outdepth = orig->outdepth;
1229 b->outvars = DMNEW(s4, orig->outdepth);
1230 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1232 /* clone exception handlers */
1234 for (i=0; sd->handlers[i]; ++i) {
1235 ex = DNEW(exceptiontable);
1236 ex->handler = sd->handlers[i]->handler;
1238 ex->end = b; /* XXX hack, see end of new_stack_analyse */
1239 ex->catchtype = sd->handlers[i]->catchtype;
1242 assert(sd->extableend->down == NULL);
1243 sd->extableend->down = ex;
1244 sd->extableend = ex;
1245 sd->jd->cd->exceptiontablelength++;
1247 sd->handlers[i] = ex;
1251 cloneinstructions = false;
1254 invarstart = sd->vartop;
1255 blockvarstart = sd->vartop;
1260 /* find exception handlers for the cloned block */
1262 ex = sd->jd->cd->exceptiontable;
1263 for (; ex != NULL; ex = ex->down) {
1264 /* XXX the cloned exception handlers have identical */
1265 /* start end end blocks. */
1266 if ((ex->start == b) && (ex->end == b)) {
1267 sd->handlers[len++] = ex;
1270 sd->handlers[len] = NULL;
1273 #if defined(STACK_VERBOSE)
1274 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1275 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1278 /* mark block as finished */
1280 b->flags = BBFINISHED;
1282 /* initialize locals at the start of this block */
1285 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1287 /* reach exception handlers for this block */
1289 if (!stack_reach_handlers(sd))
1292 superblockend = false;
1294 for (len = b->icount; len--; iptr++) {
1295 #if defined(STACK_VERBOSE)
1296 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1302 switch (iptr->opc) {
1304 j = iptr->s1.varindex;
1306 if (sd->var[j].type != TYPE_RET) {
1307 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1311 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1312 superblockend = true;
1316 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1317 superblockend = true;
1321 superblockend = true;
1324 case ICMD_CHECKNULL:
1325 case ICMD_PUTSTATICCONST:
1331 case ICMD_INLINE_START:
1332 case ICMD_INLINE_END:
1333 case ICMD_INLINE_GOTO:
1337 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1338 superblockend = true;
1341 /* pop 0 push 1 const */
1350 /* pop 0 push 1 load */
1357 RELOCATE(iptr->dst.varindex);
1370 RELOCATE(iptr->sx.s23.s2.varindex);
1371 RELOCATE(iptr->s1.varindex);
1372 RELOCATE(iptr->dst.varindex);
1386 RELOCATE(iptr->sx.s23.s3.varindex);
1387 RELOCATE(iptr->sx.s23.s2.varindex);
1388 RELOCATE(iptr->s1.varindex);
1392 /* pop 1 push 0 store */
1399 RELOCATE(iptr->s1.varindex);
1401 j = iptr->dst.varindex;
1402 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1414 RELOCATE(iptr->s1.varindex);
1415 superblockend = true;
1418 case ICMD_PUTSTATIC:
1419 case ICMD_PUTFIELDCONST:
1422 RELOCATE(iptr->s1.varindex);
1425 /* pop 1 push 0 branch */
1428 case ICMD_IFNONNULL:
1443 RELOCATE(iptr->s1.varindex);
1444 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1447 /* pop 1 push 0 table branch */
1449 case ICMD_TABLESWITCH:
1450 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1452 if (cloneinstructions) {
1453 table = DMNEW(branch_target_t, i);
1454 MCOPY(table, iptr->dst.table, branch_target_t, i);
1455 iptr->dst.table = table;
1458 table = iptr->dst.table;
1461 RELOCATE(iptr->s1.varindex);
1463 table->block = stack_mark_reached_from_outvars(sd, table->block);
1466 superblockend = true;
1469 case ICMD_LOOKUPSWITCH:
1470 i = iptr->sx.s23.s2.lookupcount;
1471 if (cloneinstructions) {
1472 lookup = DMNEW(lookup_target_t, i);
1473 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1474 iptr->dst.lookup = lookup;
1477 lookup = iptr->dst.lookup;
1479 RELOCATE(iptr->s1.varindex);
1481 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1484 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1485 superblockend = true;
1488 case ICMD_MONITORENTER:
1489 case ICMD_MONITOREXIT:
1490 RELOCATE(iptr->s1.varindex);
1494 /* pop 2 push 0 branch */
1496 case ICMD_IF_ICMPEQ:
1497 case ICMD_IF_ICMPNE:
1498 case ICMD_IF_ICMPLT:
1499 case ICMD_IF_ICMPGE:
1500 case ICMD_IF_ICMPGT:
1501 case ICMD_IF_ICMPLE:
1503 case ICMD_IF_LCMPEQ:
1504 case ICMD_IF_LCMPNE:
1505 case ICMD_IF_LCMPLT:
1506 case ICMD_IF_LCMPGE:
1507 case ICMD_IF_LCMPGT:
1508 case ICMD_IF_LCMPLE:
1510 case ICMD_IF_FCMPEQ:
1511 case ICMD_IF_FCMPNE:
1513 case ICMD_IF_FCMPL_LT:
1514 case ICMD_IF_FCMPL_GE:
1515 case ICMD_IF_FCMPL_GT:
1516 case ICMD_IF_FCMPL_LE:
1518 case ICMD_IF_FCMPG_LT:
1519 case ICMD_IF_FCMPG_GE:
1520 case ICMD_IF_FCMPG_GT:
1521 case ICMD_IF_FCMPG_LE:
1523 case ICMD_IF_DCMPEQ:
1524 case ICMD_IF_DCMPNE:
1526 case ICMD_IF_DCMPL_LT:
1527 case ICMD_IF_DCMPL_GE:
1528 case ICMD_IF_DCMPL_GT:
1529 case ICMD_IF_DCMPL_LE:
1531 case ICMD_IF_DCMPG_LT:
1532 case ICMD_IF_DCMPG_GE:
1533 case ICMD_IF_DCMPG_GT:
1534 case ICMD_IF_DCMPG_LE:
1536 case ICMD_IF_ACMPEQ:
1537 case ICMD_IF_ACMPNE:
1538 RELOCATE(iptr->sx.s23.s2.varindex);
1539 RELOCATE(iptr->s1.varindex);
1540 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1546 case ICMD_IASTORECONST:
1547 case ICMD_LASTORECONST:
1548 case ICMD_AASTORECONST:
1549 case ICMD_BASTORECONST:
1550 case ICMD_CASTORECONST:
1551 case ICMD_SASTORECONST:
1554 RELOCATE(iptr->sx.s23.s2.varindex);
1555 RELOCATE(iptr->s1.varindex);
1558 /* pop 0 push 1 copy */
1562 RELOCATE(iptr->dst.varindex);
1563 RELOCATE(iptr->s1.varindex);
1564 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1607 RELOCATE(iptr->sx.s23.s2.varindex);
1608 RELOCATE(iptr->s1.varindex);
1609 RELOCATE(iptr->dst.varindex);
1614 case ICMD_CHECKCAST:
1615 case ICMD_ARRAYLENGTH:
1616 case ICMD_INSTANCEOF:
1618 case ICMD_ANEWARRAY:
1621 case ICMD_IADDCONST:
1622 case ICMD_ISUBCONST:
1623 case ICMD_IMULCONST:
1627 case ICMD_IANDCONST:
1629 case ICMD_IXORCONST:
1630 case ICMD_ISHLCONST:
1631 case ICMD_ISHRCONST:
1632 case ICMD_IUSHRCONST:
1633 case ICMD_LADDCONST:
1634 case ICMD_LSUBCONST:
1635 case ICMD_LMULCONST:
1639 case ICMD_LANDCONST:
1641 case ICMD_LXORCONST:
1642 case ICMD_LSHLCONST:
1643 case ICMD_LSHRCONST:
1644 case ICMD_LUSHRCONST:
1648 case ICMD_INT2SHORT:
1664 RELOCATE(iptr->s1.varindex);
1665 RELOCATE(iptr->dst.varindex);
1670 case ICMD_GETSTATIC:
1673 RELOCATE(iptr->dst.varindex);
1676 /* pop many push any */
1678 case ICMD_INVOKESTATIC:
1679 case ICMD_INVOKESPECIAL:
1680 case ICMD_INVOKEVIRTUAL:
1681 case ICMD_INVOKEINTERFACE:
1683 case ICMD_MULTIANEWARRAY:
1684 i = iptr->s1.argcount;
1685 if (cloneinstructions) {
1686 argp = DMNEW(s4, i);
1687 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1688 iptr->sx.s23.s2.args = argp;
1691 argp = iptr->sx.s23.s2.args;
1699 RELOCATE(iptr->dst.varindex);
1704 new_internalerror("Unknown ICMD %d during stack re-analysis",
1709 #if defined(STACK_VERBOSE)
1710 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1715 /* relocate outvars */
1717 for (i=0; i<b->outdepth; ++i) {
1718 RELOCATE(b->outvars[i]);
1721 #if defined(STACK_VERBOSE)
1722 stack_verbose_block_exit(sd, superblockend);
1725 /* propagate to the next block */
1728 if (!stack_reach_next_block(sd))
1735 /* stack_analyse ***************************************************************
1737 Analyse_stack uses the intermediate code created by parse.c to
1738 build a model of the JVM operand stack for the current method.
1740 The following checks are performed:
1741 - check for operand stack underflow (before each instruction)
1742 - check for operand stack overflow (after[1] each instruction)
1743 - check for matching stack depth at merging points
1744 - check for matching basic types[2] at merging points
1745 - check basic types for instruction input (except for BUILTIN*
1746 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1748 [1]) Checking this after the instruction should be ok. parse.c
1749 counts the number of required stack slots in such a way that it is
1750 only vital that we don't exceed `maxstack` at basic block
1753 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1754 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1755 types are not discerned.
1757 *******************************************************************************/
1759 bool new_stack_analyse(jitdata *jd)
1761 methodinfo *m; /* method being analyzed */
1766 int b_index; /* basic block index */
1768 stackptr curstack; /* current stack top */
1770 int opcode; /* opcode of current instruction */
1773 int len; /* # of instructions after the current one */
1774 bool superblockend; /* if true, no fallthrough to next block */
1775 bool deadcode; /* true if no live code has been reached */
1776 instruction *iptr; /* the current instruction */
1778 basicblock *original;
1781 stackptr *last_store_boundary;
1782 stackptr coalescing_boundary;
1784 stackptr src1, src2, src3, src4, dst1, dst2;
1786 branch_target_t *table;
1787 lookup_target_t *lookup;
1788 #if defined(ENABLE_VERIFIER)
1789 int expectedtype; /* used by CHECK_BASIC_TYPE */
1791 builtintable_entry *bte;
1793 constant_FMIref *fmiref;
1794 #if defined(ENABLE_STATISTICS)
1795 int iteration_count; /* number of iterations of analysis */
1797 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1799 #if defined(STACK_VERBOSE)
1800 new_show_method(jd, SHOW_PARSE);
1803 /* get required compiler data - initialization */
1810 /* initialize the stackdata_t struct */
1814 sd.varcount = jd->varcount;
1815 sd.vartop = jd->vartop;
1816 sd.localcount = jd->localcount;
1818 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1819 sd.exstack.type = TYPE_ADR;
1820 sd.exstack.prev = NULL;
1821 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1823 #if defined(ENABLE_LSRA)
1824 m->maxlifetimes = 0;
1827 #if defined(ENABLE_STATISTICS)
1828 iteration_count = 0;
1831 /* find the last real basic block */
1833 sd.last_real_block = NULL;
1834 tbptr = jd->new_basicblocks;
1835 while (tbptr->next) {
1836 sd.last_real_block = tbptr;
1837 tbptr = tbptr->next;
1839 assert(sd.last_real_block);
1841 /* find the last exception handler */
1843 if (cd->exceptiontablelength)
1844 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1846 sd.extableend = NULL;
1848 /* init jd->interface_map */
1850 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1851 for (i = 0; i < m->maxstack * 5; i++)
1852 jd->interface_map[i].flags = UNUSED;
1854 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1856 /* initialize flags and invars (none) of first block */
1858 jd->new_basicblocks[0].flags = BBREACHED;
1859 jd->new_basicblocks[0].invars = NULL;
1860 jd->new_basicblocks[0].indepth = 0;
1862 /* stack analysis loop (until fixpoint reached) **************************/
1865 #if defined(ENABLE_STATISTICS)
1869 /* initialize loop over basic blocks */
1871 sd.bptr = jd->new_basicblocks;
1872 superblockend = true;
1874 curstack = NULL; stackdepth = 0;
1877 /* iterate over basic blocks *****************************************/
1879 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1881 if (sd.bptr->flags == BBDELETED) {
1882 /* This block has been deleted - do nothing. */
1887 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1888 /* This block has not been reached so far, and we */
1889 /* don't fall into it, so we'll have to iterate again. */
1895 if (sd.bptr->flags > BBREACHED) {
1896 /* This block is already finished. */
1898 superblockend = true;
1902 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1903 /* This block is a clone and the original has not been */
1904 /* analysed, yet. Analyse it on the next iteration. */
1910 /* This block has to be analysed now. */
1912 /* XXX The rest of this block is still indented one level too */
1913 /* much in order to avoid a giant diff by changing that. */
1915 /* We know that sd.bptr->flags == BBREACHED. */
1916 /* This block has been reached before. */
1918 assert(sd.bptr->flags == BBREACHED);
1919 stackdepth = sd.bptr->indepth;
1921 /* find exception handlers for this block */
1923 /* determine the active exception handlers for this block */
1924 /* XXX could use a faster algorithm with sorted lists or */
1927 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1930 ex = cd->exceptiontable;
1931 for (; ex != NULL; ex = ex->down) {
1932 if ((ex->start <= original) && (ex->end > original)) {
1933 sd.handlers[len++] = ex;
1936 sd.handlers[len] = NULL;
1939 /* reanalyse cloned block */
1941 if (sd.bptr->original) {
1942 if (!stack_reanalyse_block(&sd))
1947 /* reset the new pointer for allocating stackslots */
1949 sd.new = jd->new_stack;
1951 /* create the instack of this block */
1953 curstack = stack_create_instack(&sd);
1955 /* initialize locals at the start of this block */
1957 if (sd.bptr->inlocals)
1958 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1960 /* set up local variables for analyzing this block */
1963 superblockend = false;
1964 len = sd.bptr->icount;
1965 iptr = sd.bptr->iinstr;
1966 b_index = sd.bptr - jd->new_basicblocks;
1968 /* mark the block as analysed */
1970 sd.bptr->flags = BBFINISHED;
1972 /* reset variables for dependency checking */
1974 coalescing_boundary = sd.new;
1975 for( i = 0; i < cd->maxlocals; i++)
1976 last_store_boundary[i] = sd.new;
1978 /* remember the start of this block's variables */
1980 sd.bptr->varstart = sd.vartop;
1982 #if defined(STACK_VERBOSE)
1983 stack_verbose_block_enter(&sd, false);
1986 /* reach exception handlers for this block */
1988 if (!stack_reach_handlers(&sd))
1991 /* iterate over ICMDs ****************************************/
1993 while (--len >= 0) {
1995 #if defined(STACK_VERBOSE)
1996 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
1997 for( copy = curstack; copy; copy = copy->prev ) {
1998 printf("%2d(%d", copy->varnum, copy->type);
1999 if (IS_OUTVAR(copy))
2001 if (IS_PREALLOC(copy))
2008 /* fetch the current opcode */
2012 /* automatically replace some ICMDs with builtins */
2014 #if defined(USEBUILTINTABLE)
2016 bte = builtintable_get_automatic(opcode);
2018 if (bte && bte->opcode == opcode) {
2019 iptr->opc = ICMD_BUILTIN;
2020 iptr->flags.bits = 0;
2021 iptr->sx.s23.s3.bte = bte;
2022 /* iptr->line is already set */
2023 jd->isleafmethod = false;
2027 #endif /* defined(USEBUILTINTABLE) */
2029 /* main opcode switch *************************************/
2041 case ICMD_CHECKNULL:
2042 coalescing_boundary = sd.new;
2043 COUNT(count_check_null);
2046 CLR_DST; /* XXX live through? */
2050 j = iptr->s1.varindex =
2051 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2053 if (sd.var[j].type != TYPE_RET) {
2054 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2060 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2062 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
2064 superblockend = true;
2068 COUNT(count_pcmd_return);
2071 superblockend = true;
2075 /* pop 0 push 1 const */
2077 /************************** ICONST OPTIMIZATIONS **************************/
2080 COUNT(count_pcmd_load);
2084 switch (iptr[1].opc) {
2086 iptr->opc = ICMD_IADDCONST;
2090 iptr[1].opc = ICMD_NOP;
2091 OP1_1(TYPE_INT, TYPE_INT);
2092 COUNT(count_pcmd_op);
2096 iptr->opc = ICMD_ISUBCONST;
2097 goto icmd_iconst_tail;
2098 #if SUPPORT_CONST_MUL
2100 iptr->opc = ICMD_IMULCONST;
2101 goto icmd_iconst_tail;
2102 #else /* SUPPORT_CONST_MUL */
2104 if (iptr->sx.val.i == 0x00000002)
2106 else if (iptr->sx.val.i == 0x00000004)
2108 else if (iptr->sx.val.i == 0x00000008)
2110 else if (iptr->sx.val.i == 0x00000010)
2112 else if (iptr->sx.val.i == 0x00000020)
2114 else if (iptr->sx.val.i == 0x00000040)
2116 else if (iptr->sx.val.i == 0x00000080)
2118 else if (iptr->sx.val.i == 0x00000100)
2120 else if (iptr->sx.val.i == 0x00000200)
2122 else if (iptr->sx.val.i == 0x00000400)
2123 iptr->sx.val.i = 10;
2124 else if (iptr->sx.val.i == 0x00000800)
2125 iptr->sx.val.i = 11;
2126 else if (iptr->sx.val.i == 0x00001000)
2127 iptr->sx.val.i = 12;
2128 else if (iptr->sx.val.i == 0x00002000)
2129 iptr->sx.val.i = 13;
2130 else if (iptr->sx.val.i == 0x00004000)
2131 iptr->sx.val.i = 14;
2132 else if (iptr->sx.val.i == 0x00008000)
2133 iptr->sx.val.i = 15;
2134 else if (iptr->sx.val.i == 0x00010000)
2135 iptr->sx.val.i = 16;
2136 else if (iptr->sx.val.i == 0x00020000)
2137 iptr->sx.val.i = 17;
2138 else if (iptr->sx.val.i == 0x00040000)
2139 iptr->sx.val.i = 18;
2140 else if (iptr->sx.val.i == 0x00080000)
2141 iptr->sx.val.i = 19;
2142 else if (iptr->sx.val.i == 0x00100000)
2143 iptr->sx.val.i = 20;
2144 else if (iptr->sx.val.i == 0x00200000)
2145 iptr->sx.val.i = 21;
2146 else if (iptr->sx.val.i == 0x00400000)
2147 iptr->sx.val.i = 22;
2148 else if (iptr->sx.val.i == 0x00800000)
2149 iptr->sx.val.i = 23;
2150 else if (iptr->sx.val.i == 0x01000000)
2151 iptr->sx.val.i = 24;
2152 else if (iptr->sx.val.i == 0x02000000)
2153 iptr->sx.val.i = 25;
2154 else if (iptr->sx.val.i == 0x04000000)
2155 iptr->sx.val.i = 26;
2156 else if (iptr->sx.val.i == 0x08000000)
2157 iptr->sx.val.i = 27;
2158 else if (iptr->sx.val.i == 0x10000000)
2159 iptr->sx.val.i = 28;
2160 else if (iptr->sx.val.i == 0x20000000)
2161 iptr->sx.val.i = 29;
2162 else if (iptr->sx.val.i == 0x40000000)
2163 iptr->sx.val.i = 30;
2164 else if (iptr->sx.val.i == 0x80000000)
2165 iptr->sx.val.i = 31;
2169 iptr->opc = ICMD_IMULPOW2;
2170 goto icmd_iconst_tail;
2171 #endif /* SUPPORT_CONST_MUL */
2173 if (iptr->sx.val.i == 0x00000002)
2175 else if (iptr->sx.val.i == 0x00000004)
2177 else if (iptr->sx.val.i == 0x00000008)
2179 else if (iptr->sx.val.i == 0x00000010)
2181 else if (iptr->sx.val.i == 0x00000020)
2183 else if (iptr->sx.val.i == 0x00000040)
2185 else if (iptr->sx.val.i == 0x00000080)
2187 else if (iptr->sx.val.i == 0x00000100)
2189 else if (iptr->sx.val.i == 0x00000200)
2191 else if (iptr->sx.val.i == 0x00000400)
2192 iptr->sx.val.i = 10;
2193 else if (iptr->sx.val.i == 0x00000800)
2194 iptr->sx.val.i = 11;
2195 else if (iptr->sx.val.i == 0x00001000)
2196 iptr->sx.val.i = 12;
2197 else if (iptr->sx.val.i == 0x00002000)
2198 iptr->sx.val.i = 13;
2199 else if (iptr->sx.val.i == 0x00004000)
2200 iptr->sx.val.i = 14;
2201 else if (iptr->sx.val.i == 0x00008000)
2202 iptr->sx.val.i = 15;
2203 else if (iptr->sx.val.i == 0x00010000)
2204 iptr->sx.val.i = 16;
2205 else if (iptr->sx.val.i == 0x00020000)
2206 iptr->sx.val.i = 17;
2207 else if (iptr->sx.val.i == 0x00040000)
2208 iptr->sx.val.i = 18;
2209 else if (iptr->sx.val.i == 0x00080000)
2210 iptr->sx.val.i = 19;
2211 else if (iptr->sx.val.i == 0x00100000)
2212 iptr->sx.val.i = 20;
2213 else if (iptr->sx.val.i == 0x00200000)
2214 iptr->sx.val.i = 21;
2215 else if (iptr->sx.val.i == 0x00400000)
2216 iptr->sx.val.i = 22;
2217 else if (iptr->sx.val.i == 0x00800000)
2218 iptr->sx.val.i = 23;
2219 else if (iptr->sx.val.i == 0x01000000)
2220 iptr->sx.val.i = 24;
2221 else if (iptr->sx.val.i == 0x02000000)
2222 iptr->sx.val.i = 25;
2223 else if (iptr->sx.val.i == 0x04000000)
2224 iptr->sx.val.i = 26;
2225 else if (iptr->sx.val.i == 0x08000000)
2226 iptr->sx.val.i = 27;
2227 else if (iptr->sx.val.i == 0x10000000)
2228 iptr->sx.val.i = 28;
2229 else if (iptr->sx.val.i == 0x20000000)
2230 iptr->sx.val.i = 29;
2231 else if (iptr->sx.val.i == 0x40000000)
2232 iptr->sx.val.i = 30;
2233 else if (iptr->sx.val.i == 0x80000000)
2234 iptr->sx.val.i = 31;
2238 iptr->opc = ICMD_IDIVPOW2;
2239 goto icmd_iconst_tail;
2242 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2243 if ((iptr->sx.val.i == 0x00000002) ||
2244 (iptr->sx.val.i == 0x00000004) ||
2245 (iptr->sx.val.i == 0x00000008) ||
2246 (iptr->sx.val.i == 0x00000010) ||
2247 (iptr->sx.val.i == 0x00000020) ||
2248 (iptr->sx.val.i == 0x00000040) ||
2249 (iptr->sx.val.i == 0x00000080) ||
2250 (iptr->sx.val.i == 0x00000100) ||
2251 (iptr->sx.val.i == 0x00000200) ||
2252 (iptr->sx.val.i == 0x00000400) ||
2253 (iptr->sx.val.i == 0x00000800) ||
2254 (iptr->sx.val.i == 0x00001000) ||
2255 (iptr->sx.val.i == 0x00002000) ||
2256 (iptr->sx.val.i == 0x00004000) ||
2257 (iptr->sx.val.i == 0x00008000) ||
2258 (iptr->sx.val.i == 0x00010000) ||
2259 (iptr->sx.val.i == 0x00020000) ||
2260 (iptr->sx.val.i == 0x00040000) ||
2261 (iptr->sx.val.i == 0x00080000) ||
2262 (iptr->sx.val.i == 0x00100000) ||
2263 (iptr->sx.val.i == 0x00200000) ||
2264 (iptr->sx.val.i == 0x00400000) ||
2265 (iptr->sx.val.i == 0x00800000) ||
2266 (iptr->sx.val.i == 0x01000000) ||
2267 (iptr->sx.val.i == 0x02000000) ||
2268 (iptr->sx.val.i == 0x04000000) ||
2269 (iptr->sx.val.i == 0x08000000) ||
2270 (iptr->sx.val.i == 0x10000000) ||
2271 (iptr->sx.val.i == 0x20000000) ||
2272 (iptr->sx.val.i == 0x40000000) ||
2273 (iptr->sx.val.i == 0x80000000))
2275 iptr->opc = ICMD_IREMPOW2;
2276 iptr->sx.val.i -= 1;
2277 goto icmd_iconst_tail;
2280 #if SUPPORT_CONST_LOGICAL
2282 iptr->opc = ICMD_IANDCONST;
2283 goto icmd_iconst_tail;
2286 iptr->opc = ICMD_IORCONST;
2287 goto icmd_iconst_tail;
2290 iptr->opc = ICMD_IXORCONST;
2291 goto icmd_iconst_tail;
2293 #endif /* SUPPORT_CONST_LOGICAL */
2295 iptr->opc = ICMD_ISHLCONST;
2296 goto icmd_iconst_tail;
2299 iptr->opc = ICMD_ISHRCONST;
2300 goto icmd_iconst_tail;
2303 iptr->opc = ICMD_IUSHRCONST;
2304 goto icmd_iconst_tail;
2305 #if SUPPORT_LONG_SHIFT
2307 iptr->opc = ICMD_LSHLCONST;
2308 goto icmd_lconst_tail;
2311 iptr->opc = ICMD_LSHRCONST;
2312 goto icmd_lconst_tail;
2315 iptr->opc = ICMD_LUSHRCONST;
2316 goto icmd_lconst_tail;
2317 #endif /* SUPPORT_LONG_SHIFT */
2318 case ICMD_IF_ICMPEQ:
2319 iptr[1].opc = ICMD_IFEQ;
2323 /* set the constant for the following icmd */
2324 iptr[1].sx.val.i = iptr->sx.val.i;
2326 /* this instruction becomes a nop */
2327 iptr->opc = ICMD_NOP;
2330 case ICMD_IF_ICMPLT:
2331 iptr[1].opc = ICMD_IFLT;
2332 goto icmd_if_icmp_tail;
2334 case ICMD_IF_ICMPLE:
2335 iptr[1].opc = ICMD_IFLE;
2336 goto icmd_if_icmp_tail;
2338 case ICMD_IF_ICMPNE:
2339 iptr[1].opc = ICMD_IFNE;
2340 goto icmd_if_icmp_tail;
2342 case ICMD_IF_ICMPGT:
2343 iptr[1].opc = ICMD_IFGT;
2344 goto icmd_if_icmp_tail;
2346 case ICMD_IF_ICMPGE:
2347 iptr[1].opc = ICMD_IFGE;
2348 goto icmd_if_icmp_tail;
2350 #if SUPPORT_CONST_STORE
2355 IF_INTRP( goto normal_ICONST; )
2356 # if SUPPORT_CONST_STORE_ZERO_ONLY
2357 if (iptr->sx.val.i != 0)
2360 switch (iptr[1].opc) {
2362 iptr->opc = ICMD_IASTORECONST;
2363 iptr->flags.bits |= INS_FLAG_CHECK;
2366 iptr->opc = ICMD_BASTORECONST;
2367 iptr->flags.bits |= INS_FLAG_CHECK;
2370 iptr->opc = ICMD_CASTORECONST;
2371 iptr->flags.bits |= INS_FLAG_CHECK;
2374 iptr->opc = ICMD_SASTORECONST;
2375 iptr->flags.bits |= INS_FLAG_CHECK;
2379 iptr[1].opc = ICMD_NOP;
2381 /* copy the constant to s3 */
2382 /* XXX constval -> astoreconstval? */
2383 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2384 OP2_0(TYPE_ADR, TYPE_INT);
2385 COUNT(count_pcmd_op);
2388 case ICMD_PUTSTATIC:
2390 IF_INTRP( goto normal_ICONST; )
2391 # if SUPPORT_CONST_STORE_ZERO_ONLY
2392 if (iptr->sx.val.i != 0)
2395 /* XXX check field type? */
2397 /* copy the constant to s2 */
2398 /* XXX constval -> fieldconstval? */
2399 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2402 /* set the field reference (s3) */
2403 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2404 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2405 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2408 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2411 switch (iptr[1].opc) {
2412 case ICMD_PUTSTATIC:
2413 iptr->opc = ICMD_PUTSTATICCONST;
2417 iptr->opc = ICMD_PUTFIELDCONST;
2422 iptr[1].opc = ICMD_NOP;
2423 COUNT(count_pcmd_op);
2425 #endif /* SUPPORT_CONST_STORE */
2431 /* if we get here, the ICONST has been optimized */
2435 /* normal case of an unoptimized ICONST */
2439 /************************** LCONST OPTIMIZATIONS **************************/
2442 COUNT(count_pcmd_load);
2446 /* switch depending on the following instruction */
2448 switch (iptr[1].opc) {
2449 #if SUPPORT_LONG_ADD
2451 iptr->opc = ICMD_LADDCONST;
2455 /* instruction of type LONG -> LONG */
2456 iptr[1].opc = ICMD_NOP;
2457 OP1_1(TYPE_LNG, TYPE_LNG);
2458 COUNT(count_pcmd_op);
2462 iptr->opc = ICMD_LSUBCONST;
2463 goto icmd_lconst_tail;
2465 #endif /* SUPPORT_LONG_ADD */
2466 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2468 iptr->opc = ICMD_LMULCONST;
2469 goto icmd_lconst_tail;
2470 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2471 # if SUPPORT_LONG_SHIFT
2473 if (iptr->sx.val.l == 0x00000002)
2475 else if (iptr->sx.val.l == 0x00000004)
2477 else if (iptr->sx.val.l == 0x00000008)
2479 else if (iptr->sx.val.l == 0x00000010)
2481 else if (iptr->sx.val.l == 0x00000020)
2483 else if (iptr->sx.val.l == 0x00000040)
2485 else if (iptr->sx.val.l == 0x00000080)
2487 else if (iptr->sx.val.l == 0x00000100)
2489 else if (iptr->sx.val.l == 0x00000200)
2491 else if (iptr->sx.val.l == 0x00000400)
2492 iptr->sx.val.i = 10;
2493 else if (iptr->sx.val.l == 0x00000800)
2494 iptr->sx.val.i = 11;
2495 else if (iptr->sx.val.l == 0x00001000)
2496 iptr->sx.val.i = 12;
2497 else if (iptr->sx.val.l == 0x00002000)
2498 iptr->sx.val.i = 13;
2499 else if (iptr->sx.val.l == 0x00004000)
2500 iptr->sx.val.i = 14;
2501 else if (iptr->sx.val.l == 0x00008000)
2502 iptr->sx.val.i = 15;
2503 else if (iptr->sx.val.l == 0x00010000)
2504 iptr->sx.val.i = 16;
2505 else if (iptr->sx.val.l == 0x00020000)
2506 iptr->sx.val.i = 17;
2507 else if (iptr->sx.val.l == 0x00040000)
2508 iptr->sx.val.i = 18;
2509 else if (iptr->sx.val.l == 0x00080000)
2510 iptr->sx.val.i = 19;
2511 else if (iptr->sx.val.l == 0x00100000)
2512 iptr->sx.val.i = 20;
2513 else if (iptr->sx.val.l == 0x00200000)
2514 iptr->sx.val.i = 21;
2515 else if (iptr->sx.val.l == 0x00400000)
2516 iptr->sx.val.i = 22;
2517 else if (iptr->sx.val.l == 0x00800000)
2518 iptr->sx.val.i = 23;
2519 else if (iptr->sx.val.l == 0x01000000)
2520 iptr->sx.val.i = 24;
2521 else if (iptr->sx.val.l == 0x02000000)
2522 iptr->sx.val.i = 25;
2523 else if (iptr->sx.val.l == 0x04000000)
2524 iptr->sx.val.i = 26;
2525 else if (iptr->sx.val.l == 0x08000000)
2526 iptr->sx.val.i = 27;
2527 else if (iptr->sx.val.l == 0x10000000)
2528 iptr->sx.val.i = 28;
2529 else if (iptr->sx.val.l == 0x20000000)
2530 iptr->sx.val.i = 29;
2531 else if (iptr->sx.val.l == 0x40000000)
2532 iptr->sx.val.i = 30;
2533 else if (iptr->sx.val.l == 0x80000000)
2534 iptr->sx.val.i = 31;
2538 iptr->opc = ICMD_LMULPOW2;
2539 goto icmd_lconst_tail;
2540 # endif /* SUPPORT_LONG_SHIFT */
2541 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2542 #if SUPPORT_LONG_DIV_POW2
2544 if (iptr->sx.val.l == 0x00000002)
2546 else if (iptr->sx.val.l == 0x00000004)
2548 else if (iptr->sx.val.l == 0x00000008)
2550 else if (iptr->sx.val.l == 0x00000010)
2552 else if (iptr->sx.val.l == 0x00000020)
2554 else if (iptr->sx.val.l == 0x00000040)
2556 else if (iptr->sx.val.l == 0x00000080)
2558 else if (iptr->sx.val.l == 0x00000100)
2560 else if (iptr->sx.val.l == 0x00000200)
2562 else if (iptr->sx.val.l == 0x00000400)
2563 iptr->sx.val.i = 10;
2564 else if (iptr->sx.val.l == 0x00000800)
2565 iptr->sx.val.i = 11;
2566 else if (iptr->sx.val.l == 0x00001000)
2567 iptr->sx.val.i = 12;
2568 else if (iptr->sx.val.l == 0x00002000)
2569 iptr->sx.val.i = 13;
2570 else if (iptr->sx.val.l == 0x00004000)
2571 iptr->sx.val.i = 14;
2572 else if (iptr->sx.val.l == 0x00008000)
2573 iptr->sx.val.i = 15;
2574 else if (iptr->sx.val.l == 0x00010000)
2575 iptr->sx.val.i = 16;
2576 else if (iptr->sx.val.l == 0x00020000)
2577 iptr->sx.val.i = 17;
2578 else if (iptr->sx.val.l == 0x00040000)
2579 iptr->sx.val.i = 18;
2580 else if (iptr->sx.val.l == 0x00080000)
2581 iptr->sx.val.i = 19;
2582 else if (iptr->sx.val.l == 0x00100000)
2583 iptr->sx.val.i = 20;
2584 else if (iptr->sx.val.l == 0x00200000)
2585 iptr->sx.val.i = 21;
2586 else if (iptr->sx.val.l == 0x00400000)
2587 iptr->sx.val.i = 22;
2588 else if (iptr->sx.val.l == 0x00800000)
2589 iptr->sx.val.i = 23;
2590 else if (iptr->sx.val.l == 0x01000000)
2591 iptr->sx.val.i = 24;
2592 else if (iptr->sx.val.l == 0x02000000)
2593 iptr->sx.val.i = 25;
2594 else if (iptr->sx.val.l == 0x04000000)
2595 iptr->sx.val.i = 26;
2596 else if (iptr->sx.val.l == 0x08000000)
2597 iptr->sx.val.i = 27;
2598 else if (iptr->sx.val.l == 0x10000000)
2599 iptr->sx.val.i = 28;
2600 else if (iptr->sx.val.l == 0x20000000)
2601 iptr->sx.val.i = 29;
2602 else if (iptr->sx.val.l == 0x40000000)
2603 iptr->sx.val.i = 30;
2604 else if (iptr->sx.val.l == 0x80000000)
2605 iptr->sx.val.i = 31;
2609 iptr->opc = ICMD_LDIVPOW2;
2610 goto icmd_lconst_tail;
2611 #endif /* SUPPORT_LONG_DIV_POW2 */
2613 #if SUPPORT_LONG_REM_POW2
2615 if ((iptr->sx.val.l == 0x00000002) ||
2616 (iptr->sx.val.l == 0x00000004) ||
2617 (iptr->sx.val.l == 0x00000008) ||
2618 (iptr->sx.val.l == 0x00000010) ||
2619 (iptr->sx.val.l == 0x00000020) ||
2620 (iptr->sx.val.l == 0x00000040) ||
2621 (iptr->sx.val.l == 0x00000080) ||
2622 (iptr->sx.val.l == 0x00000100) ||
2623 (iptr->sx.val.l == 0x00000200) ||
2624 (iptr->sx.val.l == 0x00000400) ||
2625 (iptr->sx.val.l == 0x00000800) ||
2626 (iptr->sx.val.l == 0x00001000) ||
2627 (iptr->sx.val.l == 0x00002000) ||
2628 (iptr->sx.val.l == 0x00004000) ||
2629 (iptr->sx.val.l == 0x00008000) ||
2630 (iptr->sx.val.l == 0x00010000) ||
2631 (iptr->sx.val.l == 0x00020000) ||
2632 (iptr->sx.val.l == 0x00040000) ||
2633 (iptr->sx.val.l == 0x00080000) ||
2634 (iptr->sx.val.l == 0x00100000) ||
2635 (iptr->sx.val.l == 0x00200000) ||
2636 (iptr->sx.val.l == 0x00400000) ||
2637 (iptr->sx.val.l == 0x00800000) ||
2638 (iptr->sx.val.l == 0x01000000) ||
2639 (iptr->sx.val.l == 0x02000000) ||
2640 (iptr->sx.val.l == 0x04000000) ||
2641 (iptr->sx.val.l == 0x08000000) ||
2642 (iptr->sx.val.l == 0x10000000) ||
2643 (iptr->sx.val.l == 0x20000000) ||
2644 (iptr->sx.val.l == 0x40000000) ||
2645 (iptr->sx.val.l == 0x80000000))
2647 iptr->opc = ICMD_LREMPOW2;
2648 iptr->sx.val.l -= 1;
2649 goto icmd_lconst_tail;
2652 #endif /* SUPPORT_LONG_REM_POW2 */
2654 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2657 iptr->opc = ICMD_LANDCONST;
2658 goto icmd_lconst_tail;
2661 iptr->opc = ICMD_LORCONST;
2662 goto icmd_lconst_tail;
2665 iptr->opc = ICMD_LXORCONST;
2666 goto icmd_lconst_tail;
2667 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2669 #if SUPPORT_LONG_CMP_CONST
2671 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2674 /* switch on the instruction after LCONST - LCMP */
2676 switch (iptr[2].opc) {
2678 iptr->opc = ICMD_IF_LEQ;
2681 icmd_lconst_lcmp_tail:
2682 /* convert LCONST, LCMP, IFXX to IF_LXX */
2683 iptr->dst.insindex = iptr[2].dst.insindex;
2684 iptr[1].opc = ICMD_NOP;
2685 iptr[2].opc = ICMD_NOP;
2687 OP1_BRANCH(TYPE_LNG);
2689 COUNT(count_pcmd_bra);
2690 COUNT(count_pcmd_op);
2694 iptr->opc = ICMD_IF_LNE;
2695 goto icmd_lconst_lcmp_tail;
2698 iptr->opc = ICMD_IF_LLT;
2699 goto icmd_lconst_lcmp_tail;
2702 iptr->opc = ICMD_IF_LGT;
2703 goto icmd_lconst_lcmp_tail;
2706 iptr->opc = ICMD_IF_LLE;
2707 goto icmd_lconst_lcmp_tail;
2710 iptr->opc = ICMD_IF_LGE;
2711 goto icmd_lconst_lcmp_tail;
2715 } /* end switch on opcode after LCONST - LCMP */
2717 #endif /* SUPPORT_LONG_CMP_CONST */
2719 #if SUPPORT_CONST_STORE
2721 IF_INTRP( goto normal_LCONST; )
2722 # if SUPPORT_CONST_STORE_ZERO_ONLY
2723 if (iptr->sx.val.l != 0)
2726 #if SIZEOF_VOID_P == 4
2727 /* the constant must fit into a ptrint */
2728 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2731 /* move the constant to s3 */
2732 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2734 iptr->opc = ICMD_LASTORECONST;
2735 iptr->flags.bits |= INS_FLAG_CHECK;
2736 OP2_0(TYPE_ADR, TYPE_INT);
2738 iptr[1].opc = ICMD_NOP;
2739 COUNT(count_pcmd_op);
2742 case ICMD_PUTSTATIC:
2744 IF_INTRP( goto normal_LCONST; )
2745 # if SUPPORT_CONST_STORE_ZERO_ONLY
2746 if (iptr->sx.val.l != 0)
2749 #if SIZEOF_VOID_P == 4
2750 /* the constant must fit into a ptrint */
2751 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2754 /* XXX check field type? */
2756 /* copy the constant to s2 */
2757 /* XXX constval -> fieldconstval? */
2758 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2762 #endif /* SUPPORT_CONST_STORE */
2766 } /* end switch opcode after LCONST */
2768 /* if we get here, the LCONST has been optimized */
2772 /* the normal case of an unoptimized LCONST */
2776 /************************ END OF LCONST OPTIMIZATIONS *********************/
2779 COUNT(count_pcmd_load);
2784 COUNT(count_pcmd_load);
2788 /************************** ACONST OPTIMIZATIONS **************************/
2791 coalescing_boundary = sd.new;
2792 COUNT(count_pcmd_load);
2793 #if SUPPORT_CONST_STORE
2794 IF_INTRP( goto normal_ACONST; )
2796 /* We can only optimize if the ACONST is resolved
2797 * and there is an instruction after it. */
2799 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2802 switch (iptr[1].opc) {
2804 /* We can only optimize for NULL values
2805 * here because otherwise a checkcast is
2807 if (iptr->sx.val.anyptr != NULL)
2810 /* copy the constant (NULL) to s3 */
2811 iptr->sx.s23.s3.constval = 0;
2812 iptr->opc = ICMD_AASTORECONST;
2813 iptr->flags.bits |= INS_FLAG_CHECK;
2814 OP2_0(TYPE_ADR, TYPE_INT);
2816 iptr[1].opc = ICMD_NOP;
2817 COUNT(count_pcmd_op);
2820 case ICMD_PUTSTATIC:
2822 # if SUPPORT_CONST_STORE_ZERO_ONLY
2823 if (iptr->sx.val.anyptr != NULL)
2826 /* XXX check field type? */
2827 /* copy the constant to s2 */
2828 /* XXX constval -> fieldconstval? */
2829 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2837 /* if we get here the ACONST has been optimized */
2841 #endif /* SUPPORT_CONST_STORE */
2846 /* pop 0 push 1 load */
2853 COUNT(count_load_instruction);
2854 i = opcode - ICMD_ILOAD; /* type */
2856 j = iptr->s1.varindex =
2857 jd->local_map[iptr->s1.varindex * 5 + i];
2859 if (sd.var[j].type == TYPE_RET) {
2860 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
2873 coalescing_boundary = sd.new;
2874 iptr->flags.bits |= INS_FLAG_CHECK;
2875 COUNT(count_check_null);
2876 COUNT(count_check_bound);
2877 COUNT(count_pcmd_mem);
2878 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
2885 coalescing_boundary = sd.new;
2886 iptr->flags.bits |= INS_FLAG_CHECK;
2887 COUNT(count_check_null);
2888 COUNT(count_check_bound);
2889 COUNT(count_pcmd_mem);
2890 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2893 /* pop 0 push 0 iinc */
2896 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2898 last_store_boundary[iptr->s1.varindex] = sd.new;
2901 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2906 if ((copy->varkind == LOCALVAR) &&
2907 (copy->varnum == iptr->s1.varindex))
2909 assert(IS_LOCALVAR(copy));
2916 iptr->dst.varindex = iptr->s1.varindex;
2919 /* pop 1 push 0 store */
2928 i = opcode - ICMD_ISTORE; /* type */
2929 javaindex = iptr->dst.varindex;
2930 j = iptr->dst.varindex =
2931 jd->local_map[javaindex * 5 + i];
2933 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2935 #if defined(ENABLE_STATISTICS)
2938 i = sd.new - curstack;
2940 count_store_length[20]++;
2942 count_store_length[i]++;
2945 count_store_depth[10]++;
2947 count_store_depth[i]++;
2950 /* check for conflicts as described in Figure 5.2 */
2952 copy = curstack->prev;
2955 if ((copy->varkind == LOCALVAR) &&
2956 (copy->varnum == j))
2958 copy->varkind = TEMPVAR;
2959 assert(IS_LOCALVAR(copy));
2966 /* if the variable is already coalesced, don't bother */
2968 /* We do not need to check against OUTVAR, as invars */
2969 /* are always before the coalescing boundary. */
2971 if (curstack->varkind == LOCALVAR)
2974 /* there is no STORE Lj while curstack is live */
2976 if (curstack < last_store_boundary[javaindex])
2977 goto assume_conflict;
2979 /* curstack must be after the coalescing boundary */
2981 if (curstack < coalescing_boundary)
2982 goto assume_conflict;
2984 /* there is no DEF LOCALVAR(j) while curstack is live */
2986 copy = sd.new; /* most recent stackslot created + 1 */
2987 while (--copy > curstack) {
2988 if (copy->varkind == LOCALVAR && copy->varnum == j)
2989 goto assume_conflict;
2992 /* coalesce the temporary variable with Lj */
2993 assert((curstack->varkind == TEMPVAR)
2994 || (curstack->varkind == UNDEFVAR));
2995 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
2996 assert(!IS_OUTVAR(curstack));
2997 assert(!IS_PREALLOC(curstack));
2999 assert(curstack->creator);
3000 assert(curstack->creator->dst.varindex == curstack->varnum);
3001 RELEASE_INDEX(sd, curstack);
3002 curstack->varkind = LOCALVAR;
3003 curstack->varnum = j;
3004 curstack->creator->dst.varindex = j;
3007 /* revert the coalescing, if it has been done earlier */
3009 if ((curstack->varkind == LOCALVAR)
3010 && (curstack->varnum == j))
3012 assert(IS_LOCALVAR(curstack));
3013 SET_TEMPVAR(curstack);
3016 /* remember the stack boundary at this store */
3018 last_store_boundary[javaindex] = sd.new;
3020 STORE(opcode - ICMD_ISTORE, j);
3026 coalescing_boundary = sd.new;
3027 iptr->flags.bits |= INS_FLAG_CHECK;
3028 COUNT(count_check_null);
3029 COUNT(count_check_bound);
3030 COUNT(count_pcmd_mem);
3032 bte = builtintable_get_internal(BUILTIN_canstore);
3035 if (md->memuse > rd->memuse)
3036 rd->memuse = md->memuse;
3037 if (md->argintreguse > rd->argintreguse)
3038 rd->argintreguse = md->argintreguse;
3039 /* XXX non-leaf method? */
3041 /* make all stack variables saved */
3045 sd.var[copy->varnum].flags |= SAVEDVAR;
3046 /* in case copy->varnum is/will be a LOCALVAR */
3047 /* once and set back to a non LOCALVAR */
3048 /* the correct SAVEDVAR flag has to be */
3049 /* remembered in copy->flags, too */
3050 copy->flags |= SAVEDVAR;
3054 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3061 coalescing_boundary = sd.new;
3062 iptr->flags.bits |= INS_FLAG_CHECK;
3063 COUNT(count_check_null);
3064 COUNT(count_check_bound);
3065 COUNT(count_pcmd_mem);
3066 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3073 coalescing_boundary = sd.new;
3074 iptr->flags.bits |= INS_FLAG_CHECK;
3075 COUNT(count_check_null);
3076 COUNT(count_check_bound);
3077 COUNT(count_pcmd_mem);
3078 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3084 #ifdef ENABLE_VERIFIER
3087 if (IS_2_WORD_TYPE(curstack->type))
3088 goto throw_stack_category_error;
3099 coalescing_boundary = sd.new;
3100 IF_JIT( md_return_alloc(jd, curstack); )
3101 COUNT(count_pcmd_return);
3102 OP1_0(opcode - ICMD_IRETURN);
3103 superblockend = true;
3107 coalescing_boundary = sd.new;
3108 COUNT(count_check_null);
3110 curstack = NULL; stackdepth = 0;
3111 superblockend = true;
3114 case ICMD_PUTSTATIC:
3115 coalescing_boundary = sd.new;
3116 COUNT(count_pcmd_mem);
3117 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3118 OP1_0(fmiref->parseddesc.fd->type);
3121 /* pop 1 push 0 branch */
3124 case ICMD_IFNONNULL:
3125 COUNT(count_pcmd_bra);
3126 OP1_BRANCH(TYPE_ADR);
3136 COUNT(count_pcmd_bra);
3137 /* iptr->sx.val.i is set implicitly in parse by
3138 clearing the memory or from IF_ICMPxx
3141 OP1_BRANCH(TYPE_INT);
3142 /* iptr->sx.val.i = 0; */
3146 /* pop 0 push 0 branch */
3149 COUNT(count_pcmd_bra);
3152 superblockend = true;
3155 /* pop 1 push 0 table branch */
3157 case ICMD_TABLESWITCH:
3158 COUNT(count_pcmd_table);
3159 OP1_BRANCH(TYPE_INT);
3161 table = iptr->dst.table;
3162 BRANCH_TARGET(*table, tbptr);
3165 i = iptr->sx.s23.s3.tablehigh
3166 - iptr->sx.s23.s2.tablelow + 1;
3169 BRANCH_TARGET(*table, tbptr);
3172 superblockend = true;
3175 /* pop 1 push 0 table branch */
3177 case ICMD_LOOKUPSWITCH:
3178 COUNT(count_pcmd_table);
3179 OP1_BRANCH(TYPE_INT);
3181 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3183 lookup = iptr->dst.lookup;
3185 i = iptr->sx.s23.s2.lookupcount;
3188 BRANCH_TARGET(lookup->target, tbptr);
3191 superblockend = true;
3194 case ICMD_MONITORENTER:
3195 case ICMD_MONITOREXIT:
3196 coalescing_boundary = sd.new;
3197 COUNT(count_check_null);
3201 /* pop 2 push 0 branch */
3203 case ICMD_IF_ICMPEQ:
3204 case ICMD_IF_ICMPNE:
3205 case ICMD_IF_ICMPLT:
3206 case ICMD_IF_ICMPGE:
3207 case ICMD_IF_ICMPGT:
3208 case ICMD_IF_ICMPLE:
3209 COUNT(count_pcmd_bra);
3210 OP2_BRANCH(TYPE_INT, TYPE_INT);
3214 case ICMD_IF_ACMPEQ:
3215 case ICMD_IF_ACMPNE:
3216 COUNT(count_pcmd_bra);
3217 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3224 coalescing_boundary = sd.new;
3225 COUNT(count_check_null);
3226 COUNT(count_pcmd_mem);
3227 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3228 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3233 if (!IS_2_WORD_TYPE(curstack->type)) {
3235 #ifdef ENABLE_VERIFIER
3238 if (IS_2_WORD_TYPE(curstack->prev->type))
3239 goto throw_stack_category_error;
3242 OP2_0_ANY_ANY; /* pop two slots */
3245 iptr->opc = ICMD_POP;
3246 OP1_0_ANY; /* pop one (two-word) slot */
3250 /* pop 0 push 1 dup */
3253 #ifdef ENABLE_VERIFIER
3256 if (IS_2_WORD_TYPE(curstack->type))
3257 goto throw_stack_category_error;
3260 COUNT(count_dup_instruction);
3266 coalescing_boundary = sd.new - 1;
3271 if (IS_2_WORD_TYPE(curstack->type)) {
3273 iptr->opc = ICMD_DUP;
3278 /* ..., ????, cat1 */
3279 #ifdef ENABLE_VERIFIER
3281 if (IS_2_WORD_TYPE(curstack->prev->type))
3282 goto throw_stack_category_error;
3285 src1 = curstack->prev;
3288 COPY_UP(src1); iptr++; len--;
3291 coalescing_boundary = sd.new;
3295 /* pop 2 push 3 dup */
3298 #ifdef ENABLE_VERIFIER
3301 if (IS_2_WORD_TYPE(curstack->type) ||
3302 IS_2_WORD_TYPE(curstack->prev->type))
3303 goto throw_stack_category_error;
3308 src1 = curstack->prev;
3313 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3315 MOVE_UP(src1); iptr++; len--;
3316 MOVE_UP(src2); iptr++; len--;
3318 COPY_DOWN(curstack, dst1);
3320 coalescing_boundary = sd.new;
3325 if (IS_2_WORD_TYPE(curstack->type)) {
3326 /* ..., ????, cat2 */
3327 #ifdef ENABLE_VERIFIER
3329 if (IS_2_WORD_TYPE(curstack->prev->type))
3330 goto throw_stack_category_error;
3333 iptr->opc = ICMD_DUP_X1;
3337 /* ..., ????, cat1 */
3338 #ifdef ENABLE_VERIFIER
3341 if (IS_2_WORD_TYPE(curstack->prev->type)
3342 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3343 goto throw_stack_category_error;
3348 src1 = curstack->prev->prev;
3349 src2 = curstack->prev;
3351 POPANY; POPANY; POPANY;
3354 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3355 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3357 MOVE_UP(src1); iptr++; len--;
3358 MOVE_UP(src2); iptr++; len--;
3359 MOVE_UP(src3); iptr++; len--;
3361 COPY_DOWN(curstack, dst2); iptr++; len--;
3362 COPY_DOWN(curstack->prev, dst1);
3364 coalescing_boundary = sd.new;
3368 /* pop 3 push 4 dup */
3372 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3373 /* ..., cat2, ???? */
3374 #ifdef ENABLE_VERIFIER
3376 if (IS_2_WORD_TYPE(curstack->type))
3377 goto throw_stack_category_error;
3380 iptr->opc = ICMD_DUP_X1;
3384 /* ..., cat1, ???? */
3385 #ifdef ENABLE_VERIFIER
3388 if (IS_2_WORD_TYPE(curstack->type)
3389 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3390 goto throw_stack_category_error;
3394 src1 = curstack->prev->prev;
3395 src2 = curstack->prev;
3397 POPANY; POPANY; POPANY;
3400 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3402 MOVE_UP(src1); iptr++; len--;
3403 MOVE_UP(src2); iptr++; len--;
3404 MOVE_UP(src3); iptr++; len--;
3406 COPY_DOWN(curstack, dst1);
3408 coalescing_boundary = sd.new;
3414 if (IS_2_WORD_TYPE(curstack->type)) {
3415 /* ..., ????, cat2 */
3416 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3417 /* ..., cat2, cat2 */
3418 iptr->opc = ICMD_DUP_X1;
3422 /* ..., cat1, cat2 */
3423 #ifdef ENABLE_VERIFIER
3426 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3427 goto throw_stack_category_error;
3430 iptr->opc = ICMD_DUP_X2;
3436 /* ..., ????, ????, cat1 */
3438 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3439 /* ..., cat2, ????, cat1 */
3440 #ifdef ENABLE_VERIFIER
3442 if (IS_2_WORD_TYPE(curstack->prev->type))
3443 goto throw_stack_category_error;
3446 iptr->opc = ICMD_DUP2_X1;
3450 /* ..., cat1, ????, cat1 */
3451 #ifdef ENABLE_VERIFIER
3454 if (IS_2_WORD_TYPE(curstack->prev->type)
3455 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3456 goto throw_stack_category_error;
3460 src1 = curstack->prev->prev->prev;
3461 src2 = curstack->prev->prev;
3462 src3 = curstack->prev;
3464 POPANY; POPANY; POPANY; POPANY;
3467 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3468 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3470 MOVE_UP(src1); iptr++; len--;
3471 MOVE_UP(src2); iptr++; len--;
3472 MOVE_UP(src3); iptr++; len--;
3473 MOVE_UP(src4); iptr++; len--;
3475 COPY_DOWN(curstack, dst2); iptr++; len--;
3476 COPY_DOWN(curstack->prev, dst1);
3478 coalescing_boundary = sd.new;
3482 /* pop 2 push 2 swap */
3485 #ifdef ENABLE_VERIFIER
3488 if (IS_2_WORD_TYPE(curstack->type)
3489 || IS_2_WORD_TYPE(curstack->prev->type))
3490 goto throw_stack_category_error;
3494 src1 = curstack->prev;
3499 MOVE_UP(src2); iptr++; len--;
3502 coalescing_boundary = sd.new;
3509 coalescing_boundary = sd.new;
3510 #if !SUPPORT_DIVISION
3511 bte = iptr->sx.s23.s3.bte;
3514 if (md->memuse > rd->memuse)
3515 rd->memuse = md->memuse;
3516 if (md->argintreguse > rd->argintreguse)
3517 rd->argintreguse = md->argintreguse;
3519 /* make all stack variables saved */
3523 sd.var[copy->varnum].flags |= SAVEDVAR;
3524 copy->flags |= SAVEDVAR;
3529 #endif /* !SUPPORT_DIVISION */
3540 COUNT(count_pcmd_op);
3541 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3546 coalescing_boundary = sd.new;
3547 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3548 bte = iptr->sx.s23.s3.bte;
3551 if (md->memuse > rd->memuse)
3552 rd->memuse = md->memuse;
3553 if (md->argintreguse > rd->argintreguse)
3554 rd->argintreguse = md->argintreguse;
3555 /* XXX non-leaf method? */
3557 /* make all stack variables saved */
3561 sd.var[copy->varnum].flags |= SAVEDVAR;
3562 copy->flags |= SAVEDVAR;
3567 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3572 #if SUPPORT_LONG_LOGICAL
3576 #endif /* SUPPORT_LONG_LOGICAL */
3577 COUNT(count_pcmd_op);
3578 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3584 COUNT(count_pcmd_op);
3585 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3593 COUNT(count_pcmd_op);
3594 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3602 COUNT(count_pcmd_op);
3603 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3607 COUNT(count_pcmd_op);
3608 #if SUPPORT_LONG_CMP_CONST
3609 if ((len == 0) || (iptr[1].sx.val.i != 0))
3612 switch (iptr[1].opc) {
3614 iptr->opc = ICMD_IF_LCMPEQ;
3616 iptr->dst.insindex = iptr[1].dst.insindex;
3617 iptr[1].opc = ICMD_NOP;
3619 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3622 COUNT(count_pcmd_bra);
3625 iptr->opc = ICMD_IF_LCMPNE;
3626 goto icmd_lcmp_if_tail;
3628 iptr->opc = ICMD_IF_LCMPLT;
3629 goto icmd_lcmp_if_tail;
3631 iptr->opc = ICMD_IF_LCMPGT;
3632 goto icmd_lcmp_if_tail;
3634 iptr->opc = ICMD_IF_LCMPLE;
3635 goto icmd_lcmp_if_tail;
3637 iptr->opc = ICMD_IF_LCMPGE;
3638 goto icmd_lcmp_if_tail;
3644 #endif /* SUPPORT_LONG_CMP_CONST */
3645 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3648 /* XXX why is this deactivated? */
3651 COUNT(count_pcmd_op);
3652 if ((len == 0) || (iptr[1].sx.val.i != 0))
3655 switch (iptr[1].opc) {
3657 iptr->opc = ICMD_IF_FCMPEQ;
3659 iptr->dst.insindex = iptr[1].dst.insindex;
3660 iptr[1].opc = ICMD_NOP;
3662 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3665 COUNT(count_pcmd_bra);
3668 iptr->opc = ICMD_IF_FCMPNE;
3669 goto icmd_if_fcmpl_tail;
3671 iptr->opc = ICMD_IF_FCMPL_LT;
3672 goto icmd_if_fcmpl_tail;
3674 iptr->opc = ICMD_IF_FCMPL_GT;
3675 goto icmd_if_fcmpl_tail;
3677 iptr->opc = ICMD_IF_FCMPL_LE;
3678 goto icmd_if_fcmpl_tail;
3680 iptr->opc = ICMD_IF_FCMPL_GE;
3681 goto icmd_if_fcmpl_tail;
3688 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3692 COUNT(count_pcmd_op);
3693 if ((len == 0) || (iptr[1].sx.val.i != 0))
3696 switch (iptr[1].opc) {
3698 iptr->opc = ICMD_IF_FCMPEQ;
3700 iptr->dst.insindex = iptr[1].dst.insindex;
3701 iptr[1].opc = ICMD_NOP;
3703 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3706 COUNT(count_pcmd_bra);
3709 iptr->opc = ICMD_IF_FCMPNE;
3710 goto icmd_if_fcmpg_tail;
3712 iptr->opc = ICMD_IF_FCMPG_LT;
3713 goto icmd_if_fcmpg_tail;
3715 iptr->opc = ICMD_IF_FCMPG_GT;
3716 goto icmd_if_fcmpg_tail;
3718 iptr->opc = ICMD_IF_FCMPG_LE;
3719 goto icmd_if_fcmpg_tail;
3721 iptr->opc = ICMD_IF_FCMPG_GE;
3722 goto icmd_if_fcmpg_tail;
3729 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3733 COUNT(count_pcmd_op);
3734 if ((len == 0) || (iptr[1].sx.val.i != 0))
3737 switch (iptr[1].opc) {
3739 iptr->opc = ICMD_IF_DCMPEQ;
3741 iptr->dst.insindex = iptr[1].dst.insindex;
3742 iptr[1].opc = ICMD_NOP;
3744 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3747 COUNT(count_pcmd_bra);
3750 iptr->opc = ICMD_IF_DCMPNE;
3751 goto icmd_if_dcmpl_tail;
3753 iptr->opc = ICMD_IF_DCMPL_LT;
3754 goto icmd_if_dcmpl_tail;
3756 iptr->opc = ICMD_IF_DCMPL_GT;
3757 goto icmd_if_dcmpl_tail;
3759 iptr->opc = ICMD_IF_DCMPL_LE;
3760 goto icmd_if_dcmpl_tail;
3762 iptr->opc = ICMD_IF_DCMPL_GE;
3763 goto icmd_if_dcmpl_tail;
3770 OPTT2_1(TYPE_DBL, TYPE_INT);
3774 COUNT(count_pcmd_op);
3775 if ((len == 0) || (iptr[1].sx.val.i != 0))
3778 switch (iptr[1].opc) {
3780 iptr->opc = ICMD_IF_DCMPEQ;
3782 iptr->dst.insindex = iptr[1].dst.insindex;
3783 iptr[1].opc = ICMD_NOP;
3785 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3788 COUNT(count_pcmd_bra);
3791 iptr->opc = ICMD_IF_DCMPNE;
3792 goto icmd_if_dcmpg_tail;
3794 iptr->opc = ICMD_IF_DCMPG_LT;
3795 goto icmd_if_dcmpg_tail;
3797 iptr->opc = ICMD_IF_DCMPG_GT;
3798 goto icmd_if_dcmpg_tail;
3800 iptr->opc = ICMD_IF_DCMPG_LE;
3801 goto icmd_if_dcmpg_tail;
3803 iptr->opc = ICMD_IF_DCMPG_GE;
3804 goto icmd_if_dcmpg_tail;
3811 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3816 COUNT(count_pcmd_op);
3817 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3822 COUNT(count_pcmd_op);
3823 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3832 case ICMD_INT2SHORT:
3833 COUNT(count_pcmd_op);
3834 OP1_1(TYPE_INT, TYPE_INT);
3837 COUNT(count_pcmd_op);
3838 OP1_1(TYPE_LNG, TYPE_LNG);
3841 COUNT(count_pcmd_op);
3842 OP1_1(TYPE_FLT, TYPE_FLT);
3845 COUNT(count_pcmd_op);
3846 OP1_1(TYPE_DBL, TYPE_DBL);
3850 COUNT(count_pcmd_op);
3851 OP1_1(TYPE_INT, TYPE_LNG);
3854 COUNT(count_pcmd_op);
3855 OP1_1(TYPE_INT, TYPE_FLT);
3858 COUNT(count_pcmd_op);
3859 OP1_1(TYPE_INT, TYPE_DBL);
3862 COUNT(count_pcmd_op);
3863 OP1_1(TYPE_LNG, TYPE_INT);
3866 COUNT(count_pcmd_op);
3867 OP1_1(TYPE_LNG, TYPE_FLT);
3870 COUNT(count_pcmd_op);
3871 OP1_1(TYPE_LNG, TYPE_DBL);
3874 COUNT(count_pcmd_op);
3875 OP1_1(TYPE_FLT, TYPE_INT);
3878 COUNT(count_pcmd_op);
3879 OP1_1(TYPE_FLT, TYPE_LNG);
3882 COUNT(count_pcmd_op);
3883 OP1_1(TYPE_FLT, TYPE_DBL);
3886 COUNT(count_pcmd_op);
3887 OP1_1(TYPE_DBL, TYPE_INT);
3890 COUNT(count_pcmd_op);
3891 OP1_1(TYPE_DBL, TYPE_LNG);
3894 COUNT(count_pcmd_op);
3895 OP1_1(TYPE_DBL, TYPE_FLT);
3898 case ICMD_CHECKCAST:
3899 coalescing_boundary = sd.new;
3900 if (iptr->flags.bits & INS_FLAG_ARRAY) {
3901 /* array type cast-check */
3903 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
3906 if (md->memuse > rd->memuse)
3907 rd->memuse = md->memuse;
3908 if (md->argintreguse > rd->argintreguse)
3909 rd->argintreguse = md->argintreguse;
3911 /* make all stack variables saved */
3915 sd.var[copy->varnum].flags |= SAVEDVAR;
3916 copy->flags |= SAVEDVAR;
3920 OP1_1(TYPE_ADR, TYPE_ADR);
3923 case ICMD_INSTANCEOF:
3924 case ICMD_ARRAYLENGTH:
3925 coalescing_boundary = sd.new;
3926 OP1_1(TYPE_ADR, TYPE_INT);
3930 case ICMD_ANEWARRAY:
3931 coalescing_boundary = sd.new;
3932 OP1_1(TYPE_INT, TYPE_ADR);
3936 coalescing_boundary = sd.new;
3937 COUNT(count_check_null);
3938 COUNT(count_pcmd_mem);
3939 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3940 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
3945 case ICMD_GETSTATIC:
3946 coalescing_boundary = sd.new;
3947 COUNT(count_pcmd_mem);
3948 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3949 OP0_1(fmiref->parseddesc.fd->type);
3953 coalescing_boundary = sd.new;
3960 assert(sd.bptr->next); /* XXX exception */
3961 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
3963 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
3964 tbptr->type = BBTYPE_SBR;
3966 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
3970 iptr->sx.s23.s3.jsrtarget.block = tbptr;
3972 /* We need to check for overflow right here because
3973 * the pushed value is poped afterwards */
3976 superblockend = true;
3977 /* XXX should not be marked as interface, as it does not need to be */
3978 /* allocated. Same for the invar of the target. */
3981 /* pop many push any */
3985 bte = iptr->sx.s23.s3.bte;
3989 case ICMD_INVOKESTATIC:
3990 case ICMD_INVOKESPECIAL:
3991 case ICMD_INVOKEVIRTUAL:
3992 case ICMD_INVOKEINTERFACE:
3993 COUNT(count_pcmd_met);
3995 /* Check for functions to replace with builtin
3998 if (builtintable_replace_function(iptr))
4001 INSTRUCTION_GET_METHODDESC(iptr, md);
4002 /* XXX resurrect this COUNT? */
4003 /* if (lm->flags & ACC_STATIC) */
4004 /* {COUNT(count_check_null);} */
4008 coalescing_boundary = sd.new;
4012 if (md->memuse > rd->memuse)
4013 rd->memuse = md->memuse;
4014 if (md->argintreguse > rd->argintreguse)
4015 rd->argintreguse = md->argintreguse;
4016 if (md->argfltreguse > rd->argfltreguse)
4017 rd->argfltreguse = md->argfltreguse;
4021 /* XXX optimize for <= 2 args */
4022 /* XXX not for ICMD_BUILTIN */
4023 iptr->s1.argcount = stackdepth;
4024 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4027 for (i-- ; i >= 0; i--) {
4028 iptr->sx.s23.s2.args[i] = copy->varnum;
4030 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4031 /* -> won't help anyway */
4032 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
4034 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4035 /* If we pass float arguments in integer argument registers, we
4036 * are not allowed to precolor them here. Floats have to be moved
4037 * to this regs explicitly in codegen().
4038 * Only arguments that are passed by stack anyway can be precolored
4039 * (michi 2005/07/24) */
4040 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4041 (!IS_FLT_DBL_TYPE(copy->type)
4042 || md->params[i].inmemory)) {
4044 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4049 #if defined(ENABLE_INTRP)
4052 if (md->params[i].inmemory) {
4053 sd.var[copy->varnum].vv.regoff =
4054 md->params[i].regoff;
4055 sd.var[copy->varnum].flags |=
4059 if (IS_FLT_DBL_TYPE(copy->type)) {
4060 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4061 assert(0); /* XXX is this assert ok? */
4063 sd.var[copy->varnum].vv.regoff =
4064 rd->argfltregs[md->params[i].regoff];
4065 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4068 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4069 if (IS_2_WORD_TYPE(copy->type))
4070 sd.var[copy->varnum].vv.regoff =
4071 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4072 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4075 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4076 sd.var[copy->varnum].vv.regoff =
4077 rd->argintregs[md->params[i].regoff];
4080 #if defined(ENABLE_INTRP)
4081 } /* end if (!opt_intrp) */
4088 /* deal with live-through stack slots "under" the */
4090 /* XXX not for ICMD_BUILTIN */
4096 iptr->sx.s23.s2.args[i++] = copy->varnum;
4097 sd.var[copy->varnum].flags |= SAVEDVAR;
4101 /* pop the arguments */
4110 /* push the return value */
4112 if (md->returntype.type != TYPE_VOID) {
4113 GET_NEW_VAR(sd, new_index, md->returntype.type);
4114 DST(md->returntype.type, new_index);
4119 case ICMD_INLINE_START:
4120 case ICMD_INLINE_END:
4125 case ICMD_MULTIANEWARRAY:
4126 coalescing_boundary = sd.new;
4127 if (rd->argintreguse < 3)
4128 rd->argintreguse = 3;
4130 i = iptr->s1.argcount;
4134 iptr->sx.s23.s2.args = DMNEW(s4, i);
4136 #if defined(SPECIALMEMUSE)
4137 # if defined(__DARWIN__)
4138 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4139 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4141 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4142 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4145 # if defined(__I386__)
4146 if (rd->memuse < i + 3)
4147 rd->memuse = i + 3; /* n integer args spilled on stack */
4148 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4149 if (rd->memuse < i + 2)
4150 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4153 rd->memuse = i; /* n integer args spilled on stack */
4154 # endif /* defined(__I386__) */
4158 /* check INT type here? Currently typecheck does this. */
4159 iptr->sx.s23.s2.args[i] = copy->varnum;
4160 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4161 && (!IS_OUTVAR(copy))
4162 && (!IS_LOCALVAR(copy)) ) {
4163 copy->varkind = ARGVAR;
4164 sd.var[copy->varnum].flags |=
4165 INMEMORY & PREALLOC;
4166 #if defined(SPECIALMEMUSE)
4167 # if defined(__DARWIN__)
4168 sd.var[copy->varnum].vv.regoff = i +
4169 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4171 sd.var[copy->varnum].vv.regoff = i +
4172 LA_SIZE_IN_POINTERS + 3;
4175 # if defined(__I386__)
4176 sd.var[copy->varnum].vv.regoff = i + 3;
4177 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4178 sd.var[copy->varnum].vv.regoff = i + 2;
4180 sd.var[copy->varnum].vv.regoff = i;
4181 # endif /* defined(__I386__) */
4182 #endif /* defined(SPECIALMEMUSE) */
4187 sd.var[copy->varnum].flags |= SAVEDVAR;
4191 i = iptr->s1.argcount;
4196 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4197 DST(TYPE_ADR, new_index);
4203 new_internalerror("Unknown ICMD %d", opcode);
4209 } /* while instructions */
4211 /* stack slots at basic block end become interfaces */
4213 sd.bptr->outdepth = stackdepth;
4214 sd.bptr->outvars = DMNEW(s4, stackdepth);
4217 for (copy = curstack; copy; i--, copy = copy->prev) {
4221 /* with the new vars rd->interfaces will be removed */
4222 /* and all in and outvars have to be STACKVARS! */
4223 /* in the moment i.e. SWAP with in and out vars can */
4224 /* create an unresolvable conflict */
4231 v = sd.var + copy->varnum;
4234 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4235 /* no interface var until now for this depth and */
4237 jd->interface_map[i*5 + t].flags = v->flags;
4240 jd->interface_map[i*5 + t].flags |= v->flags;
4243 sd.bptr->outvars[i] = copy->varnum;
4246 /* check if interface slots at basic block begin must be saved */
4248 for (i=0; i<sd.bptr->indepth; ++i) {
4249 varinfo *v = sd.var + sd.bptr->invars[i];
4256 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4257 /* no interface var until now for this depth and */
4259 jd->interface_map[i*5 + t].flags = v->flags;
4262 jd->interface_map[i*5 + t].flags |= v->flags;
4267 /* store the number of this block's variables */
4269 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4271 #if defined(STACK_VERBOSE)
4272 stack_verbose_block_exit(&sd, superblockend);
4275 /* reach the following block, if any */
4278 if (!stack_reach_next_block(&sd))
4283 } while (sd.repeat && !deadcode);
4285 /* XXX reset TYPE_RET to TYPE_ADR */
4287 for (i=0; i<sd.vartop; ++i) {
4288 if (sd.var[i].type == TYPE_RET)
4289 sd.var[i].type = TYPE_ADR;
4292 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4294 ex = cd->exceptiontable;
4295 for (; ex != NULL; ex = ex->down) {
4296 if (ex->start == ex->end) {
4297 assert(ex->end->next);
4298 ex->end = ex->end->next;
4302 /* gather statistics *****************************************************/
4304 #if defined(ENABLE_STATISTICS)
4306 if (jd->new_basicblockcount > count_max_basic_blocks)
4307 count_max_basic_blocks = jd->new_basicblockcount;
4308 count_basic_blocks += jd->new_basicblockcount;
4309 if (jd->new_instructioncount > count_max_javainstr)
4310 count_max_javainstr = jd->new_instructioncount;
4311 count_javainstr += jd->new_instructioncount;
4312 if (jd->new_stackcount > count_upper_bound_new_stack)
4313 count_upper_bound_new_stack = jd->new_stackcount;
4314 if ((sd.new - jd->new_stack) > count_max_new_stack)
4315 count_max_new_stack = (sd.new - jd->new_stack);
4317 sd.bptr = jd->new_basicblocks;
4318 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4319 if (sd.bptr->flags > BBREACHED) {
4320 if (sd.bptr->indepth >= 10)
4321 count_block_stack[10]++;
4323 count_block_stack[sd.bptr->indepth]++;
4324 len = sd.bptr->icount;
4326 count_block_size_distribution[len]++;
4328 count_block_size_distribution[10]++;
4330 count_block_size_distribution[11]++;
4332 count_block_size_distribution[12]++;
4334 count_block_size_distribution[13]++;
4336 count_block_size_distribution[14]++;
4338 count_block_size_distribution[15]++;
4340 count_block_size_distribution[16]++;
4342 count_block_size_distribution[17]++;
4346 if (iteration_count == 1)
4347 count_analyse_iterations[0]++;
4348 else if (iteration_count == 2)
4349 count_analyse_iterations[1]++;
4350 else if (iteration_count == 3)
4351 count_analyse_iterations[2]++;
4352 else if (iteration_count == 4)
4353 count_analyse_iterations[3]++;
4355 count_analyse_iterations[4]++;
4357 if (jd->new_basicblockcount <= 5)
4358 count_method_bb_distribution[0]++;
4359 else if (jd->new_basicblockcount <= 10)
4360 count_method_bb_distribution[1]++;
4361 else if (jd->new_basicblockcount <= 15)
4362 count_method_bb_distribution[2]++;
4363 else if (jd->new_basicblockcount <= 20)
4364 count_method_bb_distribution[3]++;
4365 else if (jd->new_basicblockcount <= 30)
4366 count_method_bb_distribution[4]++;
4367 else if (jd->new_basicblockcount <= 40)
4368 count_method_bb_distribution[5]++;
4369 else if (jd->new_basicblockcount <= 50)
4370 count_method_bb_distribution[6]++;
4371 else if (jd->new_basicblockcount <= 75)
4372 count_method_bb_distribution[7]++;
4374 count_method_bb_distribution[8]++;
4376 #endif /* defined(ENABLE_STATISTICS) */
4378 /* everything's ok *******************************************************/
4382 /* goto labels for throwing verifier exceptions **************************/
4384 #if defined(ENABLE_VERIFIER)
4386 throw_stack_underflow:
4387 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4390 throw_stack_overflow:
4391 exceptions_throw_verifyerror(m, "Stack size too large");
4394 throw_stack_depth_error:
4395 exceptions_throw_verifyerror(m,"Stack depth mismatch");
4398 throw_stack_type_error:
4399 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4402 throw_stack_category_error:
4403 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4410 /* functions for verbose stack analysis output ********************************/
4412 #if defined(STACK_VERBOSE)
4413 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4415 printf("%c", show_jit_type_letters[v->type]);
4416 if (v->type == TYPE_RET)
4417 printf("{L%03d}", v->vv.retaddr->nr);
4421 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4423 assert(index >= 0 && index < sd->vartop);
4424 stack_verbose_show_varinfo(sd, sd->var + index);
4428 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4432 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4434 for (i=0; i<bptr->indepth; ++i) {
4437 stack_verbose_show_variable(sd, bptr->invars[i]);
4442 printf("] inlocals [");
4443 if (bptr->inlocals) {
4444 for (i=0; i<sd->localcount; ++i) {
4447 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4452 printf("] out:%d [", bptr->outdepth);
4453 if (bptr->outvars) {
4454 for (i=0; i<bptr->outdepth; ++i) {
4457 stack_verbose_show_variable(sd, bptr->outvars[i]);
4465 printf(" (clone of L%03d)", bptr->original->nr);
4467 basicblock *b = bptr->copied_to;
4469 printf(" (copied to ");
4470 for (; b; b = b->copied_to)
4471 printf("L%03d ", b->nr);
4478 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4482 printf("======================================== STACK %sANALYSE BLOCK ",
4483 (reanalyse) ? "RE-" : "");
4484 stack_verbose_show_block(sd, sd->bptr);
4487 if (sd->handlers[0]) {
4488 printf("HANDLERS: ");
4489 for (i=0; sd->handlers[i]; ++i) {
4490 printf("L%03d ", sd->handlers[i]->handler->nr);
4498 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4500 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4501 stack_verbose_show_block(sd, sd->bptr);
4508 * These are local overrides for various environment variables in Emacs.
4509 * Please do not remove this and leave it at the end of the file, where
4510 * Emacs will automagically detect them.
4511 * ---------------------------------------------------------------------
4514 * indent-tabs-mode: t
4518 * vim:noexpandtab:sw=4:ts=4: