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 5472 2006-09-11 23:24:46Z 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 #if defined(ENABLE_VERIFIER)
473 #define MARKREACHED(b, c) \
475 if (!stack_mark_reached(&sd, (b), curstack, stackdepth)) \
479 #define MARKREACHED(b, c) \
481 (void) stack_mark_reached(&sd, (b), curstack, stackdepth); \
485 #define BRANCH_TARGET(bt, tempbptr, tempsp) \
487 (bt).block = tempbptr = BLOCK_OF((bt).insindex); \
488 MARKREACHED(tempbptr, tempsp); \
491 #define BRANCH(tempbptr, tempsp) \
493 iptr->dst.block = tempbptr = BLOCK_OF(iptr->dst.insindex); \
494 MARKREACHED(tempbptr, tempsp); \
498 /* forward declarations *******************************************************/
500 static void stack_create_invars(stackdata_t *sd, basicblock *b,
501 stackptr curstack, int stackdepth);
502 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
504 #if defined(STACK_VERBOSE)
505 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
506 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
507 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
508 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
509 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
513 /* stack_init ******************************************************************
515 Initialized the stack analysis subsystem (called by jit_init).
517 *******************************************************************************/
519 bool stack_init(void)
525 /* stack_grow_variable_array ***************************************************
527 Grow the variable array so the given number of additional variables fits in.
530 sd...........stack analysis data
531 num..........number of additional variables
533 *******************************************************************************/
535 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
544 /* XXX avoid too many reallocations */
545 newcount = sd->varcount + num;
547 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
548 sd->varcount = newcount;
549 sd->jd->var = sd->var;
550 sd->jd->varcount = newcount;
554 /* stack_append_block **********************************************************
556 Append the given block after the last real block of the method (before
557 the pseudo-block at the end).
560 sd...........stack analysis data
561 b............the block to append
563 *******************************************************************************/
565 static void stack_append_block(stackdata_t *sd, basicblock *b)
567 #if defined(STACK_VERBOSE)
568 printf("APPENDING BLOCK L%0d\n", b->nr);
571 b->next = sd->last_real_block->next;
572 sd->last_real_block->next = b;
573 sd->last_real_block = b;
574 sd->jd->new_basicblockcount++;
578 /* stack_clone_block ***********************************************************
580 Create a copy of the given block and insert it at the end of the method.
582 CAUTION: This function does not copy the any variables or the instruction
583 list. It _does_, however, reserve space for the block's invars in the
587 sd...........stack analysis data
588 b............the block to clone
591 a pointer to the copy
593 *******************************************************************************/
595 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
599 clone = DNEW(basicblock);
602 clone->iinstr = NULL;
603 clone->inlocals = NULL;
604 clone->invars = NULL;
606 clone->original = (b->original) ? b->original : b;
607 clone->copied_to = clone->original->copied_to;
608 clone->original->copied_to = clone;
609 clone->nr = sd->m->c_debug_nr++;
611 clone->flags = BBREACHED;
613 stack_append_block(sd, clone);
615 /* allocate space for the invars of the clone */
617 stack_grow_variable_array(sd, b->indepth);
619 #if defined(STACK_VERBOSE)
620 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
627 /* stack_create_invars *********************************************************
629 Create the invars for the given basic block. Also make a copy of the locals.
632 sd...........stack analysis data
633 b............block to create the invars for
634 curstack.....current stack top
635 stackdepth...current stack depth
637 This function creates STACKDEPTH invars and sets their types to the
638 types to the types of the corresponding slot in the current stack.
640 *******************************************************************************/
642 static void stack_create_invars(stackdata_t *sd, basicblock *b,
643 stackptr curstack, int stackdepth)
650 assert(sd->vartop + stackdepth <= sd->varcount);
652 b->indepth = stackdepth;
653 b->invars = DMNEW(s4, stackdepth);
655 /* allocate the variable indices */
656 index = (sd->vartop += stackdepth);
659 for (sp = curstack; i--; sp = sp->prev) {
660 b->invars[i] = --index;
664 v->vv = sd->var[sp->varnum].vv;
665 #if defined(STACK_VERBOSE) && 0
666 printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
670 /* copy the current state of the local variables */
672 v = DMNEW(varinfo, sd->localcount);
674 for (i=0; i<sd->localcount; ++i)
679 /* stack_create_invars_from_outvars ********************************************
681 Create the invars for the given basic block. Also make a copy of the locals.
682 Types are propagated from the outvars of the current block.
685 sd...........stack analysis data
686 b............block to create the invars for
688 *******************************************************************************/
690 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
696 n = sd->bptr->outdepth;
697 assert(sd->vartop + n <= sd->varcount);
700 b->invars = DMNEW(s4, n);
703 dv = sd->var + sd->vartop;
705 /* allocate the invars */
707 for (i=0; i<n; ++i, ++dv) {
708 sv = sd->var + sd->bptr->outvars[i];
709 b->invars[i] = sd->vartop++;
716 /* copy the current state of the local variables */
718 dv = DMNEW(varinfo, sd->localcount);
720 for (i=0; i<sd->localcount; ++i)
725 /* stack_check_invars **********************************************************
727 Check the current stack against the invars of the given basic block.
728 Depth and types must match.
731 sd...........stack analysis data
732 b............block which invars to check against
733 curstack.....current stack top
734 stackdepth...current stack depth
738 NULL.........a VerifyError has been thrown
740 *******************************************************************************/
742 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
743 stackptr curstack, int stackdepth)
750 #if defined(STACK_VERBOSE)
751 printf("stack_check_invars(L%03d)\n", b->nr);
754 /* find original of b */
759 #if defined(STACK_VERBOSE)
760 printf("original is L%03d\n", orig->nr);
765 if (i != stackdepth) {
766 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
773 #if defined(STACK_VERBOSE)
774 printf("checking against ");
775 stack_verbose_show_block(sd, b); printf("\n");
779 for (i = orig->indepth; i--; sp = sp->prev) {
780 if (sd->var[b->invars[i]].type != sp->type) {
781 exceptions_throw_verifyerror_for_stack(sd->m,
782 sd->var[b->invars[i]].type);
786 if (sp->type == TYPE_RET) {
787 if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
795 for (i=0; i<sd->localcount; ++i) {
796 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
797 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
806 /* XXX mark mixed type variables void */
807 /* XXX cascading collapse? */
808 #if defined(STACK_VERBOSE)
809 printf("------> using L%03d\n", b->nr);
813 } while ((b = b->copied_to) != NULL);
815 b = stack_clone_block(sd, orig);
819 stack_create_invars(sd, b, curstack, stackdepth);
824 /* stack_check_invars_from_outvars *********************************************
826 Check the outvars of the current block against the invars of the given block.
827 Depth and types must match.
830 sd...........stack analysis data
831 b............block which invars to check against
835 NULL.........a VerifyError has been thrown
837 *******************************************************************************/
839 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
847 #if defined(STACK_VERBOSE)
848 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
851 /* find original of b */
856 #if defined(STACK_VERBOSE)
857 printf("original is L%03d\n", orig->nr);
861 n = sd->bptr->outdepth;
864 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
871 #if defined(STACK_VERBOSE)
872 printf("checking against ");
873 stack_verbose_show_block(sd, b); printf("\n");
877 dv = sd->var + b->invars[0];
879 for (i=0; i<n; ++i, ++dv) {
880 sv = sd->var + sd->bptr->outvars[i];
881 if (sv->type != dv->type) {
882 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
886 if (dv->type == TYPE_RET) {
887 if (sv->vv.retaddr != dv->vv.retaddr) {
896 for (i=0; i<sd->localcount; ++i) {
897 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
898 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
907 /* XXX mark mixed type variables void */
908 /* XXX cascading collapse? */
909 #if defined(STACK_VERBOSE)
910 printf("------> using L%03d\n", b->nr);
914 } while ((b = b->copied_to) != NULL);
916 b = stack_clone_block(sd, orig);
920 stack_create_invars_from_outvars(sd, b);
925 /* stack_create_instack ********************************************************
927 Create the instack of the current basic block.
930 sd...........stack analysis data
933 the current stack top at the start of the basic block.
935 *******************************************************************************/
937 static stackptr stack_create_instack(stackdata_t *sd)
943 if ((depth = sd->bptr->indepth) == 0)
946 sp = (sd->new += depth);
950 index = sd->bptr->invars[depth];
952 sp->type = sd->var[index].type;
956 sp->varkind = STACKVAR;
960 /* return the top of the created stack */
965 /* stack_mark_reached **********************************************************
967 Mark the given block reached and propagate the current stack and locals to
968 it. This function specializes the target block, if necessary, and returns
969 a pointer to the specialized target.
972 sd...........stack analysis data
973 b............the block to reach
974 curstack.....the current stack top
975 stackdepth...the current stack depth
978 a pointer to (a specialized version of) the target
979 NULL.........a VerifyError has been thrown
981 *******************************************************************************/
983 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
985 #if defined(STACK_VERBOSE)
986 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
988 /* mark targets of backward branches */
990 b->bitflags |= BBFLAG_REPLACEMENT;
992 if (b->flags < BBREACHED) {
993 /* b is reached for the first time. Create its invars. */
995 #if defined(STACK_VERBOSE)
996 printf("reached L%03d for the first time\n", b->nr);
999 stack_create_invars(sd, b, curstack, stackdepth);
1001 b->flags = BBREACHED;
1006 /* b has been reached before. Check that its invars match. */
1008 return stack_check_invars(sd, b, curstack, stackdepth);
1013 /* stack_mark_reached_from_outvars *********************************************
1015 Mark the given block reached and propagate the outvars of the current block
1016 and the current locals to it. This function specializes the target block,
1017 if necessary, and returns a pointer to the specialized target.
1020 sd...........stack analysis data
1021 b............the block to reach
1024 a pointer to (a specialized version of) the target
1025 NULL.........a VerifyError has been thrown
1027 *******************************************************************************/
1029 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1031 #if defined(STACK_VERBOSE)
1032 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1034 /* mark targets of backward branches */
1036 b->bitflags |= BBFLAG_REPLACEMENT;
1038 if (b->flags < BBREACHED) {
1039 /* b is reached for the first time. Create its invars. */
1041 #if defined(STACK_VERBOSE)
1042 printf("reached L%03d for the first time\n", b->nr);
1045 stack_create_invars_from_outvars(sd, b);
1047 b->flags = BBREACHED;
1052 /* b has been reached before. Check that its invars match. */
1054 return stack_check_invars_from_outvars(sd, b);
1059 /* stack_reach_next_block ******************************************************
1061 Mark the following block reached and propagate the outvars of the current block
1062 and the current locals to it. This function specializes the target block,
1063 if necessary, and returns a pointer to the specialized target.
1066 sd...........stack analysis data
1069 a pointer to (a specialized version of) the following block
1070 NULL.........a VerifyError has been thrown
1072 *******************************************************************************/
1074 static bool stack_reach_next_block(stackdata_t *sd)
1079 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1080 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1084 if (tbptr != sd->bptr->next) {
1085 #if defined(STACK_VERBOSE)
1086 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1088 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1089 assert(iptr->opc == ICMD_NOP);
1090 iptr->opc = ICMD_GOTO;
1091 iptr->dst.block = tbptr;
1093 if (tbptr->flags < BBFINISHED)
1094 sd->repeat = true; /* XXX check if we really need to repeat */
1101 /* stack_reach_handlers ********************************************************
1103 Reach the exception handlers for the current block.
1106 sd...........stack analysis data
1109 true.........everything ok
1110 false........a VerifyError has been thrown
1112 *******************************************************************************/
1114 static bool stack_reach_handlers(stackdata_t *sd)
1119 #if defined(STACK_VERBOSE)
1120 printf("reaching exception handlers...\n");
1123 for (i=0; sd->handlers[i]; ++i) {
1124 tbptr = sd->handlers[i]->handler;
1126 tbptr->type = BBTYPE_EXH;
1127 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1129 /* reach (and specialize) the handler block */
1131 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1136 sd->handlers[i]->handler = tbptr;
1143 /* stack_reanalyse_block ******************************************************
1145 Re-analyse the current block. This is called if either the block itself
1146 has already been analysed before, or the current block is a clone of an
1147 already analysed block, and this clone is reached for the first time.
1148 In the latter case, this function does all that is necessary for fully
1149 cloning the block (cloning the instruction list and variables, etc.).
1152 sd...........stack analysis data
1155 true.........everything ok
1156 false........a VerifyError has been thrown
1158 *******************************************************************************/
1160 #define RELOCATE(index) \
1162 if ((index) >= blockvarstart) \
1163 (index) += blockvarshift; \
1164 else if ((index) >= invarstart) \
1165 (index) += invarshift; \
1168 bool stack_reanalyse_block(stackdata_t *sd)
1180 branch_target_t *table;
1181 lookup_target_t *lookup;
1184 bool cloneinstructions;
1188 #if defined(STACK_VERBOSE)
1189 stack_verbose_block_enter(sd, true);
1196 assert(orig != NULL);
1198 /* clone the instruction list */
1200 cloneinstructions = true;
1202 assert(orig->iinstr);
1204 iptr = DMNEW(instruction, len + 1);
1206 MCOPY(iptr, orig->iinstr, instruction, len);
1207 iptr[len].opc = ICMD_NOP;
1211 /* allocate space for the clone's block variables */
1213 stack_grow_variable_array(sd, orig->varcount);
1215 /* we already have the invars set */
1217 assert(b->indepth == orig->indepth);
1219 /* calculate relocation shifts for invars and block variables */
1221 if (orig->indepth) {
1222 invarstart = orig->invars[0];
1223 invarshift = b->invars[0] - invarstart;
1226 invarstart = INT_MAX;
1229 blockvarstart = orig->varstart;
1230 blockvarshift = sd->vartop - blockvarstart;
1232 /* copy block variables */
1234 b->varstart = sd->vartop;
1235 b->varcount = orig->varcount;
1236 sd->vartop += b->varcount;
1237 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1241 b->outdepth = orig->outdepth;
1242 b->outvars = DMNEW(s4, orig->outdepth);
1243 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1245 /* clone exception handlers */
1247 for (i=0; sd->handlers[i]; ++i) {
1248 ex = DNEW(exceptiontable);
1249 ex->handler = sd->handlers[i]->handler;
1251 ex->end = b; /* XXX hack, see end of new_stack_analyse */
1252 ex->catchtype = sd->handlers[i]->catchtype;
1255 assert(sd->extableend->down == NULL);
1256 sd->extableend->down = ex;
1257 sd->extableend = ex;
1258 sd->jd->cd->exceptiontablelength++;
1260 sd->handlers[i] = ex;
1264 cloneinstructions = false;
1267 invarstart = sd->vartop;
1268 blockvarstart = sd->vartop;
1273 /* find exception handlers for the cloned block */
1275 ex = sd->jd->cd->exceptiontable;
1276 for (; ex != NULL; ex = ex->down) {
1277 /* XXX the cloned exception handlers have identical */
1278 /* start end end blocks. */
1279 if ((ex->start == b) && (ex->end == b)) {
1280 sd->handlers[len++] = ex;
1283 sd->handlers[len] = NULL;
1286 #if defined(STACK_VERBOSE)
1287 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1288 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1291 /* mark block as finished */
1293 b->flags = BBFINISHED;
1295 /* initialize locals at the start of this block */
1298 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1300 /* reach exception handlers for this block */
1302 if (!stack_reach_handlers(sd))
1305 superblockend = false;
1307 for (len = b->icount; len--; iptr++) {
1308 #if defined(STACK_VERBOSE)
1309 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1315 switch (iptr->opc) {
1317 j = iptr->s1.varindex;
1319 if (sd->var[j].type != TYPE_RET) {
1320 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1324 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1325 superblockend = true;
1329 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1330 superblockend = true;
1334 superblockend = true;
1337 case ICMD_CHECKNULL:
1338 case ICMD_PUTSTATICCONST:
1344 case ICMD_INLINE_START:
1345 case ICMD_INLINE_END:
1346 case ICMD_INLINE_GOTO:
1350 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1351 superblockend = true;
1354 /* pop 0 push 1 const */
1363 /* pop 0 push 1 load */
1370 RELOCATE(iptr->dst.varindex);
1383 RELOCATE(iptr->sx.s23.s2.varindex);
1384 RELOCATE(iptr->s1.varindex);
1385 RELOCATE(iptr->dst.varindex);
1399 RELOCATE(iptr->sx.s23.s3.varindex);
1400 RELOCATE(iptr->sx.s23.s2.varindex);
1401 RELOCATE(iptr->s1.varindex);
1405 /* pop 1 push 0 store */
1412 RELOCATE(iptr->s1.varindex);
1414 j = iptr->dst.varindex;
1415 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1427 RELOCATE(iptr->s1.varindex);
1428 superblockend = true;
1431 case ICMD_PUTSTATIC:
1432 case ICMD_PUTFIELDCONST:
1435 RELOCATE(iptr->s1.varindex);
1438 /* pop 1 push 0 branch */
1441 case ICMD_IFNONNULL:
1456 RELOCATE(iptr->s1.varindex);
1457 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1460 /* pop 1 push 0 table branch */
1462 case ICMD_TABLESWITCH:
1463 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1465 if (cloneinstructions) {
1466 table = DMNEW(branch_target_t, i);
1467 MCOPY(table, iptr->dst.table, branch_target_t, i);
1468 iptr->dst.table = table;
1471 table = iptr->dst.table;
1474 RELOCATE(iptr->s1.varindex);
1476 table->block = stack_mark_reached_from_outvars(sd, table->block);
1479 superblockend = true;
1482 case ICMD_LOOKUPSWITCH:
1483 i = iptr->sx.s23.s2.lookupcount;
1484 if (cloneinstructions) {
1485 lookup = DMNEW(lookup_target_t, i);
1486 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1487 iptr->dst.lookup = lookup;
1490 lookup = iptr->dst.lookup;
1492 RELOCATE(iptr->s1.varindex);
1494 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1497 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1498 superblockend = true;
1501 case ICMD_MONITORENTER:
1502 case ICMD_MONITOREXIT:
1503 RELOCATE(iptr->s1.varindex);
1507 /* pop 2 push 0 branch */
1509 case ICMD_IF_ICMPEQ:
1510 case ICMD_IF_ICMPNE:
1511 case ICMD_IF_ICMPLT:
1512 case ICMD_IF_ICMPGE:
1513 case ICMD_IF_ICMPGT:
1514 case ICMD_IF_ICMPLE:
1516 case ICMD_IF_LCMPEQ:
1517 case ICMD_IF_LCMPNE:
1518 case ICMD_IF_LCMPLT:
1519 case ICMD_IF_LCMPGE:
1520 case ICMD_IF_LCMPGT:
1521 case ICMD_IF_LCMPLE:
1523 case ICMD_IF_FCMPEQ:
1524 case ICMD_IF_FCMPNE:
1526 case ICMD_IF_FCMPL_LT:
1527 case ICMD_IF_FCMPL_GE:
1528 case ICMD_IF_FCMPL_GT:
1529 case ICMD_IF_FCMPL_LE:
1531 case ICMD_IF_FCMPG_LT:
1532 case ICMD_IF_FCMPG_GE:
1533 case ICMD_IF_FCMPG_GT:
1534 case ICMD_IF_FCMPG_LE:
1536 case ICMD_IF_DCMPEQ:
1537 case ICMD_IF_DCMPNE:
1539 case ICMD_IF_DCMPL_LT:
1540 case ICMD_IF_DCMPL_GE:
1541 case ICMD_IF_DCMPL_GT:
1542 case ICMD_IF_DCMPL_LE:
1544 case ICMD_IF_DCMPG_LT:
1545 case ICMD_IF_DCMPG_GE:
1546 case ICMD_IF_DCMPG_GT:
1547 case ICMD_IF_DCMPG_LE:
1549 case ICMD_IF_ACMPEQ:
1550 case ICMD_IF_ACMPNE:
1551 RELOCATE(iptr->sx.s23.s2.varindex);
1552 RELOCATE(iptr->s1.varindex);
1553 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1559 case ICMD_IASTORECONST:
1560 case ICMD_LASTORECONST:
1561 case ICMD_AASTORECONST:
1562 case ICMD_BASTORECONST:
1563 case ICMD_CASTORECONST:
1564 case ICMD_SASTORECONST:
1567 RELOCATE(iptr->sx.s23.s2.varindex);
1568 RELOCATE(iptr->s1.varindex);
1571 /* pop 0 push 1 copy */
1575 RELOCATE(iptr->dst.varindex);
1576 RELOCATE(iptr->s1.varindex);
1577 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1620 RELOCATE(iptr->sx.s23.s2.varindex);
1621 RELOCATE(iptr->s1.varindex);
1622 RELOCATE(iptr->dst.varindex);
1627 case ICMD_CHECKCAST:
1628 case ICMD_ARRAYLENGTH:
1629 case ICMD_INSTANCEOF:
1631 case ICMD_ANEWARRAY:
1634 case ICMD_IADDCONST:
1635 case ICMD_ISUBCONST:
1636 case ICMD_IMULCONST:
1640 case ICMD_IANDCONST:
1642 case ICMD_IXORCONST:
1643 case ICMD_ISHLCONST:
1644 case ICMD_ISHRCONST:
1645 case ICMD_IUSHRCONST:
1646 case ICMD_LADDCONST:
1647 case ICMD_LSUBCONST:
1648 case ICMD_LMULCONST:
1652 case ICMD_LANDCONST:
1654 case ICMD_LXORCONST:
1655 case ICMD_LSHLCONST:
1656 case ICMD_LSHRCONST:
1657 case ICMD_LUSHRCONST:
1661 case ICMD_INT2SHORT:
1677 RELOCATE(iptr->s1.varindex);
1678 RELOCATE(iptr->dst.varindex);
1683 case ICMD_GETSTATIC:
1686 RELOCATE(iptr->dst.varindex);
1689 /* pop many push any */
1691 case ICMD_INVOKESTATIC:
1692 case ICMD_INVOKESPECIAL:
1693 case ICMD_INVOKEVIRTUAL:
1694 case ICMD_INVOKEINTERFACE:
1696 case ICMD_MULTIANEWARRAY:
1697 i = iptr->s1.argcount;
1698 if (cloneinstructions) {
1699 argp = DMNEW(s4, i);
1700 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1701 iptr->sx.s23.s2.args = argp;
1704 argp = iptr->sx.s23.s2.args;
1712 RELOCATE(iptr->dst.varindex);
1717 new_internalerror("Unknown ICMD %d during stack re-analysis",
1722 #if defined(STACK_VERBOSE)
1723 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1728 /* relocate outvars */
1730 for (i=0; i<b->outdepth; ++i) {
1731 RELOCATE(b->outvars[i]);
1734 #if defined(STACK_VERBOSE)
1735 stack_verbose_block_exit(sd, superblockend);
1738 /* propagate to the next block */
1741 if (!stack_reach_next_block(sd))
1748 /* stack_analyse ***************************************************************
1750 Analyse_stack uses the intermediate code created by parse.c to
1751 build a model of the JVM operand stack for the current method.
1753 The following checks are performed:
1754 - check for operand stack underflow (before each instruction)
1755 - check for operand stack overflow (after[1] each instruction)
1756 - check for matching stack depth at merging points
1757 - check for matching basic types[2] at merging points
1758 - check basic types for instruction input (except for BUILTIN*
1759 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1761 [1]) Checking this after the instruction should be ok. parse.c
1762 counts the number of required stack slots in such a way that it is
1763 only vital that we don't exceed `maxstack` at basic block
1766 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1767 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1768 types are not discerned.
1770 *******************************************************************************/
1772 bool new_stack_analyse(jitdata *jd)
1774 methodinfo *m; /* method being analyzed */
1779 int b_index; /* basic block index */
1781 stackptr curstack; /* current stack top */
1783 int opcode; /* opcode of current instruction */
1786 int len; /* # of instructions after the current one */
1787 bool superblockend; /* if true, no fallthrough to next block */
1788 bool deadcode; /* true if no live code has been reached */
1789 instruction *iptr; /* the current instruction */
1791 basicblock *original;
1794 stackptr *last_store_boundary;
1795 stackptr coalescing_boundary;
1797 stackptr src1, src2, src3, src4, dst1, dst2;
1799 branch_target_t *table;
1800 lookup_target_t *lookup;
1801 #if defined(ENABLE_VERIFIER)
1802 int expectedtype; /* used by CHECK_BASIC_TYPE */
1804 builtintable_entry *bte;
1806 constant_FMIref *fmiref;
1807 #if defined(ENABLE_STATISTICS)
1808 int iteration_count; /* number of iterations of analysis */
1810 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1812 #if defined(STACK_VERBOSE)
1813 new_show_method(jd, SHOW_PARSE);
1816 /* get required compiler data - initialization */
1823 /* initialize the stackdata_t struct */
1827 sd.varcount = jd->varcount;
1828 sd.vartop = jd->vartop;
1829 sd.localcount = jd->localcount;
1831 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1832 sd.exstack.type = TYPE_ADR;
1833 sd.exstack.prev = NULL;
1834 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1836 #if defined(ENABLE_LSRA)
1837 m->maxlifetimes = 0;
1840 #if defined(ENABLE_STATISTICS)
1841 iteration_count = 0;
1844 /* find the last real basic block */
1846 sd.last_real_block = NULL;
1847 tbptr = jd->new_basicblocks;
1848 while (tbptr->next) {
1849 sd.last_real_block = tbptr;
1850 tbptr = tbptr->next;
1852 assert(sd.last_real_block);
1854 /* find the last exception handler */
1856 if (cd->exceptiontablelength)
1857 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1859 sd.extableend = NULL;
1861 /* init jd->interface_map */
1863 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1864 for (i = 0; i < m->maxstack * 5; i++)
1865 jd->interface_map[i].flags = UNUSED;
1867 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1869 /* initialize flags and invars (none) of first block */
1871 jd->new_basicblocks[0].flags = BBREACHED;
1872 jd->new_basicblocks[0].invars = NULL;
1873 jd->new_basicblocks[0].indepth = 0;
1875 /* stack analysis loop (until fixpoint reached) **************************/
1878 #if defined(ENABLE_STATISTICS)
1882 /* initialize loop over basic blocks */
1884 sd.bptr = jd->new_basicblocks;
1885 superblockend = true;
1887 curstack = NULL; stackdepth = 0;
1890 /* iterate over basic blocks *****************************************/
1892 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1894 if (sd.bptr->flags == BBDELETED) {
1895 /* This block has been deleted - do nothing. */
1900 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1901 /* This block has not been reached so far, and we */
1902 /* don't fall into it, so we'll have to iterate again. */
1908 if (sd.bptr->flags > BBREACHED) {
1909 /* This block is already finished. */
1911 superblockend = true;
1915 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1916 /* This block is a clone and the original has not been */
1917 /* analysed, yet. Analyse it on the next iteration. */
1923 /* This block has to be analysed now. */
1925 /* XXX The rest of this block is still indented one level too */
1926 /* much in order to avoid a giant diff by changing that. */
1928 /* We know that sd.bptr->flags == BBREACHED. */
1929 /* This block has been reached before. */
1931 assert(sd.bptr->flags == BBREACHED);
1932 stackdepth = sd.bptr->indepth;
1934 /* find exception handlers for this block */
1936 /* determine the active exception handlers for this block */
1937 /* XXX could use a faster algorithm with sorted lists or */
1940 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1943 ex = cd->exceptiontable;
1944 for (; ex != NULL; ex = ex->down) {
1945 if ((ex->start <= original) && (ex->end > original)) {
1946 sd.handlers[len++] = ex;
1949 sd.handlers[len] = NULL;
1952 /* reanalyse cloned block */
1954 if (sd.bptr->original) {
1955 if (!stack_reanalyse_block(&sd))
1960 /* reset the new pointer for allocating stackslots */
1962 sd.new = jd->new_stack;
1964 /* create the instack of this block */
1966 curstack = stack_create_instack(&sd);
1968 /* initialize locals at the start of this block */
1970 if (sd.bptr->inlocals)
1971 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1973 /* set up local variables for analyzing this block */
1976 superblockend = false;
1977 len = sd.bptr->icount;
1978 iptr = sd.bptr->iinstr;
1979 b_index = sd.bptr - jd->new_basicblocks;
1981 /* mark the block as analysed */
1983 sd.bptr->flags = BBFINISHED;
1985 /* reset variables for dependency checking */
1987 coalescing_boundary = sd.new;
1988 for( i = 0; i < cd->maxlocals; i++)
1989 last_store_boundary[i] = sd.new;
1991 /* remember the start of this block's variables */
1993 sd.bptr->varstart = sd.vartop;
1995 #if defined(STACK_VERBOSE)
1996 stack_verbose_block_enter(&sd, false);
1999 /* reach exception handlers for this block */
2001 if (!stack_reach_handlers(&sd))
2004 /* iterate over ICMDs ****************************************/
2006 while (--len >= 0) {
2008 #if defined(STACK_VERBOSE)
2009 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2010 for( copy = curstack; copy; copy = copy->prev ) {
2011 printf("%2d(%d", copy->varnum, copy->type);
2012 if (IS_OUTVAR(copy))
2014 if (IS_PREALLOC(copy))
2021 /* fetch the current opcode */
2025 /* automatically replace some ICMDs with builtins */
2027 #if defined(USEBUILTINTABLE)
2029 bte = builtintable_get_automatic(opcode);
2031 if (bte && bte->opcode == opcode) {
2032 iptr->opc = ICMD_BUILTIN;
2033 iptr->flags.bits = 0;
2034 iptr->sx.s23.s3.bte = bte;
2035 /* iptr->line is already set */
2036 jd->isleafmethod = false;
2040 #endif /* defined(USEBUILTINTABLE) */
2042 /* main opcode switch *************************************/
2054 case ICMD_CHECKNULL:
2055 coalescing_boundary = sd.new;
2056 COUNT(count_check_null);
2059 CLR_DST; /* XXX live through? */
2063 j = iptr->s1.varindex =
2064 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2066 if (sd.var[j].type != TYPE_RET) {
2067 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2073 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2075 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
2077 superblockend = true;
2081 COUNT(count_pcmd_return);
2084 superblockend = true;
2088 /* pop 0 push 1 const */
2090 /************************** ICONST OPTIMIZATIONS **************************/
2093 COUNT(count_pcmd_load);
2097 switch (iptr[1].opc) {
2099 iptr->opc = ICMD_IADDCONST;
2103 iptr[1].opc = ICMD_NOP;
2104 OP1_1(TYPE_INT, TYPE_INT);
2105 COUNT(count_pcmd_op);
2109 iptr->opc = ICMD_ISUBCONST;
2110 goto icmd_iconst_tail;
2111 #if SUPPORT_CONST_MUL
2113 iptr->opc = ICMD_IMULCONST;
2114 goto icmd_iconst_tail;
2115 #else /* SUPPORT_CONST_MUL */
2117 if (iptr->sx.val.i == 0x00000002)
2119 else if (iptr->sx.val.i == 0x00000004)
2121 else if (iptr->sx.val.i == 0x00000008)
2123 else if (iptr->sx.val.i == 0x00000010)
2125 else if (iptr->sx.val.i == 0x00000020)
2127 else if (iptr->sx.val.i == 0x00000040)
2129 else if (iptr->sx.val.i == 0x00000080)
2131 else if (iptr->sx.val.i == 0x00000100)
2133 else if (iptr->sx.val.i == 0x00000200)
2135 else if (iptr->sx.val.i == 0x00000400)
2136 iptr->sx.val.i = 10;
2137 else if (iptr->sx.val.i == 0x00000800)
2138 iptr->sx.val.i = 11;
2139 else if (iptr->sx.val.i == 0x00001000)
2140 iptr->sx.val.i = 12;
2141 else if (iptr->sx.val.i == 0x00002000)
2142 iptr->sx.val.i = 13;
2143 else if (iptr->sx.val.i == 0x00004000)
2144 iptr->sx.val.i = 14;
2145 else if (iptr->sx.val.i == 0x00008000)
2146 iptr->sx.val.i = 15;
2147 else if (iptr->sx.val.i == 0x00010000)
2148 iptr->sx.val.i = 16;
2149 else if (iptr->sx.val.i == 0x00020000)
2150 iptr->sx.val.i = 17;
2151 else if (iptr->sx.val.i == 0x00040000)
2152 iptr->sx.val.i = 18;
2153 else if (iptr->sx.val.i == 0x00080000)
2154 iptr->sx.val.i = 19;
2155 else if (iptr->sx.val.i == 0x00100000)
2156 iptr->sx.val.i = 20;
2157 else if (iptr->sx.val.i == 0x00200000)
2158 iptr->sx.val.i = 21;
2159 else if (iptr->sx.val.i == 0x00400000)
2160 iptr->sx.val.i = 22;
2161 else if (iptr->sx.val.i == 0x00800000)
2162 iptr->sx.val.i = 23;
2163 else if (iptr->sx.val.i == 0x01000000)
2164 iptr->sx.val.i = 24;
2165 else if (iptr->sx.val.i == 0x02000000)
2166 iptr->sx.val.i = 25;
2167 else if (iptr->sx.val.i == 0x04000000)
2168 iptr->sx.val.i = 26;
2169 else if (iptr->sx.val.i == 0x08000000)
2170 iptr->sx.val.i = 27;
2171 else if (iptr->sx.val.i == 0x10000000)
2172 iptr->sx.val.i = 28;
2173 else if (iptr->sx.val.i == 0x20000000)
2174 iptr->sx.val.i = 29;
2175 else if (iptr->sx.val.i == 0x40000000)
2176 iptr->sx.val.i = 30;
2177 else if (iptr->sx.val.i == 0x80000000)
2178 iptr->sx.val.i = 31;
2182 iptr->opc = ICMD_IMULPOW2;
2183 goto icmd_iconst_tail;
2184 #endif /* SUPPORT_CONST_MUL */
2186 if (iptr->sx.val.i == 0x00000002)
2188 else if (iptr->sx.val.i == 0x00000004)
2190 else if (iptr->sx.val.i == 0x00000008)
2192 else if (iptr->sx.val.i == 0x00000010)
2194 else if (iptr->sx.val.i == 0x00000020)
2196 else if (iptr->sx.val.i == 0x00000040)
2198 else if (iptr->sx.val.i == 0x00000080)
2200 else if (iptr->sx.val.i == 0x00000100)
2202 else if (iptr->sx.val.i == 0x00000200)
2204 else if (iptr->sx.val.i == 0x00000400)
2205 iptr->sx.val.i = 10;
2206 else if (iptr->sx.val.i == 0x00000800)
2207 iptr->sx.val.i = 11;
2208 else if (iptr->sx.val.i == 0x00001000)
2209 iptr->sx.val.i = 12;
2210 else if (iptr->sx.val.i == 0x00002000)
2211 iptr->sx.val.i = 13;
2212 else if (iptr->sx.val.i == 0x00004000)
2213 iptr->sx.val.i = 14;
2214 else if (iptr->sx.val.i == 0x00008000)
2215 iptr->sx.val.i = 15;
2216 else if (iptr->sx.val.i == 0x00010000)
2217 iptr->sx.val.i = 16;
2218 else if (iptr->sx.val.i == 0x00020000)
2219 iptr->sx.val.i = 17;
2220 else if (iptr->sx.val.i == 0x00040000)
2221 iptr->sx.val.i = 18;
2222 else if (iptr->sx.val.i == 0x00080000)
2223 iptr->sx.val.i = 19;
2224 else if (iptr->sx.val.i == 0x00100000)
2225 iptr->sx.val.i = 20;
2226 else if (iptr->sx.val.i == 0x00200000)
2227 iptr->sx.val.i = 21;
2228 else if (iptr->sx.val.i == 0x00400000)
2229 iptr->sx.val.i = 22;
2230 else if (iptr->sx.val.i == 0x00800000)
2231 iptr->sx.val.i = 23;
2232 else if (iptr->sx.val.i == 0x01000000)
2233 iptr->sx.val.i = 24;
2234 else if (iptr->sx.val.i == 0x02000000)
2235 iptr->sx.val.i = 25;
2236 else if (iptr->sx.val.i == 0x04000000)
2237 iptr->sx.val.i = 26;
2238 else if (iptr->sx.val.i == 0x08000000)
2239 iptr->sx.val.i = 27;
2240 else if (iptr->sx.val.i == 0x10000000)
2241 iptr->sx.val.i = 28;
2242 else if (iptr->sx.val.i == 0x20000000)
2243 iptr->sx.val.i = 29;
2244 else if (iptr->sx.val.i == 0x40000000)
2245 iptr->sx.val.i = 30;
2246 else if (iptr->sx.val.i == 0x80000000)
2247 iptr->sx.val.i = 31;
2251 iptr->opc = ICMD_IDIVPOW2;
2252 goto icmd_iconst_tail;
2255 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2256 if ((iptr->sx.val.i == 0x00000002) ||
2257 (iptr->sx.val.i == 0x00000004) ||
2258 (iptr->sx.val.i == 0x00000008) ||
2259 (iptr->sx.val.i == 0x00000010) ||
2260 (iptr->sx.val.i == 0x00000020) ||
2261 (iptr->sx.val.i == 0x00000040) ||
2262 (iptr->sx.val.i == 0x00000080) ||
2263 (iptr->sx.val.i == 0x00000100) ||
2264 (iptr->sx.val.i == 0x00000200) ||
2265 (iptr->sx.val.i == 0x00000400) ||
2266 (iptr->sx.val.i == 0x00000800) ||
2267 (iptr->sx.val.i == 0x00001000) ||
2268 (iptr->sx.val.i == 0x00002000) ||
2269 (iptr->sx.val.i == 0x00004000) ||
2270 (iptr->sx.val.i == 0x00008000) ||
2271 (iptr->sx.val.i == 0x00010000) ||
2272 (iptr->sx.val.i == 0x00020000) ||
2273 (iptr->sx.val.i == 0x00040000) ||
2274 (iptr->sx.val.i == 0x00080000) ||
2275 (iptr->sx.val.i == 0x00100000) ||
2276 (iptr->sx.val.i == 0x00200000) ||
2277 (iptr->sx.val.i == 0x00400000) ||
2278 (iptr->sx.val.i == 0x00800000) ||
2279 (iptr->sx.val.i == 0x01000000) ||
2280 (iptr->sx.val.i == 0x02000000) ||
2281 (iptr->sx.val.i == 0x04000000) ||
2282 (iptr->sx.val.i == 0x08000000) ||
2283 (iptr->sx.val.i == 0x10000000) ||
2284 (iptr->sx.val.i == 0x20000000) ||
2285 (iptr->sx.val.i == 0x40000000) ||
2286 (iptr->sx.val.i == 0x80000000))
2288 iptr->opc = ICMD_IREMPOW2;
2289 iptr->sx.val.i -= 1;
2290 goto icmd_iconst_tail;
2293 #if SUPPORT_CONST_LOGICAL
2295 iptr->opc = ICMD_IANDCONST;
2296 goto icmd_iconst_tail;
2299 iptr->opc = ICMD_IORCONST;
2300 goto icmd_iconst_tail;
2303 iptr->opc = ICMD_IXORCONST;
2304 goto icmd_iconst_tail;
2306 #endif /* SUPPORT_CONST_LOGICAL */
2308 iptr->opc = ICMD_ISHLCONST;
2309 goto icmd_iconst_tail;
2312 iptr->opc = ICMD_ISHRCONST;
2313 goto icmd_iconst_tail;
2316 iptr->opc = ICMD_IUSHRCONST;
2317 goto icmd_iconst_tail;
2318 #if SUPPORT_LONG_SHIFT
2320 iptr->opc = ICMD_LSHLCONST;
2321 goto icmd_lconst_tail;
2324 iptr->opc = ICMD_LSHRCONST;
2325 goto icmd_lconst_tail;
2328 iptr->opc = ICMD_LUSHRCONST;
2329 goto icmd_lconst_tail;
2330 #endif /* SUPPORT_LONG_SHIFT */
2331 case ICMD_IF_ICMPEQ:
2332 iptr[1].opc = ICMD_IFEQ;
2336 /* set the constant for the following icmd */
2337 iptr[1].sx.val.i = iptr->sx.val.i;
2339 /* this instruction becomes a nop */
2340 iptr->opc = ICMD_NOP;
2343 case ICMD_IF_ICMPLT:
2344 iptr[1].opc = ICMD_IFLT;
2345 goto icmd_if_icmp_tail;
2347 case ICMD_IF_ICMPLE:
2348 iptr[1].opc = ICMD_IFLE;
2349 goto icmd_if_icmp_tail;
2351 case ICMD_IF_ICMPNE:
2352 iptr[1].opc = ICMD_IFNE;
2353 goto icmd_if_icmp_tail;
2355 case ICMD_IF_ICMPGT:
2356 iptr[1].opc = ICMD_IFGT;
2357 goto icmd_if_icmp_tail;
2359 case ICMD_IF_ICMPGE:
2360 iptr[1].opc = ICMD_IFGE;
2361 goto icmd_if_icmp_tail;
2363 #if SUPPORT_CONST_STORE
2368 IF_INTRP( goto normal_ICONST; )
2369 # if SUPPORT_CONST_STORE_ZERO_ONLY
2370 if (iptr->sx.val.i != 0)
2373 switch (iptr[1].opc) {
2375 iptr->opc = ICMD_IASTORECONST;
2376 iptr->flags.bits |= INS_FLAG_CHECK;
2379 iptr->opc = ICMD_BASTORECONST;
2380 iptr->flags.bits |= INS_FLAG_CHECK;
2383 iptr->opc = ICMD_CASTORECONST;
2384 iptr->flags.bits |= INS_FLAG_CHECK;
2387 iptr->opc = ICMD_SASTORECONST;
2388 iptr->flags.bits |= INS_FLAG_CHECK;
2392 iptr[1].opc = ICMD_NOP;
2394 /* copy the constant to s3 */
2395 /* XXX constval -> astoreconstval? */
2396 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2397 OP2_0(TYPE_ADR, TYPE_INT);
2398 COUNT(count_pcmd_op);
2401 case ICMD_PUTSTATIC:
2403 IF_INTRP( goto normal_ICONST; )
2404 # if SUPPORT_CONST_STORE_ZERO_ONLY
2405 if (iptr->sx.val.i != 0)
2408 /* XXX check field type? */
2410 /* copy the constant to s2 */
2411 /* XXX constval -> fieldconstval? */
2412 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2415 /* set the field reference (s3) */
2416 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2417 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2418 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2421 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2424 switch (iptr[1].opc) {
2425 case ICMD_PUTSTATIC:
2426 iptr->opc = ICMD_PUTSTATICCONST;
2430 iptr->opc = ICMD_PUTFIELDCONST;
2435 iptr[1].opc = ICMD_NOP;
2436 COUNT(count_pcmd_op);
2438 #endif /* SUPPORT_CONST_STORE */
2444 /* if we get here, the ICONST has been optimized */
2448 /* normal case of an unoptimized ICONST */
2452 /************************** LCONST OPTIMIZATIONS **************************/
2455 COUNT(count_pcmd_load);
2459 /* switch depending on the following instruction */
2461 switch (iptr[1].opc) {
2462 #if SUPPORT_LONG_ADD
2464 iptr->opc = ICMD_LADDCONST;
2468 /* instruction of type LONG -> LONG */
2469 iptr[1].opc = ICMD_NOP;
2470 OP1_1(TYPE_LNG, TYPE_LNG);
2471 COUNT(count_pcmd_op);
2475 iptr->opc = ICMD_LSUBCONST;
2476 goto icmd_lconst_tail;
2478 #endif /* SUPPORT_LONG_ADD */
2479 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2481 iptr->opc = ICMD_LMULCONST;
2482 goto icmd_lconst_tail;
2483 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2484 # if SUPPORT_LONG_SHIFT
2486 if (iptr->sx.val.l == 0x00000002)
2488 else if (iptr->sx.val.l == 0x00000004)
2490 else if (iptr->sx.val.l == 0x00000008)
2492 else if (iptr->sx.val.l == 0x00000010)
2494 else if (iptr->sx.val.l == 0x00000020)
2496 else if (iptr->sx.val.l == 0x00000040)
2498 else if (iptr->sx.val.l == 0x00000080)
2500 else if (iptr->sx.val.l == 0x00000100)
2502 else if (iptr->sx.val.l == 0x00000200)
2504 else if (iptr->sx.val.l == 0x00000400)
2505 iptr->sx.val.i = 10;
2506 else if (iptr->sx.val.l == 0x00000800)
2507 iptr->sx.val.i = 11;
2508 else if (iptr->sx.val.l == 0x00001000)
2509 iptr->sx.val.i = 12;
2510 else if (iptr->sx.val.l == 0x00002000)
2511 iptr->sx.val.i = 13;
2512 else if (iptr->sx.val.l == 0x00004000)
2513 iptr->sx.val.i = 14;
2514 else if (iptr->sx.val.l == 0x00008000)
2515 iptr->sx.val.i = 15;
2516 else if (iptr->sx.val.l == 0x00010000)
2517 iptr->sx.val.i = 16;
2518 else if (iptr->sx.val.l == 0x00020000)
2519 iptr->sx.val.i = 17;
2520 else if (iptr->sx.val.l == 0x00040000)
2521 iptr->sx.val.i = 18;
2522 else if (iptr->sx.val.l == 0x00080000)
2523 iptr->sx.val.i = 19;
2524 else if (iptr->sx.val.l == 0x00100000)
2525 iptr->sx.val.i = 20;
2526 else if (iptr->sx.val.l == 0x00200000)
2527 iptr->sx.val.i = 21;
2528 else if (iptr->sx.val.l == 0x00400000)
2529 iptr->sx.val.i = 22;
2530 else if (iptr->sx.val.l == 0x00800000)
2531 iptr->sx.val.i = 23;
2532 else if (iptr->sx.val.l == 0x01000000)
2533 iptr->sx.val.i = 24;
2534 else if (iptr->sx.val.l == 0x02000000)
2535 iptr->sx.val.i = 25;
2536 else if (iptr->sx.val.l == 0x04000000)
2537 iptr->sx.val.i = 26;
2538 else if (iptr->sx.val.l == 0x08000000)
2539 iptr->sx.val.i = 27;
2540 else if (iptr->sx.val.l == 0x10000000)
2541 iptr->sx.val.i = 28;
2542 else if (iptr->sx.val.l == 0x20000000)
2543 iptr->sx.val.i = 29;
2544 else if (iptr->sx.val.l == 0x40000000)
2545 iptr->sx.val.i = 30;
2546 else if (iptr->sx.val.l == 0x80000000)
2547 iptr->sx.val.i = 31;
2551 iptr->opc = ICMD_LMULPOW2;
2552 goto icmd_lconst_tail;
2553 # endif /* SUPPORT_LONG_SHIFT */
2554 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2555 #if SUPPORT_LONG_DIV_POW2
2557 if (iptr->sx.val.l == 0x00000002)
2559 else if (iptr->sx.val.l == 0x00000004)
2561 else if (iptr->sx.val.l == 0x00000008)
2563 else if (iptr->sx.val.l == 0x00000010)
2565 else if (iptr->sx.val.l == 0x00000020)
2567 else if (iptr->sx.val.l == 0x00000040)
2569 else if (iptr->sx.val.l == 0x00000080)
2571 else if (iptr->sx.val.l == 0x00000100)
2573 else if (iptr->sx.val.l == 0x00000200)
2575 else if (iptr->sx.val.l == 0x00000400)
2576 iptr->sx.val.i = 10;
2577 else if (iptr->sx.val.l == 0x00000800)
2578 iptr->sx.val.i = 11;
2579 else if (iptr->sx.val.l == 0x00001000)
2580 iptr->sx.val.i = 12;
2581 else if (iptr->sx.val.l == 0x00002000)
2582 iptr->sx.val.i = 13;
2583 else if (iptr->sx.val.l == 0x00004000)
2584 iptr->sx.val.i = 14;
2585 else if (iptr->sx.val.l == 0x00008000)
2586 iptr->sx.val.i = 15;
2587 else if (iptr->sx.val.l == 0x00010000)
2588 iptr->sx.val.i = 16;
2589 else if (iptr->sx.val.l == 0x00020000)
2590 iptr->sx.val.i = 17;
2591 else if (iptr->sx.val.l == 0x00040000)
2592 iptr->sx.val.i = 18;
2593 else if (iptr->sx.val.l == 0x00080000)
2594 iptr->sx.val.i = 19;
2595 else if (iptr->sx.val.l == 0x00100000)
2596 iptr->sx.val.i = 20;
2597 else if (iptr->sx.val.l == 0x00200000)
2598 iptr->sx.val.i = 21;
2599 else if (iptr->sx.val.l == 0x00400000)
2600 iptr->sx.val.i = 22;
2601 else if (iptr->sx.val.l == 0x00800000)
2602 iptr->sx.val.i = 23;
2603 else if (iptr->sx.val.l == 0x01000000)
2604 iptr->sx.val.i = 24;
2605 else if (iptr->sx.val.l == 0x02000000)
2606 iptr->sx.val.i = 25;
2607 else if (iptr->sx.val.l == 0x04000000)
2608 iptr->sx.val.i = 26;
2609 else if (iptr->sx.val.l == 0x08000000)
2610 iptr->sx.val.i = 27;
2611 else if (iptr->sx.val.l == 0x10000000)
2612 iptr->sx.val.i = 28;
2613 else if (iptr->sx.val.l == 0x20000000)
2614 iptr->sx.val.i = 29;
2615 else if (iptr->sx.val.l == 0x40000000)
2616 iptr->sx.val.i = 30;
2617 else if (iptr->sx.val.l == 0x80000000)
2618 iptr->sx.val.i = 31;
2622 iptr->opc = ICMD_LDIVPOW2;
2623 goto icmd_lconst_tail;
2624 #endif /* SUPPORT_LONG_DIV_POW2 */
2626 #if SUPPORT_LONG_REM_POW2
2628 if ((iptr->sx.val.l == 0x00000002) ||
2629 (iptr->sx.val.l == 0x00000004) ||
2630 (iptr->sx.val.l == 0x00000008) ||
2631 (iptr->sx.val.l == 0x00000010) ||
2632 (iptr->sx.val.l == 0x00000020) ||
2633 (iptr->sx.val.l == 0x00000040) ||
2634 (iptr->sx.val.l == 0x00000080) ||
2635 (iptr->sx.val.l == 0x00000100) ||
2636 (iptr->sx.val.l == 0x00000200) ||
2637 (iptr->sx.val.l == 0x00000400) ||
2638 (iptr->sx.val.l == 0x00000800) ||
2639 (iptr->sx.val.l == 0x00001000) ||
2640 (iptr->sx.val.l == 0x00002000) ||
2641 (iptr->sx.val.l == 0x00004000) ||
2642 (iptr->sx.val.l == 0x00008000) ||
2643 (iptr->sx.val.l == 0x00010000) ||
2644 (iptr->sx.val.l == 0x00020000) ||
2645 (iptr->sx.val.l == 0x00040000) ||
2646 (iptr->sx.val.l == 0x00080000) ||
2647 (iptr->sx.val.l == 0x00100000) ||
2648 (iptr->sx.val.l == 0x00200000) ||
2649 (iptr->sx.val.l == 0x00400000) ||
2650 (iptr->sx.val.l == 0x00800000) ||
2651 (iptr->sx.val.l == 0x01000000) ||
2652 (iptr->sx.val.l == 0x02000000) ||
2653 (iptr->sx.val.l == 0x04000000) ||
2654 (iptr->sx.val.l == 0x08000000) ||
2655 (iptr->sx.val.l == 0x10000000) ||
2656 (iptr->sx.val.l == 0x20000000) ||
2657 (iptr->sx.val.l == 0x40000000) ||
2658 (iptr->sx.val.l == 0x80000000))
2660 iptr->opc = ICMD_LREMPOW2;
2661 iptr->sx.val.l -= 1;
2662 goto icmd_lconst_tail;
2665 #endif /* SUPPORT_LONG_REM_POW2 */
2667 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2670 iptr->opc = ICMD_LANDCONST;
2671 goto icmd_lconst_tail;
2674 iptr->opc = ICMD_LORCONST;
2675 goto icmd_lconst_tail;
2678 iptr->opc = ICMD_LXORCONST;
2679 goto icmd_lconst_tail;
2680 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2682 #if SUPPORT_LONG_CMP_CONST
2684 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2687 /* switch on the instruction after LCONST - LCMP */
2689 switch (iptr[2].opc) {
2691 iptr->opc = ICMD_IF_LEQ;
2694 icmd_lconst_lcmp_tail:
2695 /* convert LCONST, LCMP, IFXX to IF_LXX */
2696 iptr->dst.insindex = iptr[2].dst.insindex;
2697 iptr[1].opc = ICMD_NOP;
2698 iptr[2].opc = ICMD_NOP;
2700 OP1_BRANCH(TYPE_LNG);
2701 BRANCH(tbptr, copy);
2702 COUNT(count_pcmd_bra);
2703 COUNT(count_pcmd_op);
2707 iptr->opc = ICMD_IF_LNE;
2708 goto icmd_lconst_lcmp_tail;
2711 iptr->opc = ICMD_IF_LLT;
2712 goto icmd_lconst_lcmp_tail;
2715 iptr->opc = ICMD_IF_LGT;
2716 goto icmd_lconst_lcmp_tail;
2719 iptr->opc = ICMD_IF_LLE;
2720 goto icmd_lconst_lcmp_tail;
2723 iptr->opc = ICMD_IF_LGE;
2724 goto icmd_lconst_lcmp_tail;
2728 } /* end switch on opcode after LCONST - LCMP */
2730 #endif /* SUPPORT_LONG_CMP_CONST */
2732 #if SUPPORT_CONST_STORE
2734 IF_INTRP( goto normal_LCONST; )
2735 # if SUPPORT_CONST_STORE_ZERO_ONLY
2736 if (iptr->sx.val.l != 0)
2739 #if SIZEOF_VOID_P == 4
2740 /* the constant must fit into a ptrint */
2741 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2744 /* move the constant to s3 */
2745 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2747 iptr->opc = ICMD_LASTORECONST;
2748 iptr->flags.bits |= INS_FLAG_CHECK;
2749 OP2_0(TYPE_ADR, TYPE_INT);
2751 iptr[1].opc = ICMD_NOP;
2752 COUNT(count_pcmd_op);
2755 case ICMD_PUTSTATIC:
2757 IF_INTRP( goto normal_LCONST; )
2758 # if SUPPORT_CONST_STORE_ZERO_ONLY
2759 if (iptr->sx.val.l != 0)
2762 #if SIZEOF_VOID_P == 4
2763 /* the constant must fit into a ptrint */
2764 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2767 /* XXX check field type? */
2769 /* copy the constant to s2 */
2770 /* XXX constval -> fieldconstval? */
2771 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2775 #endif /* SUPPORT_CONST_STORE */
2779 } /* end switch opcode after LCONST */
2781 /* if we get here, the LCONST has been optimized */
2785 /* the normal case of an unoptimized LCONST */
2789 /************************ END OF LCONST OPTIMIZATIONS *********************/
2792 COUNT(count_pcmd_load);
2797 COUNT(count_pcmd_load);
2801 /************************** ACONST OPTIMIZATIONS **************************/
2804 coalescing_boundary = sd.new;
2805 COUNT(count_pcmd_load);
2806 #if SUPPORT_CONST_STORE
2807 IF_INTRP( goto normal_ACONST; )
2809 /* We can only optimize if the ACONST is resolved
2810 * and there is an instruction after it. */
2812 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2815 switch (iptr[1].opc) {
2817 /* We can only optimize for NULL values
2818 * here because otherwise a checkcast is
2820 if (iptr->sx.val.anyptr != NULL)
2823 /* copy the constant (NULL) to s3 */
2824 iptr->sx.s23.s3.constval = 0;
2825 iptr->opc = ICMD_AASTORECONST;
2826 iptr->flags.bits |= INS_FLAG_CHECK;
2827 OP2_0(TYPE_ADR, TYPE_INT);
2829 iptr[1].opc = ICMD_NOP;
2830 COUNT(count_pcmd_op);
2833 case ICMD_PUTSTATIC:
2835 # if SUPPORT_CONST_STORE_ZERO_ONLY
2836 if (iptr->sx.val.anyptr != NULL)
2839 /* XXX check field type? */
2840 /* copy the constant to s2 */
2841 /* XXX constval -> fieldconstval? */
2842 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2850 /* if we get here the ACONST has been optimized */
2854 #endif /* SUPPORT_CONST_STORE */
2859 /* pop 0 push 1 load */
2866 COUNT(count_load_instruction);
2867 i = opcode - ICMD_ILOAD; /* type */
2869 j = iptr->s1.varindex =
2870 jd->local_map[iptr->s1.varindex * 5 + i];
2872 if (sd.var[j].type == TYPE_RET) {
2873 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
2886 coalescing_boundary = sd.new;
2887 iptr->flags.bits |= INS_FLAG_CHECK;
2888 COUNT(count_check_null);
2889 COUNT(count_check_bound);
2890 COUNT(count_pcmd_mem);
2891 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
2898 coalescing_boundary = sd.new;
2899 iptr->flags.bits |= INS_FLAG_CHECK;
2900 COUNT(count_check_null);
2901 COUNT(count_check_bound);
2902 COUNT(count_pcmd_mem);
2903 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2906 /* pop 0 push 0 iinc */
2909 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2911 last_store_boundary[iptr->s1.varindex] = sd.new;
2914 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2919 if ((copy->varkind == LOCALVAR) &&
2920 (copy->varnum == iptr->s1.varindex))
2922 assert(IS_LOCALVAR(copy));
2929 iptr->dst.varindex = iptr->s1.varindex;
2932 /* pop 1 push 0 store */
2941 i = opcode - ICMD_ISTORE; /* type */
2942 javaindex = iptr->dst.varindex;
2943 j = iptr->dst.varindex =
2944 jd->local_map[javaindex * 5 + i];
2946 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2948 #if defined(ENABLE_STATISTICS)
2951 i = sd.new - curstack;
2953 count_store_length[20]++;
2955 count_store_length[i]++;
2958 count_store_depth[10]++;
2960 count_store_depth[i]++;
2963 /* check for conflicts as described in Figure 5.2 */
2965 copy = curstack->prev;
2968 if ((copy->varkind == LOCALVAR) &&
2969 (copy->varnum == j))
2971 copy->varkind = TEMPVAR;
2972 assert(IS_LOCALVAR(copy));
2979 /* if the variable is already coalesced, don't bother */
2981 if (IS_OUTVAR(curstack)
2982 || (curstack->varkind == LOCALVAR
2983 && curstack->varnum != j))
2986 /* there is no STORE Lj while curstack is live */
2988 if (curstack < last_store_boundary[javaindex])
2989 goto assume_conflict;
2991 /* curstack must be after the coalescing boundary */
2993 if (curstack < coalescing_boundary)
2994 goto assume_conflict;
2996 /* there is no DEF LOCALVAR(j) while curstack is live */
2998 copy = sd.new; /* most recent stackslot created + 1 */
2999 while (--copy > curstack) {
3000 if (copy->varkind == LOCALVAR && copy->varnum == j)
3001 goto assume_conflict;
3004 /* coalesce the temporary variable with Lj */
3005 assert((curstack->varkind == TEMPVAR)
3006 || (curstack->varkind == UNDEFVAR));
3007 assert(!IS_LOCALVAR(curstack));
3008 assert(!IS_OUTVAR(curstack));
3009 assert(!IS_PREALLOC(curstack));
3011 assert(curstack->creator);
3012 assert(curstack->creator->dst.varindex == curstack->varnum);
3013 RELEASE_INDEX(sd, curstack);
3014 curstack->varkind = LOCALVAR;
3015 curstack->varnum = j;
3016 curstack->creator->dst.varindex = j;
3019 /* revert the coalescing, if it has been done earlier */
3021 if ((curstack->varkind == LOCALVAR)
3022 && (curstack->varnum == j))
3024 assert(IS_LOCALVAR(curstack));
3025 SET_TEMPVAR(curstack);
3028 /* remember the stack boundary at this store */
3030 last_store_boundary[javaindex] = sd.new;
3032 STORE(opcode - ICMD_ISTORE, j);
3038 coalescing_boundary = sd.new;
3039 iptr->flags.bits |= INS_FLAG_CHECK;
3040 COUNT(count_check_null);
3041 COUNT(count_check_bound);
3042 COUNT(count_pcmd_mem);
3044 bte = builtintable_get_internal(BUILTIN_canstore);
3047 if (md->memuse > rd->memuse)
3048 rd->memuse = md->memuse;
3049 if (md->argintreguse > rd->argintreguse)
3050 rd->argintreguse = md->argintreguse;
3051 /* XXX non-leaf method? */
3053 /* make all stack variables saved */
3057 sd.var[copy->varnum].flags |= SAVEDVAR;
3058 /* in case copy->varnum is/will be a LOCALVAR */
3059 /* once and set back to a non LOCALVAR */
3060 /* the correct SAVEDVAR flag has to be */
3061 /* remembered in copy->flags, too */
3062 copy->flags |= SAVEDVAR;
3066 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
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, opcode - ICMD_IASTORE);
3085 coalescing_boundary = sd.new;
3086 iptr->flags.bits |= INS_FLAG_CHECK;
3087 COUNT(count_check_null);
3088 COUNT(count_check_bound);
3089 COUNT(count_pcmd_mem);
3090 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3096 #ifdef ENABLE_VERIFIER
3099 if (IS_2_WORD_TYPE(curstack->type))
3100 goto throw_stack_category_error;
3111 coalescing_boundary = sd.new;
3112 IF_JIT( md_return_alloc(jd, curstack); )
3113 COUNT(count_pcmd_return);
3114 OP1_0(opcode - ICMD_IRETURN);
3115 superblockend = true;
3119 coalescing_boundary = sd.new;
3120 COUNT(count_check_null);
3122 curstack = NULL; stackdepth = 0;
3123 superblockend = true;
3126 case ICMD_PUTSTATIC:
3127 coalescing_boundary = sd.new;
3128 COUNT(count_pcmd_mem);
3129 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3130 OP1_0(fmiref->parseddesc.fd->type);
3133 /* pop 1 push 0 branch */
3136 case ICMD_IFNONNULL:
3137 COUNT(count_pcmd_bra);
3138 OP1_BRANCH(TYPE_ADR);
3139 BRANCH(tbptr, copy);
3148 COUNT(count_pcmd_bra);
3149 /* iptr->sx.val.i is set implicitly in parse by
3150 clearing the memory or from IF_ICMPxx
3153 OP1_BRANCH(TYPE_INT);
3154 /* iptr->sx.val.i = 0; */
3155 BRANCH(tbptr, copy);
3158 /* pop 0 push 0 branch */
3161 COUNT(count_pcmd_bra);
3163 BRANCH(tbptr, copy);
3164 superblockend = true;
3167 /* pop 1 push 0 table branch */
3169 case ICMD_TABLESWITCH:
3170 COUNT(count_pcmd_table);
3171 OP1_BRANCH(TYPE_INT);
3173 table = iptr->dst.table;
3174 BRANCH_TARGET(*table, tbptr, copy);
3177 i = iptr->sx.s23.s3.tablehigh
3178 - iptr->sx.s23.s2.tablelow + 1;
3181 BRANCH_TARGET(*table, tbptr, copy);
3184 superblockend = true;
3187 /* pop 1 push 0 table branch */
3189 case ICMD_LOOKUPSWITCH:
3190 COUNT(count_pcmd_table);
3191 OP1_BRANCH(TYPE_INT);
3193 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
3195 lookup = iptr->dst.lookup;
3197 i = iptr->sx.s23.s2.lookupcount;
3200 BRANCH_TARGET(lookup->target, tbptr, copy);
3203 superblockend = true;
3206 case ICMD_MONITORENTER:
3207 case ICMD_MONITOREXIT:
3208 coalescing_boundary = sd.new;
3209 COUNT(count_check_null);
3213 /* pop 2 push 0 branch */
3215 case ICMD_IF_ICMPEQ:
3216 case ICMD_IF_ICMPNE:
3217 case ICMD_IF_ICMPLT:
3218 case ICMD_IF_ICMPGE:
3219 case ICMD_IF_ICMPGT:
3220 case ICMD_IF_ICMPLE:
3221 COUNT(count_pcmd_bra);
3222 OP2_BRANCH(TYPE_INT, TYPE_INT);
3223 BRANCH(tbptr, copy);
3226 case ICMD_IF_ACMPEQ:
3227 case ICMD_IF_ACMPNE:
3228 COUNT(count_pcmd_bra);
3229 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3230 BRANCH(tbptr, copy);
3236 coalescing_boundary = sd.new;
3237 COUNT(count_check_null);
3238 COUNT(count_pcmd_mem);
3239 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3240 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3245 if (!IS_2_WORD_TYPE(curstack->type)) {
3247 #ifdef ENABLE_VERIFIER
3250 if (IS_2_WORD_TYPE(curstack->prev->type))
3251 goto throw_stack_category_error;
3254 OP2_0_ANY_ANY; /* pop two slots */
3257 iptr->opc = ICMD_POP;
3258 OP1_0_ANY; /* pop one (two-word) slot */
3262 /* pop 0 push 1 dup */
3265 #ifdef ENABLE_VERIFIER
3268 if (IS_2_WORD_TYPE(curstack->type))
3269 goto throw_stack_category_error;
3272 COUNT(count_dup_instruction);
3278 coalescing_boundary = sd.new - 1;
3283 if (IS_2_WORD_TYPE(curstack->type)) {
3285 iptr->opc = ICMD_DUP;
3290 /* ..., ????, cat1 */
3291 #ifdef ENABLE_VERIFIER
3293 if (IS_2_WORD_TYPE(curstack->prev->type))
3294 goto throw_stack_category_error;
3297 src1 = curstack->prev;
3300 COPY_UP(src1); iptr++; len--;
3303 coalescing_boundary = sd.new;
3307 /* pop 2 push 3 dup */
3310 #ifdef ENABLE_VERIFIER
3313 if (IS_2_WORD_TYPE(curstack->type) ||
3314 IS_2_WORD_TYPE(curstack->prev->type))
3315 goto throw_stack_category_error;
3320 src1 = curstack->prev;
3325 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3327 MOVE_UP(src1); iptr++; len--;
3328 MOVE_UP(src2); iptr++; len--;
3330 COPY_DOWN(curstack, dst1);
3332 coalescing_boundary = sd.new;
3337 if (IS_2_WORD_TYPE(curstack->type)) {
3338 /* ..., ????, cat2 */
3339 #ifdef ENABLE_VERIFIER
3341 if (IS_2_WORD_TYPE(curstack->prev->type))
3342 goto throw_stack_category_error;
3345 iptr->opc = ICMD_DUP_X1;
3349 /* ..., ????, cat1 */
3350 #ifdef ENABLE_VERIFIER
3353 if (IS_2_WORD_TYPE(curstack->prev->type)
3354 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3355 goto throw_stack_category_error;
3360 src1 = curstack->prev->prev;
3361 src2 = curstack->prev;
3363 POPANY; POPANY; POPANY;
3366 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3367 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3369 MOVE_UP(src1); iptr++; len--;
3370 MOVE_UP(src2); iptr++; len--;
3371 MOVE_UP(src3); iptr++; len--;
3373 COPY_DOWN(curstack, dst2); iptr++; len--;
3374 COPY_DOWN(curstack->prev, dst1);
3376 coalescing_boundary = sd.new;
3380 /* pop 3 push 4 dup */
3384 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3385 /* ..., cat2, ???? */
3386 #ifdef ENABLE_VERIFIER
3388 if (IS_2_WORD_TYPE(curstack->type))
3389 goto throw_stack_category_error;
3392 iptr->opc = ICMD_DUP_X1;
3396 /* ..., cat1, ???? */
3397 #ifdef ENABLE_VERIFIER
3400 if (IS_2_WORD_TYPE(curstack->type)
3401 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3402 goto throw_stack_category_error;
3406 src1 = curstack->prev->prev;
3407 src2 = curstack->prev;
3409 POPANY; POPANY; POPANY;
3412 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3414 MOVE_UP(src1); iptr++; len--;
3415 MOVE_UP(src2); iptr++; len--;
3416 MOVE_UP(src3); iptr++; len--;
3418 COPY_DOWN(curstack, dst1);
3420 coalescing_boundary = sd.new;
3426 if (IS_2_WORD_TYPE(curstack->type)) {
3427 /* ..., ????, cat2 */
3428 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3429 /* ..., cat2, cat2 */
3430 iptr->opc = ICMD_DUP_X1;
3434 /* ..., cat1, cat2 */
3435 #ifdef ENABLE_VERIFIER
3438 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3439 goto throw_stack_category_error;
3442 iptr->opc = ICMD_DUP_X2;
3448 /* ..., ????, ????, cat1 */
3450 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3451 /* ..., cat2, ????, cat1 */
3452 #ifdef ENABLE_VERIFIER
3454 if (IS_2_WORD_TYPE(curstack->prev->type))
3455 goto throw_stack_category_error;
3458 iptr->opc = ICMD_DUP2_X1;
3462 /* ..., cat1, ????, cat1 */
3463 #ifdef ENABLE_VERIFIER
3466 if (IS_2_WORD_TYPE(curstack->prev->type)
3467 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3468 goto throw_stack_category_error;
3472 src1 = curstack->prev->prev->prev;
3473 src2 = curstack->prev->prev;
3474 src3 = curstack->prev;
3476 POPANY; POPANY; POPANY; POPANY;
3479 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3480 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3482 MOVE_UP(src1); iptr++; len--;
3483 MOVE_UP(src2); iptr++; len--;
3484 MOVE_UP(src3); iptr++; len--;
3485 MOVE_UP(src4); iptr++; len--;
3487 COPY_DOWN(curstack, dst2); iptr++; len--;
3488 COPY_DOWN(curstack->prev, dst1);
3490 coalescing_boundary = sd.new;
3494 /* pop 2 push 2 swap */
3497 #ifdef ENABLE_VERIFIER
3500 if (IS_2_WORD_TYPE(curstack->type)
3501 || IS_2_WORD_TYPE(curstack->prev->type))
3502 goto throw_stack_category_error;
3506 src1 = curstack->prev;
3511 MOVE_UP(src2); iptr++; len--;
3514 coalescing_boundary = sd.new;
3521 coalescing_boundary = sd.new;
3522 #if !SUPPORT_DIVISION
3523 bte = iptr->sx.s23.s3.bte;
3526 if (md->memuse > rd->memuse)
3527 rd->memuse = md->memuse;
3528 if (md->argintreguse > rd->argintreguse)
3529 rd->argintreguse = md->argintreguse;
3531 /* make all stack variables saved */
3535 sd.var[copy->varnum].flags |= SAVEDVAR;
3536 copy->flags |= SAVEDVAR;
3541 #endif /* !SUPPORT_DIVISION */
3552 COUNT(count_pcmd_op);
3553 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3558 coalescing_boundary = sd.new;
3559 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3560 bte = iptr->sx.s23.s3.bte;
3563 if (md->memuse > rd->memuse)
3564 rd->memuse = md->memuse;
3565 if (md->argintreguse > rd->argintreguse)
3566 rd->argintreguse = md->argintreguse;
3567 /* XXX non-leaf method? */
3569 /* make all stack variables saved */
3573 sd.var[copy->varnum].flags |= SAVEDVAR;
3574 copy->flags |= SAVEDVAR;
3579 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3584 #if SUPPORT_LONG_LOGICAL
3588 #endif /* SUPPORT_LONG_LOGICAL */
3589 COUNT(count_pcmd_op);
3590 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3596 COUNT(count_pcmd_op);
3597 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3605 COUNT(count_pcmd_op);
3606 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3614 COUNT(count_pcmd_op);
3615 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3619 COUNT(count_pcmd_op);
3620 #if SUPPORT_LONG_CMP_CONST
3621 if ((len == 0) || (iptr[1].sx.val.i != 0))
3624 switch (iptr[1].opc) {
3626 iptr->opc = ICMD_IF_LCMPEQ;
3628 iptr->dst.insindex = iptr[1].dst.insindex;
3629 iptr[1].opc = ICMD_NOP;
3631 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3632 BRANCH(tbptr, copy);
3634 COUNT(count_pcmd_bra);
3637 iptr->opc = ICMD_IF_LCMPNE;
3638 goto icmd_lcmp_if_tail;
3640 iptr->opc = ICMD_IF_LCMPLT;
3641 goto icmd_lcmp_if_tail;
3643 iptr->opc = ICMD_IF_LCMPGT;
3644 goto icmd_lcmp_if_tail;
3646 iptr->opc = ICMD_IF_LCMPLE;
3647 goto icmd_lcmp_if_tail;
3649 iptr->opc = ICMD_IF_LCMPGE;
3650 goto icmd_lcmp_if_tail;
3656 #endif /* SUPPORT_LONG_CMP_CONST */
3657 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3660 /* XXX why is this deactivated? */
3663 COUNT(count_pcmd_op);
3664 if ((len == 0) || (iptr[1].sx.val.i != 0))
3667 switch (iptr[1].opc) {
3669 iptr->opc = ICMD_IF_FCMPEQ;
3671 iptr->dst.insindex = iptr[1].dst.insindex;
3672 iptr[1].opc = ICMD_NOP;
3674 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3675 BRANCH(tbptr, copy);
3677 COUNT(count_pcmd_bra);
3680 iptr->opc = ICMD_IF_FCMPNE;
3681 goto icmd_if_fcmpl_tail;
3683 iptr->opc = ICMD_IF_FCMPL_LT;
3684 goto icmd_if_fcmpl_tail;
3686 iptr->opc = ICMD_IF_FCMPL_GT;
3687 goto icmd_if_fcmpl_tail;
3689 iptr->opc = ICMD_IF_FCMPL_LE;
3690 goto icmd_if_fcmpl_tail;
3692 iptr->opc = ICMD_IF_FCMPL_GE;
3693 goto icmd_if_fcmpl_tail;
3700 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3704 COUNT(count_pcmd_op);
3705 if ((len == 0) || (iptr[1].sx.val.i != 0))
3708 switch (iptr[1].opc) {
3710 iptr->opc = ICMD_IF_FCMPEQ;
3712 iptr->dst.insindex = iptr[1].dst.insindex;
3713 iptr[1].opc = ICMD_NOP;
3715 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3716 BRANCH(tbptr, copy);
3718 COUNT(count_pcmd_bra);
3721 iptr->opc = ICMD_IF_FCMPNE;
3722 goto icmd_if_fcmpg_tail;
3724 iptr->opc = ICMD_IF_FCMPG_LT;
3725 goto icmd_if_fcmpg_tail;
3727 iptr->opc = ICMD_IF_FCMPG_GT;
3728 goto icmd_if_fcmpg_tail;
3730 iptr->opc = ICMD_IF_FCMPG_LE;
3731 goto icmd_if_fcmpg_tail;
3733 iptr->opc = ICMD_IF_FCMPG_GE;
3734 goto icmd_if_fcmpg_tail;
3741 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3745 COUNT(count_pcmd_op);
3746 if ((len == 0) || (iptr[1].sx.val.i != 0))
3749 switch (iptr[1].opc) {
3751 iptr->opc = ICMD_IF_DCMPEQ;
3753 iptr->dst.insindex = iptr[1].dst.insindex;
3754 iptr[1].opc = ICMD_NOP;
3756 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3757 BRANCH(tbptr, copy);
3759 COUNT(count_pcmd_bra);
3762 iptr->opc = ICMD_IF_DCMPNE;
3763 goto icmd_if_dcmpl_tail;
3765 iptr->opc = ICMD_IF_DCMPL_LT;
3766 goto icmd_if_dcmpl_tail;
3768 iptr->opc = ICMD_IF_DCMPL_GT;
3769 goto icmd_if_dcmpl_tail;
3771 iptr->opc = ICMD_IF_DCMPL_LE;
3772 goto icmd_if_dcmpl_tail;
3774 iptr->opc = ICMD_IF_DCMPL_GE;
3775 goto icmd_if_dcmpl_tail;
3782 OPTT2_1(TYPE_DBL, TYPE_INT);
3786 COUNT(count_pcmd_op);
3787 if ((len == 0) || (iptr[1].sx.val.i != 0))
3790 switch (iptr[1].opc) {
3792 iptr->opc = ICMD_IF_DCMPEQ;
3794 iptr->dst.insindex = iptr[1].dst.insindex;
3795 iptr[1].opc = ICMD_NOP;
3797 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3798 BRANCH(tbptr, copy);
3800 COUNT(count_pcmd_bra);
3803 iptr->opc = ICMD_IF_DCMPNE;
3804 goto icmd_if_dcmpg_tail;
3806 iptr->opc = ICMD_IF_DCMPG_LT;
3807 goto icmd_if_dcmpg_tail;
3809 iptr->opc = ICMD_IF_DCMPG_GT;
3810 goto icmd_if_dcmpg_tail;
3812 iptr->opc = ICMD_IF_DCMPG_LE;
3813 goto icmd_if_dcmpg_tail;
3815 iptr->opc = ICMD_IF_DCMPG_GE;
3816 goto icmd_if_dcmpg_tail;
3823 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3828 COUNT(count_pcmd_op);
3829 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3834 COUNT(count_pcmd_op);
3835 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3844 case ICMD_INT2SHORT:
3845 COUNT(count_pcmd_op);
3846 OP1_1(TYPE_INT, TYPE_INT);
3849 COUNT(count_pcmd_op);
3850 OP1_1(TYPE_LNG, TYPE_LNG);
3853 COUNT(count_pcmd_op);
3854 OP1_1(TYPE_FLT, TYPE_FLT);
3857 COUNT(count_pcmd_op);
3858 OP1_1(TYPE_DBL, TYPE_DBL);
3862 COUNT(count_pcmd_op);
3863 OP1_1(TYPE_INT, TYPE_LNG);
3866 COUNT(count_pcmd_op);
3867 OP1_1(TYPE_INT, TYPE_FLT);
3870 COUNT(count_pcmd_op);
3871 OP1_1(TYPE_INT, TYPE_DBL);
3874 COUNT(count_pcmd_op);
3875 OP1_1(TYPE_LNG, TYPE_INT);
3878 COUNT(count_pcmd_op);
3879 OP1_1(TYPE_LNG, TYPE_FLT);
3882 COUNT(count_pcmd_op);
3883 OP1_1(TYPE_LNG, TYPE_DBL);
3886 COUNT(count_pcmd_op);
3887 OP1_1(TYPE_FLT, TYPE_INT);
3890 COUNT(count_pcmd_op);
3891 OP1_1(TYPE_FLT, TYPE_LNG);
3894 COUNT(count_pcmd_op);
3895 OP1_1(TYPE_FLT, TYPE_DBL);
3898 COUNT(count_pcmd_op);
3899 OP1_1(TYPE_DBL, TYPE_INT);
3902 COUNT(count_pcmd_op);
3903 OP1_1(TYPE_DBL, TYPE_LNG);
3906 COUNT(count_pcmd_op);
3907 OP1_1(TYPE_DBL, TYPE_FLT);
3910 case ICMD_CHECKCAST:
3911 coalescing_boundary = sd.new;
3912 if (iptr->flags.bits & INS_FLAG_ARRAY) {
3913 /* array type cast-check */
3915 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
3918 if (md->memuse > rd->memuse)
3919 rd->memuse = md->memuse;
3920 if (md->argintreguse > rd->argintreguse)
3921 rd->argintreguse = md->argintreguse;
3923 /* make all stack variables saved */
3927 sd.var[copy->varnum].flags |= SAVEDVAR;
3928 copy->flags |= SAVEDVAR;
3932 OP1_1(TYPE_ADR, TYPE_ADR);
3935 case ICMD_INSTANCEOF:
3936 case ICMD_ARRAYLENGTH:
3937 coalescing_boundary = sd.new;
3938 OP1_1(TYPE_ADR, TYPE_INT);
3942 case ICMD_ANEWARRAY:
3943 coalescing_boundary = sd.new;
3944 OP1_1(TYPE_INT, TYPE_ADR);
3948 coalescing_boundary = sd.new;
3949 COUNT(count_check_null);
3950 COUNT(count_pcmd_mem);
3951 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3952 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
3957 case ICMD_GETSTATIC:
3958 coalescing_boundary = sd.new;
3959 COUNT(count_pcmd_mem);
3960 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3961 OP0_1(fmiref->parseddesc.fd->type);
3965 coalescing_boundary = sd.new;
3972 assert(sd.bptr->next); /* XXX exception */
3973 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
3975 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
3976 tbptr->type = BBTYPE_SBR;
3978 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
3982 iptr->sx.s23.s3.jsrtarget.block = tbptr;
3984 /* We need to check for overflow right here because
3985 * the pushed value is poped afterwards */
3988 superblockend = true;
3989 /* XXX should not be marked as interface, as it does not need to be */
3990 /* allocated. Same for the invar of the target. */
3993 /* pop many push any */
3997 bte = iptr->sx.s23.s3.bte;
4001 case ICMD_INVOKESTATIC:
4002 case ICMD_INVOKESPECIAL:
4003 case ICMD_INVOKEVIRTUAL:
4004 case ICMD_INVOKEINTERFACE:
4005 COUNT(count_pcmd_met);
4007 /* Check for functions to replace with builtin
4010 if (builtintable_replace_function(iptr))
4013 INSTRUCTION_GET_METHODDESC(iptr, md);
4014 /* XXX resurrect this COUNT? */
4015 /* if (lm->flags & ACC_STATIC) */
4016 /* {COUNT(count_check_null);} */
4020 coalescing_boundary = sd.new;
4024 if (md->memuse > rd->memuse)
4025 rd->memuse = md->memuse;
4026 if (md->argintreguse > rd->argintreguse)
4027 rd->argintreguse = md->argintreguse;
4028 if (md->argfltreguse > rd->argfltreguse)
4029 rd->argfltreguse = md->argfltreguse;
4033 /* XXX optimize for <= 2 args */
4034 /* XXX not for ICMD_BUILTIN */
4035 iptr->s1.argcount = stackdepth;
4036 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4039 for (i-- ; i >= 0; i--) {
4040 iptr->sx.s23.s2.args[i] = copy->varnum;
4042 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4043 /* -> won't help anyway */
4044 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
4046 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4047 /* If we pass float arguments in integer argument registers, we
4048 * are not allowed to precolor them here. Floats have to be moved
4049 * to this regs explicitly in codegen().
4050 * Only arguments that are passed by stack anyway can be precolored
4051 * (michi 2005/07/24) */
4052 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4053 (!IS_FLT_DBL_TYPE(copy->type)
4054 || md->params[i].inmemory)) {
4056 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4061 #if defined(ENABLE_INTRP)
4064 if (md->params[i].inmemory) {
4065 sd.var[copy->varnum].vv.regoff =
4066 md->params[i].regoff;
4067 sd.var[copy->varnum].flags |=
4071 if (IS_FLT_DBL_TYPE(copy->type)) {
4072 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4073 assert(0); /* XXX is this assert ok? */
4075 sd.var[copy->varnum].vv.regoff =
4076 rd->argfltregs[md->params[i].regoff];
4077 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4080 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4081 if (IS_2_WORD_TYPE(copy->type))
4082 sd.var[copy->varnum].vv.regoff =
4083 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4084 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4087 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4088 sd.var[copy->varnum].vv.regoff =
4089 rd->argintregs[md->params[i].regoff];
4092 #if defined(ENABLE_INTRP)
4093 } /* end if (!opt_intrp) */
4100 /* deal with live-through stack slots "under" the */
4102 /* XXX not for ICMD_BUILTIN */
4108 iptr->sx.s23.s2.args[i++] = copy->varnum;
4109 sd.var[copy->varnum].flags |= SAVEDVAR;
4113 /* pop the arguments */
4122 /* push the return value */
4124 if (md->returntype.type != TYPE_VOID) {
4125 GET_NEW_VAR(sd, new_index, md->returntype.type);
4126 DST(md->returntype.type, new_index);
4131 case ICMD_INLINE_START:
4132 case ICMD_INLINE_END:
4137 case ICMD_MULTIANEWARRAY:
4138 coalescing_boundary = sd.new;
4139 if (rd->argintreguse < 3)
4140 rd->argintreguse = 3;
4142 i = iptr->s1.argcount;
4146 iptr->sx.s23.s2.args = DMNEW(s4, i);
4148 #if defined(SPECIALMEMUSE)
4149 # if defined(__DARWIN__)
4150 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4151 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4153 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4154 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4157 # if defined(__I386__)
4158 if (rd->memuse < i + 3)
4159 rd->memuse = i + 3; /* n integer args spilled on stack */
4160 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4161 if (rd->memuse < i + 2)
4162 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4165 rd->memuse = i; /* n integer args spilled on stack */
4166 # endif /* defined(__I386__) */
4170 /* check INT type here? Currently typecheck does this. */
4171 iptr->sx.s23.s2.args[i] = copy->varnum;
4172 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4173 && (!IS_OUTVAR(copy))
4174 && (!IS_LOCALVAR(copy)) ) {
4175 copy->varkind = ARGVAR;
4176 sd.var[copy->varnum].flags |=
4177 INMEMORY & PREALLOC;
4178 #if defined(SPECIALMEMUSE)
4179 # if defined(__DARWIN__)
4180 sd.var[copy->varnum].vv.regoff = i +
4181 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4183 sd.var[copy->varnum].vv.regoff = i +
4184 LA_SIZE_IN_POINTERS + 3;
4187 # if defined(__I386__)
4188 sd.var[copy->varnum].vv.regoff = i + 3;
4189 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4190 sd.var[copy->varnum].vv.regoff = i + 2;
4192 sd.var[copy->varnum].vv.regoff = i;
4193 # endif /* defined(__I386__) */
4194 #endif /* defined(SPECIALMEMUSE) */
4199 sd.var[copy->varnum].flags |= SAVEDVAR;
4203 i = iptr->s1.argcount;
4208 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4209 DST(TYPE_ADR, new_index);
4215 new_internalerror("Unknown ICMD %d", opcode);
4221 } /* while instructions */
4223 /* stack slots at basic block end become interfaces */
4225 sd.bptr->outdepth = stackdepth;
4226 sd.bptr->outvars = DMNEW(s4, stackdepth);
4229 for (copy = curstack; copy; i--, copy = copy->prev) {
4233 /* with the new vars rd->interfaces will be removed */
4234 /* and all in and outvars have to be STACKVARS! */
4235 /* in the moment i.e. SWAP with in and out vars can */
4236 /* create an unresolvable conflict */
4243 v = sd.var + copy->varnum;
4246 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4247 /* no interface var until now for this depth and */
4249 jd->interface_map[i*5 + t].flags = v->flags;
4252 jd->interface_map[i*5 + t].flags |= v->flags;
4255 sd.bptr->outvars[i] = copy->varnum;
4258 /* check if interface slots at basic block begin must be saved */
4260 for (i=0; i<sd.bptr->indepth; ++i) {
4261 varinfo *v = sd.var + sd.bptr->invars[i];
4268 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4269 /* no interface var until now for this depth and */
4271 jd->interface_map[i*5 + t].flags = v->flags;
4274 jd->interface_map[i*5 + t].flags |= v->flags;
4279 /* store the number of this block's variables */
4281 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4283 #if defined(STACK_VERBOSE)
4284 stack_verbose_block_exit(&sd, superblockend);
4287 /* reach the following block, if any */
4290 if (!stack_reach_next_block(&sd))
4295 } while (sd.repeat && !deadcode);
4297 /* XXX reset TYPE_RET to TYPE_ADR */
4299 for (i=0; i<sd.vartop; ++i) {
4300 if (sd.var[i].type == TYPE_RET)
4301 sd.var[i].type = TYPE_ADR;
4304 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4306 ex = cd->exceptiontable;
4307 for (; ex != NULL; ex = ex->down) {
4308 if (ex->start == ex->end) {
4309 assert(ex->end->next);
4310 ex->end = ex->end->next;
4314 /* gather statistics *****************************************************/
4316 #if defined(ENABLE_STATISTICS)
4318 if (jd->new_basicblockcount > count_max_basic_blocks)
4319 count_max_basic_blocks = jd->new_basicblockcount;
4320 count_basic_blocks += jd->new_basicblockcount;
4321 if (jd->new_instructioncount > count_max_javainstr)
4322 count_max_javainstr = jd->new_instructioncount;
4323 count_javainstr += jd->new_instructioncount;
4324 if (jd->new_stackcount > count_upper_bound_new_stack)
4325 count_upper_bound_new_stack = jd->new_stackcount;
4326 if ((sd.new - jd->new_stack) > count_max_new_stack)
4327 count_max_new_stack = (sd.new - jd->new_stack);
4329 sd.bptr = jd->new_basicblocks;
4330 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4331 if (sd.bptr->flags > BBREACHED) {
4332 if (sd.bptr->indepth >= 10)
4333 count_block_stack[10]++;
4335 count_block_stack[sd.bptr->indepth]++;
4336 len = sd.bptr->icount;
4338 count_block_size_distribution[len]++;
4340 count_block_size_distribution[10]++;
4342 count_block_size_distribution[11]++;
4344 count_block_size_distribution[12]++;
4346 count_block_size_distribution[13]++;
4348 count_block_size_distribution[14]++;
4350 count_block_size_distribution[15]++;
4352 count_block_size_distribution[16]++;
4354 count_block_size_distribution[17]++;
4358 if (iteration_count == 1)
4359 count_analyse_iterations[0]++;
4360 else if (iteration_count == 2)
4361 count_analyse_iterations[1]++;
4362 else if (iteration_count == 3)
4363 count_analyse_iterations[2]++;
4364 else if (iteration_count == 4)
4365 count_analyse_iterations[3]++;
4367 count_analyse_iterations[4]++;
4369 if (jd->new_basicblockcount <= 5)
4370 count_method_bb_distribution[0]++;
4371 else if (jd->new_basicblockcount <= 10)
4372 count_method_bb_distribution[1]++;
4373 else if (jd->new_basicblockcount <= 15)
4374 count_method_bb_distribution[2]++;
4375 else if (jd->new_basicblockcount <= 20)
4376 count_method_bb_distribution[3]++;
4377 else if (jd->new_basicblockcount <= 30)
4378 count_method_bb_distribution[4]++;
4379 else if (jd->new_basicblockcount <= 40)
4380 count_method_bb_distribution[5]++;
4381 else if (jd->new_basicblockcount <= 50)
4382 count_method_bb_distribution[6]++;
4383 else if (jd->new_basicblockcount <= 75)
4384 count_method_bb_distribution[7]++;
4386 count_method_bb_distribution[8]++;
4388 #endif /* defined(ENABLE_STATISTICS) */
4390 /* everything's ok *******************************************************/
4394 /* goto labels for throwing verifier exceptions **************************/
4396 #if defined(ENABLE_VERIFIER)
4398 throw_stack_underflow:
4399 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4402 throw_stack_overflow:
4403 exceptions_throw_verifyerror(m, "Stack size too large");
4406 throw_stack_depth_error:
4407 exceptions_throw_verifyerror(m,"Stack depth mismatch");
4410 throw_stack_type_error:
4411 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4414 throw_stack_category_error:
4415 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4422 /* functions for verbose stack analysis output ********************************/
4424 #if defined(STACK_VERBOSE)
4425 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4427 printf("%c", show_jit_type_letters[v->type]);
4428 if (v->type == TYPE_RET)
4429 printf("{L%03d}", v->vv.retaddr->nr);
4433 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4435 assert(index >= 0 && index < sd->vartop);
4436 stack_verbose_show_varinfo(sd, sd->var + index);
4440 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4444 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4446 for (i=0; i<bptr->indepth; ++i) {
4449 stack_verbose_show_variable(sd, bptr->invars[i]);
4454 printf("] inlocals [");
4455 if (bptr->inlocals) {
4456 for (i=0; i<sd->localcount; ++i) {
4459 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4464 printf("] out:%d [", bptr->outdepth);
4465 if (bptr->outvars) {
4466 for (i=0; i<bptr->outdepth; ++i) {
4469 stack_verbose_show_variable(sd, bptr->outvars[i]);
4477 printf(" (clone of L%03d)", bptr->original->nr);
4479 basicblock *b = bptr->copied_to;
4481 printf(" (copied to ");
4482 for (; b; b = b->copied_to)
4483 printf("L%03d ", b->nr);
4490 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4494 printf("======================================== STACK %sANALYSE BLOCK ",
4495 (reanalyse) ? "RE-" : "");
4496 stack_verbose_show_block(sd, sd->bptr);
4499 if (sd->handlers[0]) {
4500 printf("HANDLERS: ");
4501 for (i=0; sd->handlers[i]; ++i) {
4502 printf("L%03d ", sd->handlers[i]->handler->nr);
4510 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4512 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4513 stack_verbose_show_block(sd, sd->bptr);
4520 * These are local overrides for various environment variables in Emacs.
4521 * Please do not remove this and leave it at the end of the file, where
4522 * Emacs will automagically detect them.
4523 * ---------------------------------------------------------------------
4526 * indent-tabs-mode: t
4530 * vim:noexpandtab:sw=4:ts=4: