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 5473 2006-09-11 23:32:45Z 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;
1187 #if defined(STACK_VERBOSE)
1188 stack_verbose_block_enter(sd, true);
1195 assert(orig != NULL);
1197 /* clone the instruction list */
1199 cloneinstructions = true;
1201 assert(orig->iinstr);
1203 iptr = DMNEW(instruction, len + 1);
1205 MCOPY(iptr, orig->iinstr, instruction, len);
1206 iptr[len].opc = ICMD_NOP;
1210 /* allocate space for the clone's block variables */
1212 stack_grow_variable_array(sd, orig->varcount);
1214 /* we already have the invars set */
1216 assert(b->indepth == orig->indepth);
1218 /* calculate relocation shifts for invars and block variables */
1220 if (orig->indepth) {
1221 invarstart = orig->invars[0];
1222 invarshift = b->invars[0] - invarstart;
1225 invarstart = INT_MAX;
1228 blockvarstart = orig->varstart;
1229 blockvarshift = sd->vartop - blockvarstart;
1231 /* copy block variables */
1233 b->varstart = sd->vartop;
1234 b->varcount = orig->varcount;
1235 sd->vartop += b->varcount;
1236 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1240 b->outdepth = orig->outdepth;
1241 b->outvars = DMNEW(s4, orig->outdepth);
1242 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1244 /* clone exception handlers */
1246 for (i=0; sd->handlers[i]; ++i) {
1247 ex = DNEW(exceptiontable);
1248 ex->handler = sd->handlers[i]->handler;
1250 ex->end = b; /* XXX hack, see end of new_stack_analyse */
1251 ex->catchtype = sd->handlers[i]->catchtype;
1254 assert(sd->extableend->down == NULL);
1255 sd->extableend->down = ex;
1256 sd->extableend = ex;
1257 sd->jd->cd->exceptiontablelength++;
1259 sd->handlers[i] = ex;
1263 cloneinstructions = false;
1266 invarstart = sd->vartop;
1267 blockvarstart = sd->vartop;
1272 /* find exception handlers for the cloned block */
1274 ex = sd->jd->cd->exceptiontable;
1275 for (; ex != NULL; ex = ex->down) {
1276 /* XXX the cloned exception handlers have identical */
1277 /* start end end blocks. */
1278 if ((ex->start == b) && (ex->end == b)) {
1279 sd->handlers[len++] = ex;
1282 sd->handlers[len] = NULL;
1285 #if defined(STACK_VERBOSE)
1286 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1287 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1290 /* mark block as finished */
1292 b->flags = BBFINISHED;
1294 /* initialize locals at the start of this block */
1297 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1299 /* reach exception handlers for this block */
1301 if (!stack_reach_handlers(sd))
1304 superblockend = false;
1306 for (len = b->icount; len--; iptr++) {
1307 #if defined(STACK_VERBOSE)
1308 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1314 switch (iptr->opc) {
1316 j = iptr->s1.varindex;
1318 if (sd->var[j].type != TYPE_RET) {
1319 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1323 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1324 superblockend = true;
1328 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1329 superblockend = true;
1333 superblockend = true;
1336 case ICMD_CHECKNULL:
1337 case ICMD_PUTSTATICCONST:
1343 case ICMD_INLINE_START:
1344 case ICMD_INLINE_END:
1345 case ICMD_INLINE_GOTO:
1349 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1350 superblockend = true;
1353 /* pop 0 push 1 const */
1362 /* pop 0 push 1 load */
1369 RELOCATE(iptr->dst.varindex);
1382 RELOCATE(iptr->sx.s23.s2.varindex);
1383 RELOCATE(iptr->s1.varindex);
1384 RELOCATE(iptr->dst.varindex);
1398 RELOCATE(iptr->sx.s23.s3.varindex);
1399 RELOCATE(iptr->sx.s23.s2.varindex);
1400 RELOCATE(iptr->s1.varindex);
1404 /* pop 1 push 0 store */
1411 RELOCATE(iptr->s1.varindex);
1413 j = iptr->dst.varindex;
1414 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1426 RELOCATE(iptr->s1.varindex);
1427 superblockend = true;
1430 case ICMD_PUTSTATIC:
1431 case ICMD_PUTFIELDCONST:
1434 RELOCATE(iptr->s1.varindex);
1437 /* pop 1 push 0 branch */
1440 case ICMD_IFNONNULL:
1455 RELOCATE(iptr->s1.varindex);
1456 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1459 /* pop 1 push 0 table branch */
1461 case ICMD_TABLESWITCH:
1462 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1464 if (cloneinstructions) {
1465 table = DMNEW(branch_target_t, i);
1466 MCOPY(table, iptr->dst.table, branch_target_t, i);
1467 iptr->dst.table = table;
1470 table = iptr->dst.table;
1473 RELOCATE(iptr->s1.varindex);
1475 table->block = stack_mark_reached_from_outvars(sd, table->block);
1478 superblockend = true;
1481 case ICMD_LOOKUPSWITCH:
1482 i = iptr->sx.s23.s2.lookupcount;
1483 if (cloneinstructions) {
1484 lookup = DMNEW(lookup_target_t, i);
1485 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1486 iptr->dst.lookup = lookup;
1489 lookup = iptr->dst.lookup;
1491 RELOCATE(iptr->s1.varindex);
1493 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1496 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1497 superblockend = true;
1500 case ICMD_MONITORENTER:
1501 case ICMD_MONITOREXIT:
1502 RELOCATE(iptr->s1.varindex);
1506 /* pop 2 push 0 branch */
1508 case ICMD_IF_ICMPEQ:
1509 case ICMD_IF_ICMPNE:
1510 case ICMD_IF_ICMPLT:
1511 case ICMD_IF_ICMPGE:
1512 case ICMD_IF_ICMPGT:
1513 case ICMD_IF_ICMPLE:
1515 case ICMD_IF_LCMPEQ:
1516 case ICMD_IF_LCMPNE:
1517 case ICMD_IF_LCMPLT:
1518 case ICMD_IF_LCMPGE:
1519 case ICMD_IF_LCMPGT:
1520 case ICMD_IF_LCMPLE:
1522 case ICMD_IF_FCMPEQ:
1523 case ICMD_IF_FCMPNE:
1525 case ICMD_IF_FCMPL_LT:
1526 case ICMD_IF_FCMPL_GE:
1527 case ICMD_IF_FCMPL_GT:
1528 case ICMD_IF_FCMPL_LE:
1530 case ICMD_IF_FCMPG_LT:
1531 case ICMD_IF_FCMPG_GE:
1532 case ICMD_IF_FCMPG_GT:
1533 case ICMD_IF_FCMPG_LE:
1535 case ICMD_IF_DCMPEQ:
1536 case ICMD_IF_DCMPNE:
1538 case ICMD_IF_DCMPL_LT:
1539 case ICMD_IF_DCMPL_GE:
1540 case ICMD_IF_DCMPL_GT:
1541 case ICMD_IF_DCMPL_LE:
1543 case ICMD_IF_DCMPG_LT:
1544 case ICMD_IF_DCMPG_GE:
1545 case ICMD_IF_DCMPG_GT:
1546 case ICMD_IF_DCMPG_LE:
1548 case ICMD_IF_ACMPEQ:
1549 case ICMD_IF_ACMPNE:
1550 RELOCATE(iptr->sx.s23.s2.varindex);
1551 RELOCATE(iptr->s1.varindex);
1552 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1558 case ICMD_IASTORECONST:
1559 case ICMD_LASTORECONST:
1560 case ICMD_AASTORECONST:
1561 case ICMD_BASTORECONST:
1562 case ICMD_CASTORECONST:
1563 case ICMD_SASTORECONST:
1566 RELOCATE(iptr->sx.s23.s2.varindex);
1567 RELOCATE(iptr->s1.varindex);
1570 /* pop 0 push 1 copy */
1574 RELOCATE(iptr->dst.varindex);
1575 RELOCATE(iptr->s1.varindex);
1576 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1619 RELOCATE(iptr->sx.s23.s2.varindex);
1620 RELOCATE(iptr->s1.varindex);
1621 RELOCATE(iptr->dst.varindex);
1626 case ICMD_CHECKCAST:
1627 case ICMD_ARRAYLENGTH:
1628 case ICMD_INSTANCEOF:
1630 case ICMD_ANEWARRAY:
1633 case ICMD_IADDCONST:
1634 case ICMD_ISUBCONST:
1635 case ICMD_IMULCONST:
1639 case ICMD_IANDCONST:
1641 case ICMD_IXORCONST:
1642 case ICMD_ISHLCONST:
1643 case ICMD_ISHRCONST:
1644 case ICMD_IUSHRCONST:
1645 case ICMD_LADDCONST:
1646 case ICMD_LSUBCONST:
1647 case ICMD_LMULCONST:
1651 case ICMD_LANDCONST:
1653 case ICMD_LXORCONST:
1654 case ICMD_LSHLCONST:
1655 case ICMD_LSHRCONST:
1656 case ICMD_LUSHRCONST:
1660 case ICMD_INT2SHORT:
1676 RELOCATE(iptr->s1.varindex);
1677 RELOCATE(iptr->dst.varindex);
1682 case ICMD_GETSTATIC:
1685 RELOCATE(iptr->dst.varindex);
1688 /* pop many push any */
1690 case ICMD_INVOKESTATIC:
1691 case ICMD_INVOKESPECIAL:
1692 case ICMD_INVOKEVIRTUAL:
1693 case ICMD_INVOKEINTERFACE:
1695 case ICMD_MULTIANEWARRAY:
1696 i = iptr->s1.argcount;
1697 if (cloneinstructions) {
1698 argp = DMNEW(s4, i);
1699 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1700 iptr->sx.s23.s2.args = argp;
1703 argp = iptr->sx.s23.s2.args;
1711 RELOCATE(iptr->dst.varindex);
1716 new_internalerror("Unknown ICMD %d during stack re-analysis",
1721 #if defined(STACK_VERBOSE)
1722 new_show_icmd(sd->jd, iptr, false, SHOW_STACK);
1727 /* relocate outvars */
1729 for (i=0; i<b->outdepth; ++i) {
1730 RELOCATE(b->outvars[i]);
1733 #if defined(STACK_VERBOSE)
1734 stack_verbose_block_exit(sd, superblockend);
1737 /* propagate to the next block */
1740 if (!stack_reach_next_block(sd))
1747 /* stack_analyse ***************************************************************
1749 Analyse_stack uses the intermediate code created by parse.c to
1750 build a model of the JVM operand stack for the current method.
1752 The following checks are performed:
1753 - check for operand stack underflow (before each instruction)
1754 - check for operand stack overflow (after[1] each instruction)
1755 - check for matching stack depth at merging points
1756 - check for matching basic types[2] at merging points
1757 - check basic types for instruction input (except for BUILTIN*
1758 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1760 [1]) Checking this after the instruction should be ok. parse.c
1761 counts the number of required stack slots in such a way that it is
1762 only vital that we don't exceed `maxstack` at basic block
1765 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1766 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1767 types are not discerned.
1769 *******************************************************************************/
1771 bool new_stack_analyse(jitdata *jd)
1773 methodinfo *m; /* method being analyzed */
1778 int b_index; /* basic block index */
1780 stackptr curstack; /* current stack top */
1782 int opcode; /* opcode of current instruction */
1785 int len; /* # of instructions after the current one */
1786 bool superblockend; /* if true, no fallthrough to next block */
1787 bool deadcode; /* true if no live code has been reached */
1788 instruction *iptr; /* the current instruction */
1790 basicblock *original;
1793 stackptr *last_store_boundary;
1794 stackptr coalescing_boundary;
1796 stackptr src1, src2, src3, src4, dst1, dst2;
1798 branch_target_t *table;
1799 lookup_target_t *lookup;
1800 #if defined(ENABLE_VERIFIER)
1801 int expectedtype; /* used by CHECK_BASIC_TYPE */
1803 builtintable_entry *bte;
1805 constant_FMIref *fmiref;
1806 #if defined(ENABLE_STATISTICS)
1807 int iteration_count; /* number of iterations of analysis */
1809 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1811 #if defined(STACK_VERBOSE)
1812 new_show_method(jd, SHOW_PARSE);
1815 /* get required compiler data - initialization */
1822 /* initialize the stackdata_t struct */
1826 sd.varcount = jd->varcount;
1827 sd.vartop = jd->vartop;
1828 sd.localcount = jd->localcount;
1830 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1831 sd.exstack.type = TYPE_ADR;
1832 sd.exstack.prev = NULL;
1833 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1835 #if defined(ENABLE_LSRA)
1836 m->maxlifetimes = 0;
1839 #if defined(ENABLE_STATISTICS)
1840 iteration_count = 0;
1843 /* find the last real basic block */
1845 sd.last_real_block = NULL;
1846 tbptr = jd->new_basicblocks;
1847 while (tbptr->next) {
1848 sd.last_real_block = tbptr;
1849 tbptr = tbptr->next;
1851 assert(sd.last_real_block);
1853 /* find the last exception handler */
1855 if (cd->exceptiontablelength)
1856 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1858 sd.extableend = NULL;
1860 /* init jd->interface_map */
1862 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1863 for (i = 0; i < m->maxstack * 5; i++)
1864 jd->interface_map[i].flags = UNUSED;
1866 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1868 /* initialize flags and invars (none) of first block */
1870 jd->new_basicblocks[0].flags = BBREACHED;
1871 jd->new_basicblocks[0].invars = NULL;
1872 jd->new_basicblocks[0].indepth = 0;
1874 /* stack analysis loop (until fixpoint reached) **************************/
1877 #if defined(ENABLE_STATISTICS)
1881 /* initialize loop over basic blocks */
1883 sd.bptr = jd->new_basicblocks;
1884 superblockend = true;
1886 curstack = NULL; stackdepth = 0;
1889 /* iterate over basic blocks *****************************************/
1891 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1893 if (sd.bptr->flags == BBDELETED) {
1894 /* This block has been deleted - do nothing. */
1899 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1900 /* This block has not been reached so far, and we */
1901 /* don't fall into it, so we'll have to iterate again. */
1907 if (sd.bptr->flags > BBREACHED) {
1908 /* This block is already finished. */
1910 superblockend = true;
1914 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1915 /* This block is a clone and the original has not been */
1916 /* analysed, yet. Analyse it on the next iteration. */
1922 /* This block has to be analysed now. */
1924 /* XXX The rest of this block is still indented one level too */
1925 /* much in order to avoid a giant diff by changing that. */
1927 /* We know that sd.bptr->flags == BBREACHED. */
1928 /* This block has been reached before. */
1930 assert(sd.bptr->flags == BBREACHED);
1931 stackdepth = sd.bptr->indepth;
1933 /* find exception handlers for this block */
1935 /* determine the active exception handlers for this block */
1936 /* XXX could use a faster algorithm with sorted lists or */
1939 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1942 ex = cd->exceptiontable;
1943 for (; ex != NULL; ex = ex->down) {
1944 if ((ex->start <= original) && (ex->end > original)) {
1945 sd.handlers[len++] = ex;
1948 sd.handlers[len] = NULL;
1951 /* reanalyse cloned block */
1953 if (sd.bptr->original) {
1954 if (!stack_reanalyse_block(&sd))
1959 /* reset the new pointer for allocating stackslots */
1961 sd.new = jd->new_stack;
1963 /* create the instack of this block */
1965 curstack = stack_create_instack(&sd);
1967 /* initialize locals at the start of this block */
1969 if (sd.bptr->inlocals)
1970 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1972 /* set up local variables for analyzing this block */
1975 superblockend = false;
1976 len = sd.bptr->icount;
1977 iptr = sd.bptr->iinstr;
1978 b_index = sd.bptr - jd->new_basicblocks;
1980 /* mark the block as analysed */
1982 sd.bptr->flags = BBFINISHED;
1984 /* reset variables for dependency checking */
1986 coalescing_boundary = sd.new;
1987 for( i = 0; i < cd->maxlocals; i++)
1988 last_store_boundary[i] = sd.new;
1990 /* remember the start of this block's variables */
1992 sd.bptr->varstart = sd.vartop;
1994 #if defined(STACK_VERBOSE)
1995 stack_verbose_block_enter(&sd, false);
1998 /* reach exception handlers for this block */
2000 if (!stack_reach_handlers(&sd))
2003 /* iterate over ICMDs ****************************************/
2005 while (--len >= 0) {
2007 #if defined(STACK_VERBOSE)
2008 new_show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2009 for( copy = curstack; copy; copy = copy->prev ) {
2010 printf("%2d(%d", copy->varnum, copy->type);
2011 if (IS_OUTVAR(copy))
2013 if (IS_PREALLOC(copy))
2020 /* fetch the current opcode */
2024 /* automatically replace some ICMDs with builtins */
2026 #if defined(USEBUILTINTABLE)
2028 bte = builtintable_get_automatic(opcode);
2030 if (bte && bte->opcode == opcode) {
2031 iptr->opc = ICMD_BUILTIN;
2032 iptr->flags.bits = 0;
2033 iptr->sx.s23.s3.bte = bte;
2034 /* iptr->line is already set */
2035 jd->isleafmethod = false;
2039 #endif /* defined(USEBUILTINTABLE) */
2041 /* main opcode switch *************************************/
2053 case ICMD_CHECKNULL:
2054 coalescing_boundary = sd.new;
2055 COUNT(count_check_null);
2058 CLR_DST; /* XXX live through? */
2062 j = iptr->s1.varindex =
2063 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2065 if (sd.var[j].type != TYPE_RET) {
2066 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2072 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2074 IF_NO_INTRP( rd->locals[iptr->s1.localindex/*XXX invalid here*/][TYPE_ADR].type = TYPE_ADR; );
2076 superblockend = true;
2080 COUNT(count_pcmd_return);
2083 superblockend = true;
2087 /* pop 0 push 1 const */
2089 /************************** ICONST OPTIMIZATIONS **************************/
2092 COUNT(count_pcmd_load);
2096 switch (iptr[1].opc) {
2098 iptr->opc = ICMD_IADDCONST;
2102 iptr[1].opc = ICMD_NOP;
2103 OP1_1(TYPE_INT, TYPE_INT);
2104 COUNT(count_pcmd_op);
2108 iptr->opc = ICMD_ISUBCONST;
2109 goto icmd_iconst_tail;
2110 #if SUPPORT_CONST_MUL
2112 iptr->opc = ICMD_IMULCONST;
2113 goto icmd_iconst_tail;
2114 #else /* SUPPORT_CONST_MUL */
2116 if (iptr->sx.val.i == 0x00000002)
2118 else if (iptr->sx.val.i == 0x00000004)
2120 else if (iptr->sx.val.i == 0x00000008)
2122 else if (iptr->sx.val.i == 0x00000010)
2124 else if (iptr->sx.val.i == 0x00000020)
2126 else if (iptr->sx.val.i == 0x00000040)
2128 else if (iptr->sx.val.i == 0x00000080)
2130 else if (iptr->sx.val.i == 0x00000100)
2132 else if (iptr->sx.val.i == 0x00000200)
2134 else if (iptr->sx.val.i == 0x00000400)
2135 iptr->sx.val.i = 10;
2136 else if (iptr->sx.val.i == 0x00000800)
2137 iptr->sx.val.i = 11;
2138 else if (iptr->sx.val.i == 0x00001000)
2139 iptr->sx.val.i = 12;
2140 else if (iptr->sx.val.i == 0x00002000)
2141 iptr->sx.val.i = 13;
2142 else if (iptr->sx.val.i == 0x00004000)
2143 iptr->sx.val.i = 14;
2144 else if (iptr->sx.val.i == 0x00008000)
2145 iptr->sx.val.i = 15;
2146 else if (iptr->sx.val.i == 0x00010000)
2147 iptr->sx.val.i = 16;
2148 else if (iptr->sx.val.i == 0x00020000)
2149 iptr->sx.val.i = 17;
2150 else if (iptr->sx.val.i == 0x00040000)
2151 iptr->sx.val.i = 18;
2152 else if (iptr->sx.val.i == 0x00080000)
2153 iptr->sx.val.i = 19;
2154 else if (iptr->sx.val.i == 0x00100000)
2155 iptr->sx.val.i = 20;
2156 else if (iptr->sx.val.i == 0x00200000)
2157 iptr->sx.val.i = 21;
2158 else if (iptr->sx.val.i == 0x00400000)
2159 iptr->sx.val.i = 22;
2160 else if (iptr->sx.val.i == 0x00800000)
2161 iptr->sx.val.i = 23;
2162 else if (iptr->sx.val.i == 0x01000000)
2163 iptr->sx.val.i = 24;
2164 else if (iptr->sx.val.i == 0x02000000)
2165 iptr->sx.val.i = 25;
2166 else if (iptr->sx.val.i == 0x04000000)
2167 iptr->sx.val.i = 26;
2168 else if (iptr->sx.val.i == 0x08000000)
2169 iptr->sx.val.i = 27;
2170 else if (iptr->sx.val.i == 0x10000000)
2171 iptr->sx.val.i = 28;
2172 else if (iptr->sx.val.i == 0x20000000)
2173 iptr->sx.val.i = 29;
2174 else if (iptr->sx.val.i == 0x40000000)
2175 iptr->sx.val.i = 30;
2176 else if (iptr->sx.val.i == 0x80000000)
2177 iptr->sx.val.i = 31;
2181 iptr->opc = ICMD_IMULPOW2;
2182 goto icmd_iconst_tail;
2183 #endif /* SUPPORT_CONST_MUL */
2185 if (iptr->sx.val.i == 0x00000002)
2187 else if (iptr->sx.val.i == 0x00000004)
2189 else if (iptr->sx.val.i == 0x00000008)
2191 else if (iptr->sx.val.i == 0x00000010)
2193 else if (iptr->sx.val.i == 0x00000020)
2195 else if (iptr->sx.val.i == 0x00000040)
2197 else if (iptr->sx.val.i == 0x00000080)
2199 else if (iptr->sx.val.i == 0x00000100)
2201 else if (iptr->sx.val.i == 0x00000200)
2203 else if (iptr->sx.val.i == 0x00000400)
2204 iptr->sx.val.i = 10;
2205 else if (iptr->sx.val.i == 0x00000800)
2206 iptr->sx.val.i = 11;
2207 else if (iptr->sx.val.i == 0x00001000)
2208 iptr->sx.val.i = 12;
2209 else if (iptr->sx.val.i == 0x00002000)
2210 iptr->sx.val.i = 13;
2211 else if (iptr->sx.val.i == 0x00004000)
2212 iptr->sx.val.i = 14;
2213 else if (iptr->sx.val.i == 0x00008000)
2214 iptr->sx.val.i = 15;
2215 else if (iptr->sx.val.i == 0x00010000)
2216 iptr->sx.val.i = 16;
2217 else if (iptr->sx.val.i == 0x00020000)
2218 iptr->sx.val.i = 17;
2219 else if (iptr->sx.val.i == 0x00040000)
2220 iptr->sx.val.i = 18;
2221 else if (iptr->sx.val.i == 0x00080000)
2222 iptr->sx.val.i = 19;
2223 else if (iptr->sx.val.i == 0x00100000)
2224 iptr->sx.val.i = 20;
2225 else if (iptr->sx.val.i == 0x00200000)
2226 iptr->sx.val.i = 21;
2227 else if (iptr->sx.val.i == 0x00400000)
2228 iptr->sx.val.i = 22;
2229 else if (iptr->sx.val.i == 0x00800000)
2230 iptr->sx.val.i = 23;
2231 else if (iptr->sx.val.i == 0x01000000)
2232 iptr->sx.val.i = 24;
2233 else if (iptr->sx.val.i == 0x02000000)
2234 iptr->sx.val.i = 25;
2235 else if (iptr->sx.val.i == 0x04000000)
2236 iptr->sx.val.i = 26;
2237 else if (iptr->sx.val.i == 0x08000000)
2238 iptr->sx.val.i = 27;
2239 else if (iptr->sx.val.i == 0x10000000)
2240 iptr->sx.val.i = 28;
2241 else if (iptr->sx.val.i == 0x20000000)
2242 iptr->sx.val.i = 29;
2243 else if (iptr->sx.val.i == 0x40000000)
2244 iptr->sx.val.i = 30;
2245 else if (iptr->sx.val.i == 0x80000000)
2246 iptr->sx.val.i = 31;
2250 iptr->opc = ICMD_IDIVPOW2;
2251 goto icmd_iconst_tail;
2254 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2255 if ((iptr->sx.val.i == 0x00000002) ||
2256 (iptr->sx.val.i == 0x00000004) ||
2257 (iptr->sx.val.i == 0x00000008) ||
2258 (iptr->sx.val.i == 0x00000010) ||
2259 (iptr->sx.val.i == 0x00000020) ||
2260 (iptr->sx.val.i == 0x00000040) ||
2261 (iptr->sx.val.i == 0x00000080) ||
2262 (iptr->sx.val.i == 0x00000100) ||
2263 (iptr->sx.val.i == 0x00000200) ||
2264 (iptr->sx.val.i == 0x00000400) ||
2265 (iptr->sx.val.i == 0x00000800) ||
2266 (iptr->sx.val.i == 0x00001000) ||
2267 (iptr->sx.val.i == 0x00002000) ||
2268 (iptr->sx.val.i == 0x00004000) ||
2269 (iptr->sx.val.i == 0x00008000) ||
2270 (iptr->sx.val.i == 0x00010000) ||
2271 (iptr->sx.val.i == 0x00020000) ||
2272 (iptr->sx.val.i == 0x00040000) ||
2273 (iptr->sx.val.i == 0x00080000) ||
2274 (iptr->sx.val.i == 0x00100000) ||
2275 (iptr->sx.val.i == 0x00200000) ||
2276 (iptr->sx.val.i == 0x00400000) ||
2277 (iptr->sx.val.i == 0x00800000) ||
2278 (iptr->sx.val.i == 0x01000000) ||
2279 (iptr->sx.val.i == 0x02000000) ||
2280 (iptr->sx.val.i == 0x04000000) ||
2281 (iptr->sx.val.i == 0x08000000) ||
2282 (iptr->sx.val.i == 0x10000000) ||
2283 (iptr->sx.val.i == 0x20000000) ||
2284 (iptr->sx.val.i == 0x40000000) ||
2285 (iptr->sx.val.i == 0x80000000))
2287 iptr->opc = ICMD_IREMPOW2;
2288 iptr->sx.val.i -= 1;
2289 goto icmd_iconst_tail;
2292 #if SUPPORT_CONST_LOGICAL
2294 iptr->opc = ICMD_IANDCONST;
2295 goto icmd_iconst_tail;
2298 iptr->opc = ICMD_IORCONST;
2299 goto icmd_iconst_tail;
2302 iptr->opc = ICMD_IXORCONST;
2303 goto icmd_iconst_tail;
2305 #endif /* SUPPORT_CONST_LOGICAL */
2307 iptr->opc = ICMD_ISHLCONST;
2308 goto icmd_iconst_tail;
2311 iptr->opc = ICMD_ISHRCONST;
2312 goto icmd_iconst_tail;
2315 iptr->opc = ICMD_IUSHRCONST;
2316 goto icmd_iconst_tail;
2317 #if SUPPORT_LONG_SHIFT
2319 iptr->opc = ICMD_LSHLCONST;
2320 goto icmd_lconst_tail;
2323 iptr->opc = ICMD_LSHRCONST;
2324 goto icmd_lconst_tail;
2327 iptr->opc = ICMD_LUSHRCONST;
2328 goto icmd_lconst_tail;
2329 #endif /* SUPPORT_LONG_SHIFT */
2330 case ICMD_IF_ICMPEQ:
2331 iptr[1].opc = ICMD_IFEQ;
2335 /* set the constant for the following icmd */
2336 iptr[1].sx.val.i = iptr->sx.val.i;
2338 /* this instruction becomes a nop */
2339 iptr->opc = ICMD_NOP;
2342 case ICMD_IF_ICMPLT:
2343 iptr[1].opc = ICMD_IFLT;
2344 goto icmd_if_icmp_tail;
2346 case ICMD_IF_ICMPLE:
2347 iptr[1].opc = ICMD_IFLE;
2348 goto icmd_if_icmp_tail;
2350 case ICMD_IF_ICMPNE:
2351 iptr[1].opc = ICMD_IFNE;
2352 goto icmd_if_icmp_tail;
2354 case ICMD_IF_ICMPGT:
2355 iptr[1].opc = ICMD_IFGT;
2356 goto icmd_if_icmp_tail;
2358 case ICMD_IF_ICMPGE:
2359 iptr[1].opc = ICMD_IFGE;
2360 goto icmd_if_icmp_tail;
2362 #if SUPPORT_CONST_STORE
2367 IF_INTRP( goto normal_ICONST; )
2368 # if SUPPORT_CONST_STORE_ZERO_ONLY
2369 if (iptr->sx.val.i != 0)
2372 switch (iptr[1].opc) {
2374 iptr->opc = ICMD_IASTORECONST;
2375 iptr->flags.bits |= INS_FLAG_CHECK;
2378 iptr->opc = ICMD_BASTORECONST;
2379 iptr->flags.bits |= INS_FLAG_CHECK;
2382 iptr->opc = ICMD_CASTORECONST;
2383 iptr->flags.bits |= INS_FLAG_CHECK;
2386 iptr->opc = ICMD_SASTORECONST;
2387 iptr->flags.bits |= INS_FLAG_CHECK;
2391 iptr[1].opc = ICMD_NOP;
2393 /* copy the constant to s3 */
2394 /* XXX constval -> astoreconstval? */
2395 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2396 OP2_0(TYPE_ADR, TYPE_INT);
2397 COUNT(count_pcmd_op);
2400 case ICMD_PUTSTATIC:
2402 IF_INTRP( goto normal_ICONST; )
2403 # if SUPPORT_CONST_STORE_ZERO_ONLY
2404 if (iptr->sx.val.i != 0)
2407 /* XXX check field type? */
2409 /* copy the constant to s2 */
2410 /* XXX constval -> fieldconstval? */
2411 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2414 /* set the field reference (s3) */
2415 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2416 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2417 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2420 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2423 switch (iptr[1].opc) {
2424 case ICMD_PUTSTATIC:
2425 iptr->opc = ICMD_PUTSTATICCONST;
2429 iptr->opc = ICMD_PUTFIELDCONST;
2434 iptr[1].opc = ICMD_NOP;
2435 COUNT(count_pcmd_op);
2437 #endif /* SUPPORT_CONST_STORE */
2443 /* if we get here, the ICONST has been optimized */
2447 /* normal case of an unoptimized ICONST */
2451 /************************** LCONST OPTIMIZATIONS **************************/
2454 COUNT(count_pcmd_load);
2458 /* switch depending on the following instruction */
2460 switch (iptr[1].opc) {
2461 #if SUPPORT_LONG_ADD
2463 iptr->opc = ICMD_LADDCONST;
2467 /* instruction of type LONG -> LONG */
2468 iptr[1].opc = ICMD_NOP;
2469 OP1_1(TYPE_LNG, TYPE_LNG);
2470 COUNT(count_pcmd_op);
2474 iptr->opc = ICMD_LSUBCONST;
2475 goto icmd_lconst_tail;
2477 #endif /* SUPPORT_LONG_ADD */
2478 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2480 iptr->opc = ICMD_LMULCONST;
2481 goto icmd_lconst_tail;
2482 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2483 # if SUPPORT_LONG_SHIFT
2485 if (iptr->sx.val.l == 0x00000002)
2487 else if (iptr->sx.val.l == 0x00000004)
2489 else if (iptr->sx.val.l == 0x00000008)
2491 else if (iptr->sx.val.l == 0x00000010)
2493 else if (iptr->sx.val.l == 0x00000020)
2495 else if (iptr->sx.val.l == 0x00000040)
2497 else if (iptr->sx.val.l == 0x00000080)
2499 else if (iptr->sx.val.l == 0x00000100)
2501 else if (iptr->sx.val.l == 0x00000200)
2503 else if (iptr->sx.val.l == 0x00000400)
2504 iptr->sx.val.i = 10;
2505 else if (iptr->sx.val.l == 0x00000800)
2506 iptr->sx.val.i = 11;
2507 else if (iptr->sx.val.l == 0x00001000)
2508 iptr->sx.val.i = 12;
2509 else if (iptr->sx.val.l == 0x00002000)
2510 iptr->sx.val.i = 13;
2511 else if (iptr->sx.val.l == 0x00004000)
2512 iptr->sx.val.i = 14;
2513 else if (iptr->sx.val.l == 0x00008000)
2514 iptr->sx.val.i = 15;
2515 else if (iptr->sx.val.l == 0x00010000)
2516 iptr->sx.val.i = 16;
2517 else if (iptr->sx.val.l == 0x00020000)
2518 iptr->sx.val.i = 17;
2519 else if (iptr->sx.val.l == 0x00040000)
2520 iptr->sx.val.i = 18;
2521 else if (iptr->sx.val.l == 0x00080000)
2522 iptr->sx.val.i = 19;
2523 else if (iptr->sx.val.l == 0x00100000)
2524 iptr->sx.val.i = 20;
2525 else if (iptr->sx.val.l == 0x00200000)
2526 iptr->sx.val.i = 21;
2527 else if (iptr->sx.val.l == 0x00400000)
2528 iptr->sx.val.i = 22;
2529 else if (iptr->sx.val.l == 0x00800000)
2530 iptr->sx.val.i = 23;
2531 else if (iptr->sx.val.l == 0x01000000)
2532 iptr->sx.val.i = 24;
2533 else if (iptr->sx.val.l == 0x02000000)
2534 iptr->sx.val.i = 25;
2535 else if (iptr->sx.val.l == 0x04000000)
2536 iptr->sx.val.i = 26;
2537 else if (iptr->sx.val.l == 0x08000000)
2538 iptr->sx.val.i = 27;
2539 else if (iptr->sx.val.l == 0x10000000)
2540 iptr->sx.val.i = 28;
2541 else if (iptr->sx.val.l == 0x20000000)
2542 iptr->sx.val.i = 29;
2543 else if (iptr->sx.val.l == 0x40000000)
2544 iptr->sx.val.i = 30;
2545 else if (iptr->sx.val.l == 0x80000000)
2546 iptr->sx.val.i = 31;
2550 iptr->opc = ICMD_LMULPOW2;
2551 goto icmd_lconst_tail;
2552 # endif /* SUPPORT_LONG_SHIFT */
2553 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2554 #if SUPPORT_LONG_DIV_POW2
2556 if (iptr->sx.val.l == 0x00000002)
2558 else if (iptr->sx.val.l == 0x00000004)
2560 else if (iptr->sx.val.l == 0x00000008)
2562 else if (iptr->sx.val.l == 0x00000010)
2564 else if (iptr->sx.val.l == 0x00000020)
2566 else if (iptr->sx.val.l == 0x00000040)
2568 else if (iptr->sx.val.l == 0x00000080)
2570 else if (iptr->sx.val.l == 0x00000100)
2572 else if (iptr->sx.val.l == 0x00000200)
2574 else if (iptr->sx.val.l == 0x00000400)
2575 iptr->sx.val.i = 10;
2576 else if (iptr->sx.val.l == 0x00000800)
2577 iptr->sx.val.i = 11;
2578 else if (iptr->sx.val.l == 0x00001000)
2579 iptr->sx.val.i = 12;
2580 else if (iptr->sx.val.l == 0x00002000)
2581 iptr->sx.val.i = 13;
2582 else if (iptr->sx.val.l == 0x00004000)
2583 iptr->sx.val.i = 14;
2584 else if (iptr->sx.val.l == 0x00008000)
2585 iptr->sx.val.i = 15;
2586 else if (iptr->sx.val.l == 0x00010000)
2587 iptr->sx.val.i = 16;
2588 else if (iptr->sx.val.l == 0x00020000)
2589 iptr->sx.val.i = 17;
2590 else if (iptr->sx.val.l == 0x00040000)
2591 iptr->sx.val.i = 18;
2592 else if (iptr->sx.val.l == 0x00080000)
2593 iptr->sx.val.i = 19;
2594 else if (iptr->sx.val.l == 0x00100000)
2595 iptr->sx.val.i = 20;
2596 else if (iptr->sx.val.l == 0x00200000)
2597 iptr->sx.val.i = 21;
2598 else if (iptr->sx.val.l == 0x00400000)
2599 iptr->sx.val.i = 22;
2600 else if (iptr->sx.val.l == 0x00800000)
2601 iptr->sx.val.i = 23;
2602 else if (iptr->sx.val.l == 0x01000000)
2603 iptr->sx.val.i = 24;
2604 else if (iptr->sx.val.l == 0x02000000)
2605 iptr->sx.val.i = 25;
2606 else if (iptr->sx.val.l == 0x04000000)
2607 iptr->sx.val.i = 26;
2608 else if (iptr->sx.val.l == 0x08000000)
2609 iptr->sx.val.i = 27;
2610 else if (iptr->sx.val.l == 0x10000000)
2611 iptr->sx.val.i = 28;
2612 else if (iptr->sx.val.l == 0x20000000)
2613 iptr->sx.val.i = 29;
2614 else if (iptr->sx.val.l == 0x40000000)
2615 iptr->sx.val.i = 30;
2616 else if (iptr->sx.val.l == 0x80000000)
2617 iptr->sx.val.i = 31;
2621 iptr->opc = ICMD_LDIVPOW2;
2622 goto icmd_lconst_tail;
2623 #endif /* SUPPORT_LONG_DIV_POW2 */
2625 #if SUPPORT_LONG_REM_POW2
2627 if ((iptr->sx.val.l == 0x00000002) ||
2628 (iptr->sx.val.l == 0x00000004) ||
2629 (iptr->sx.val.l == 0x00000008) ||
2630 (iptr->sx.val.l == 0x00000010) ||
2631 (iptr->sx.val.l == 0x00000020) ||
2632 (iptr->sx.val.l == 0x00000040) ||
2633 (iptr->sx.val.l == 0x00000080) ||
2634 (iptr->sx.val.l == 0x00000100) ||
2635 (iptr->sx.val.l == 0x00000200) ||
2636 (iptr->sx.val.l == 0x00000400) ||
2637 (iptr->sx.val.l == 0x00000800) ||
2638 (iptr->sx.val.l == 0x00001000) ||
2639 (iptr->sx.val.l == 0x00002000) ||
2640 (iptr->sx.val.l == 0x00004000) ||
2641 (iptr->sx.val.l == 0x00008000) ||
2642 (iptr->sx.val.l == 0x00010000) ||
2643 (iptr->sx.val.l == 0x00020000) ||
2644 (iptr->sx.val.l == 0x00040000) ||
2645 (iptr->sx.val.l == 0x00080000) ||
2646 (iptr->sx.val.l == 0x00100000) ||
2647 (iptr->sx.val.l == 0x00200000) ||
2648 (iptr->sx.val.l == 0x00400000) ||
2649 (iptr->sx.val.l == 0x00800000) ||
2650 (iptr->sx.val.l == 0x01000000) ||
2651 (iptr->sx.val.l == 0x02000000) ||
2652 (iptr->sx.val.l == 0x04000000) ||
2653 (iptr->sx.val.l == 0x08000000) ||
2654 (iptr->sx.val.l == 0x10000000) ||
2655 (iptr->sx.val.l == 0x20000000) ||
2656 (iptr->sx.val.l == 0x40000000) ||
2657 (iptr->sx.val.l == 0x80000000))
2659 iptr->opc = ICMD_LREMPOW2;
2660 iptr->sx.val.l -= 1;
2661 goto icmd_lconst_tail;
2664 #endif /* SUPPORT_LONG_REM_POW2 */
2666 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2669 iptr->opc = ICMD_LANDCONST;
2670 goto icmd_lconst_tail;
2673 iptr->opc = ICMD_LORCONST;
2674 goto icmd_lconst_tail;
2677 iptr->opc = ICMD_LXORCONST;
2678 goto icmd_lconst_tail;
2679 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2681 #if SUPPORT_LONG_CMP_CONST
2683 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2686 /* switch on the instruction after LCONST - LCMP */
2688 switch (iptr[2].opc) {
2690 iptr->opc = ICMD_IF_LEQ;
2693 icmd_lconst_lcmp_tail:
2694 /* convert LCONST, LCMP, IFXX to IF_LXX */
2695 iptr->dst.insindex = iptr[2].dst.insindex;
2696 iptr[1].opc = ICMD_NOP;
2697 iptr[2].opc = ICMD_NOP;
2699 OP1_BRANCH(TYPE_LNG);
2700 BRANCH(tbptr, copy);
2701 COUNT(count_pcmd_bra);
2702 COUNT(count_pcmd_op);
2706 iptr->opc = ICMD_IF_LNE;
2707 goto icmd_lconst_lcmp_tail;
2710 iptr->opc = ICMD_IF_LLT;
2711 goto icmd_lconst_lcmp_tail;
2714 iptr->opc = ICMD_IF_LGT;
2715 goto icmd_lconst_lcmp_tail;
2718 iptr->opc = ICMD_IF_LLE;
2719 goto icmd_lconst_lcmp_tail;
2722 iptr->opc = ICMD_IF_LGE;
2723 goto icmd_lconst_lcmp_tail;
2727 } /* end switch on opcode after LCONST - LCMP */
2729 #endif /* SUPPORT_LONG_CMP_CONST */
2731 #if SUPPORT_CONST_STORE
2733 IF_INTRP( goto normal_LCONST; )
2734 # if SUPPORT_CONST_STORE_ZERO_ONLY
2735 if (iptr->sx.val.l != 0)
2738 #if SIZEOF_VOID_P == 4
2739 /* the constant must fit into a ptrint */
2740 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2743 /* move the constant to s3 */
2744 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2746 iptr->opc = ICMD_LASTORECONST;
2747 iptr->flags.bits |= INS_FLAG_CHECK;
2748 OP2_0(TYPE_ADR, TYPE_INT);
2750 iptr[1].opc = ICMD_NOP;
2751 COUNT(count_pcmd_op);
2754 case ICMD_PUTSTATIC:
2756 IF_INTRP( goto normal_LCONST; )
2757 # if SUPPORT_CONST_STORE_ZERO_ONLY
2758 if (iptr->sx.val.l != 0)
2761 #if SIZEOF_VOID_P == 4
2762 /* the constant must fit into a ptrint */
2763 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2766 /* XXX check field type? */
2768 /* copy the constant to s2 */
2769 /* XXX constval -> fieldconstval? */
2770 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2774 #endif /* SUPPORT_CONST_STORE */
2778 } /* end switch opcode after LCONST */
2780 /* if we get here, the LCONST has been optimized */
2784 /* the normal case of an unoptimized LCONST */
2788 /************************ END OF LCONST OPTIMIZATIONS *********************/
2791 COUNT(count_pcmd_load);
2796 COUNT(count_pcmd_load);
2800 /************************** ACONST OPTIMIZATIONS **************************/
2803 coalescing_boundary = sd.new;
2804 COUNT(count_pcmd_load);
2805 #if SUPPORT_CONST_STORE
2806 IF_INTRP( goto normal_ACONST; )
2808 /* We can only optimize if the ACONST is resolved
2809 * and there is an instruction after it. */
2811 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2814 switch (iptr[1].opc) {
2816 /* We can only optimize for NULL values
2817 * here because otherwise a checkcast is
2819 if (iptr->sx.val.anyptr != NULL)
2822 /* copy the constant (NULL) to s3 */
2823 iptr->sx.s23.s3.constval = 0;
2824 iptr->opc = ICMD_AASTORECONST;
2825 iptr->flags.bits |= INS_FLAG_CHECK;
2826 OP2_0(TYPE_ADR, TYPE_INT);
2828 iptr[1].opc = ICMD_NOP;
2829 COUNT(count_pcmd_op);
2832 case ICMD_PUTSTATIC:
2834 # if SUPPORT_CONST_STORE_ZERO_ONLY
2835 if (iptr->sx.val.anyptr != NULL)
2838 /* XXX check field type? */
2839 /* copy the constant to s2 */
2840 /* XXX constval -> fieldconstval? */
2841 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2849 /* if we get here the ACONST has been optimized */
2853 #endif /* SUPPORT_CONST_STORE */
2858 /* pop 0 push 1 load */
2865 COUNT(count_load_instruction);
2866 i = opcode - ICMD_ILOAD; /* type */
2868 j = iptr->s1.varindex =
2869 jd->local_map[iptr->s1.varindex * 5 + i];
2871 if (sd.var[j].type == TYPE_RET) {
2872 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
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, opcode - ICMD_IALOAD);
2897 coalescing_boundary = sd.new;
2898 iptr->flags.bits |= INS_FLAG_CHECK;
2899 COUNT(count_check_null);
2900 COUNT(count_check_bound);
2901 COUNT(count_pcmd_mem);
2902 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2905 /* pop 0 push 0 iinc */
2908 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2910 last_store_boundary[iptr->s1.varindex] = sd.new;
2913 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2918 if ((copy->varkind == LOCALVAR) &&
2919 (copy->varnum == iptr->s1.varindex))
2921 assert(IS_LOCALVAR(copy));
2928 iptr->dst.varindex = iptr->s1.varindex;
2931 /* pop 1 push 0 store */
2940 i = opcode - ICMD_ISTORE; /* type */
2941 javaindex = iptr->dst.varindex;
2942 j = iptr->dst.varindex =
2943 jd->local_map[javaindex * 5 + i];
2945 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2947 #if defined(ENABLE_STATISTICS)
2950 i = sd.new - curstack;
2952 count_store_length[20]++;
2954 count_store_length[i]++;
2957 count_store_depth[10]++;
2959 count_store_depth[i]++;
2962 /* check for conflicts as described in Figure 5.2 */
2964 copy = curstack->prev;
2967 if ((copy->varkind == LOCALVAR) &&
2968 (copy->varnum == j))
2970 copy->varkind = TEMPVAR;
2971 assert(IS_LOCALVAR(copy));
2978 /* if the variable is already coalesced, don't bother */
2980 if (IS_OUTVAR(curstack)
2981 || (curstack->varkind == LOCALVAR
2982 && curstack->varnum != j))
2985 /* there is no STORE Lj while curstack is live */
2987 if (curstack < last_store_boundary[javaindex])
2988 goto assume_conflict;
2990 /* curstack must be after the coalescing boundary */
2992 if (curstack < coalescing_boundary)
2993 goto assume_conflict;
2995 /* there is no DEF LOCALVAR(j) while curstack is live */
2997 copy = sd.new; /* most recent stackslot created + 1 */
2998 while (--copy > curstack) {
2999 if (copy->varkind == LOCALVAR && copy->varnum == j)
3000 goto assume_conflict;
3003 /* coalesce the temporary variable with Lj */
3004 assert((curstack->varkind == TEMPVAR)
3005 || (curstack->varkind == UNDEFVAR));
3006 assert(!IS_LOCALVAR(curstack));
3007 assert(!IS_OUTVAR(curstack));
3008 assert(!IS_PREALLOC(curstack));
3010 assert(curstack->creator);
3011 assert(curstack->creator->dst.varindex == curstack->varnum);
3012 RELEASE_INDEX(sd, curstack);
3013 curstack->varkind = LOCALVAR;
3014 curstack->varnum = j;
3015 curstack->creator->dst.varindex = j;
3018 /* revert the coalescing, if it has been done earlier */
3020 if ((curstack->varkind == LOCALVAR)
3021 && (curstack->varnum == j))
3023 assert(IS_LOCALVAR(curstack));
3024 SET_TEMPVAR(curstack);
3027 /* remember the stack boundary at this store */
3029 last_store_boundary[javaindex] = sd.new;
3031 STORE(opcode - ICMD_ISTORE, j);
3037 coalescing_boundary = sd.new;
3038 iptr->flags.bits |= INS_FLAG_CHECK;
3039 COUNT(count_check_null);
3040 COUNT(count_check_bound);
3041 COUNT(count_pcmd_mem);
3043 bte = builtintable_get_internal(BUILTIN_canstore);
3046 if (md->memuse > rd->memuse)
3047 rd->memuse = md->memuse;
3048 if (md->argintreguse > rd->argintreguse)
3049 rd->argintreguse = md->argintreguse;
3050 /* XXX non-leaf method? */
3052 /* make all stack variables saved */
3056 sd.var[copy->varnum].flags |= SAVEDVAR;
3057 /* in case copy->varnum is/will be a LOCALVAR */
3058 /* once and set back to a non LOCALVAR */
3059 /* the correct SAVEDVAR flag has to be */
3060 /* remembered in copy->flags, too */
3061 copy->flags |= SAVEDVAR;
3065 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3072 coalescing_boundary = sd.new;
3073 iptr->flags.bits |= INS_FLAG_CHECK;
3074 COUNT(count_check_null);
3075 COUNT(count_check_bound);
3076 COUNT(count_pcmd_mem);
3077 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3084 coalescing_boundary = sd.new;
3085 iptr->flags.bits |= INS_FLAG_CHECK;
3086 COUNT(count_check_null);
3087 COUNT(count_check_bound);
3088 COUNT(count_pcmd_mem);
3089 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3095 #ifdef ENABLE_VERIFIER
3098 if (IS_2_WORD_TYPE(curstack->type))
3099 goto throw_stack_category_error;
3110 coalescing_boundary = sd.new;
3111 IF_JIT( md_return_alloc(jd, curstack); )
3112 COUNT(count_pcmd_return);
3113 OP1_0(opcode - ICMD_IRETURN);
3114 superblockend = true;
3118 coalescing_boundary = sd.new;
3119 COUNT(count_check_null);
3121 curstack = NULL; stackdepth = 0;
3122 superblockend = true;
3125 case ICMD_PUTSTATIC:
3126 coalescing_boundary = sd.new;
3127 COUNT(count_pcmd_mem);
3128 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3129 OP1_0(fmiref->parseddesc.fd->type);
3132 /* pop 1 push 0 branch */
3135 case ICMD_IFNONNULL:
3136 COUNT(count_pcmd_bra);
3137 OP1_BRANCH(TYPE_ADR);
3138 BRANCH(tbptr, copy);
3147 COUNT(count_pcmd_bra);
3148 /* iptr->sx.val.i is set implicitly in parse by
3149 clearing the memory or from IF_ICMPxx
3152 OP1_BRANCH(TYPE_INT);
3153 /* iptr->sx.val.i = 0; */
3154 BRANCH(tbptr, copy);
3157 /* pop 0 push 0 branch */
3160 COUNT(count_pcmd_bra);
3162 BRANCH(tbptr, copy);
3163 superblockend = true;
3166 /* pop 1 push 0 table branch */
3168 case ICMD_TABLESWITCH:
3169 COUNT(count_pcmd_table);
3170 OP1_BRANCH(TYPE_INT);
3172 table = iptr->dst.table;
3173 BRANCH_TARGET(*table, tbptr, copy);
3176 i = iptr->sx.s23.s3.tablehigh
3177 - iptr->sx.s23.s2.tablelow + 1;
3180 BRANCH_TARGET(*table, tbptr, copy);
3183 superblockend = true;
3186 /* pop 1 push 0 table branch */
3188 case ICMD_LOOKUPSWITCH:
3189 COUNT(count_pcmd_table);
3190 OP1_BRANCH(TYPE_INT);
3192 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr, copy);
3194 lookup = iptr->dst.lookup;
3196 i = iptr->sx.s23.s2.lookupcount;
3199 BRANCH_TARGET(lookup->target, tbptr, copy);
3202 superblockend = true;
3205 case ICMD_MONITORENTER:
3206 case ICMD_MONITOREXIT:
3207 coalescing_boundary = sd.new;
3208 COUNT(count_check_null);
3212 /* pop 2 push 0 branch */
3214 case ICMD_IF_ICMPEQ:
3215 case ICMD_IF_ICMPNE:
3216 case ICMD_IF_ICMPLT:
3217 case ICMD_IF_ICMPGE:
3218 case ICMD_IF_ICMPGT:
3219 case ICMD_IF_ICMPLE:
3220 COUNT(count_pcmd_bra);
3221 OP2_BRANCH(TYPE_INT, TYPE_INT);
3222 BRANCH(tbptr, copy);
3225 case ICMD_IF_ACMPEQ:
3226 case ICMD_IF_ACMPNE:
3227 COUNT(count_pcmd_bra);
3228 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3229 BRANCH(tbptr, copy);
3235 coalescing_boundary = sd.new;
3236 COUNT(count_check_null);
3237 COUNT(count_pcmd_mem);
3238 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3239 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3244 if (!IS_2_WORD_TYPE(curstack->type)) {
3246 #ifdef ENABLE_VERIFIER
3249 if (IS_2_WORD_TYPE(curstack->prev->type))
3250 goto throw_stack_category_error;
3253 OP2_0_ANY_ANY; /* pop two slots */
3256 iptr->opc = ICMD_POP;
3257 OP1_0_ANY; /* pop one (two-word) slot */
3261 /* pop 0 push 1 dup */
3264 #ifdef ENABLE_VERIFIER
3267 if (IS_2_WORD_TYPE(curstack->type))
3268 goto throw_stack_category_error;
3271 COUNT(count_dup_instruction);
3277 coalescing_boundary = sd.new - 1;
3282 if (IS_2_WORD_TYPE(curstack->type)) {
3284 iptr->opc = ICMD_DUP;
3289 /* ..., ????, cat1 */
3290 #ifdef ENABLE_VERIFIER
3292 if (IS_2_WORD_TYPE(curstack->prev->type))
3293 goto throw_stack_category_error;
3296 src1 = curstack->prev;
3299 COPY_UP(src1); iptr++; len--;
3302 coalescing_boundary = sd.new;
3306 /* pop 2 push 3 dup */
3309 #ifdef ENABLE_VERIFIER
3312 if (IS_2_WORD_TYPE(curstack->type) ||
3313 IS_2_WORD_TYPE(curstack->prev->type))
3314 goto throw_stack_category_error;
3319 src1 = curstack->prev;
3324 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3326 MOVE_UP(src1); iptr++; len--;
3327 MOVE_UP(src2); iptr++; len--;
3329 COPY_DOWN(curstack, dst1);
3331 coalescing_boundary = sd.new;
3336 if (IS_2_WORD_TYPE(curstack->type)) {
3337 /* ..., ????, cat2 */
3338 #ifdef ENABLE_VERIFIER
3340 if (IS_2_WORD_TYPE(curstack->prev->type))
3341 goto throw_stack_category_error;
3344 iptr->opc = ICMD_DUP_X1;
3348 /* ..., ????, cat1 */
3349 #ifdef ENABLE_VERIFIER
3352 if (IS_2_WORD_TYPE(curstack->prev->type)
3353 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3354 goto throw_stack_category_error;
3359 src1 = curstack->prev->prev;
3360 src2 = curstack->prev;
3362 POPANY; POPANY; POPANY;
3365 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3366 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3368 MOVE_UP(src1); iptr++; len--;
3369 MOVE_UP(src2); iptr++; len--;
3370 MOVE_UP(src3); iptr++; len--;
3372 COPY_DOWN(curstack, dst2); iptr++; len--;
3373 COPY_DOWN(curstack->prev, dst1);
3375 coalescing_boundary = sd.new;
3379 /* pop 3 push 4 dup */
3383 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3384 /* ..., cat2, ???? */
3385 #ifdef ENABLE_VERIFIER
3387 if (IS_2_WORD_TYPE(curstack->type))
3388 goto throw_stack_category_error;
3391 iptr->opc = ICMD_DUP_X1;
3395 /* ..., cat1, ???? */
3396 #ifdef ENABLE_VERIFIER
3399 if (IS_2_WORD_TYPE(curstack->type)
3400 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3401 goto throw_stack_category_error;
3405 src1 = curstack->prev->prev;
3406 src2 = curstack->prev;
3408 POPANY; POPANY; POPANY;
3411 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3413 MOVE_UP(src1); iptr++; len--;
3414 MOVE_UP(src2); iptr++; len--;
3415 MOVE_UP(src3); iptr++; len--;
3417 COPY_DOWN(curstack, dst1);
3419 coalescing_boundary = sd.new;
3425 if (IS_2_WORD_TYPE(curstack->type)) {
3426 /* ..., ????, cat2 */
3427 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3428 /* ..., cat2, cat2 */
3429 iptr->opc = ICMD_DUP_X1;
3433 /* ..., cat1, cat2 */
3434 #ifdef ENABLE_VERIFIER
3437 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3438 goto throw_stack_category_error;
3441 iptr->opc = ICMD_DUP_X2;
3447 /* ..., ????, ????, cat1 */
3449 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3450 /* ..., cat2, ????, cat1 */
3451 #ifdef ENABLE_VERIFIER
3453 if (IS_2_WORD_TYPE(curstack->prev->type))
3454 goto throw_stack_category_error;
3457 iptr->opc = ICMD_DUP2_X1;
3461 /* ..., cat1, ????, cat1 */
3462 #ifdef ENABLE_VERIFIER
3465 if (IS_2_WORD_TYPE(curstack->prev->type)
3466 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3467 goto throw_stack_category_error;
3471 src1 = curstack->prev->prev->prev;
3472 src2 = curstack->prev->prev;
3473 src3 = curstack->prev;
3475 POPANY; POPANY; POPANY; POPANY;
3478 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3479 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3481 MOVE_UP(src1); iptr++; len--;
3482 MOVE_UP(src2); iptr++; len--;
3483 MOVE_UP(src3); iptr++; len--;
3484 MOVE_UP(src4); iptr++; len--;
3486 COPY_DOWN(curstack, dst2); iptr++; len--;
3487 COPY_DOWN(curstack->prev, dst1);
3489 coalescing_boundary = sd.new;
3493 /* pop 2 push 2 swap */
3496 #ifdef ENABLE_VERIFIER
3499 if (IS_2_WORD_TYPE(curstack->type)
3500 || IS_2_WORD_TYPE(curstack->prev->type))
3501 goto throw_stack_category_error;
3505 src1 = curstack->prev;
3510 MOVE_UP(src2); iptr++; len--;
3513 coalescing_boundary = sd.new;
3520 coalescing_boundary = sd.new;
3521 #if !SUPPORT_DIVISION
3522 bte = iptr->sx.s23.s3.bte;
3525 if (md->memuse > rd->memuse)
3526 rd->memuse = md->memuse;
3527 if (md->argintreguse > rd->argintreguse)
3528 rd->argintreguse = md->argintreguse;
3530 /* make all stack variables saved */
3534 sd.var[copy->varnum].flags |= SAVEDVAR;
3535 copy->flags |= SAVEDVAR;
3540 #endif /* !SUPPORT_DIVISION */
3551 COUNT(count_pcmd_op);
3552 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3557 coalescing_boundary = sd.new;
3558 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3559 bte = iptr->sx.s23.s3.bte;
3562 if (md->memuse > rd->memuse)
3563 rd->memuse = md->memuse;
3564 if (md->argintreguse > rd->argintreguse)
3565 rd->argintreguse = md->argintreguse;
3566 /* XXX non-leaf method? */
3568 /* make all stack variables saved */
3572 sd.var[copy->varnum].flags |= SAVEDVAR;
3573 copy->flags |= SAVEDVAR;
3578 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3583 #if SUPPORT_LONG_LOGICAL
3587 #endif /* SUPPORT_LONG_LOGICAL */
3588 COUNT(count_pcmd_op);
3589 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3595 COUNT(count_pcmd_op);
3596 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3604 COUNT(count_pcmd_op);
3605 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3613 COUNT(count_pcmd_op);
3614 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3618 COUNT(count_pcmd_op);
3619 #if SUPPORT_LONG_CMP_CONST
3620 if ((len == 0) || (iptr[1].sx.val.i != 0))
3623 switch (iptr[1].opc) {
3625 iptr->opc = ICMD_IF_LCMPEQ;
3627 iptr->dst.insindex = iptr[1].dst.insindex;
3628 iptr[1].opc = ICMD_NOP;
3630 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3631 BRANCH(tbptr, copy);
3633 COUNT(count_pcmd_bra);
3636 iptr->opc = ICMD_IF_LCMPNE;
3637 goto icmd_lcmp_if_tail;
3639 iptr->opc = ICMD_IF_LCMPLT;
3640 goto icmd_lcmp_if_tail;
3642 iptr->opc = ICMD_IF_LCMPGT;
3643 goto icmd_lcmp_if_tail;
3645 iptr->opc = ICMD_IF_LCMPLE;
3646 goto icmd_lcmp_if_tail;
3648 iptr->opc = ICMD_IF_LCMPGE;
3649 goto icmd_lcmp_if_tail;
3655 #endif /* SUPPORT_LONG_CMP_CONST */
3656 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3659 /* XXX why is this deactivated? */
3662 COUNT(count_pcmd_op);
3663 if ((len == 0) || (iptr[1].sx.val.i != 0))
3666 switch (iptr[1].opc) {
3668 iptr->opc = ICMD_IF_FCMPEQ;
3670 iptr->dst.insindex = iptr[1].dst.insindex;
3671 iptr[1].opc = ICMD_NOP;
3673 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3674 BRANCH(tbptr, copy);
3676 COUNT(count_pcmd_bra);
3679 iptr->opc = ICMD_IF_FCMPNE;
3680 goto icmd_if_fcmpl_tail;
3682 iptr->opc = ICMD_IF_FCMPL_LT;
3683 goto icmd_if_fcmpl_tail;
3685 iptr->opc = ICMD_IF_FCMPL_GT;
3686 goto icmd_if_fcmpl_tail;
3688 iptr->opc = ICMD_IF_FCMPL_LE;
3689 goto icmd_if_fcmpl_tail;
3691 iptr->opc = ICMD_IF_FCMPL_GE;
3692 goto icmd_if_fcmpl_tail;
3699 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3703 COUNT(count_pcmd_op);
3704 if ((len == 0) || (iptr[1].sx.val.i != 0))
3707 switch (iptr[1].opc) {
3709 iptr->opc = ICMD_IF_FCMPEQ;
3711 iptr->dst.insindex = iptr[1].dst.insindex;
3712 iptr[1].opc = ICMD_NOP;
3714 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3715 BRANCH(tbptr, copy);
3717 COUNT(count_pcmd_bra);
3720 iptr->opc = ICMD_IF_FCMPNE;
3721 goto icmd_if_fcmpg_tail;
3723 iptr->opc = ICMD_IF_FCMPG_LT;
3724 goto icmd_if_fcmpg_tail;
3726 iptr->opc = ICMD_IF_FCMPG_GT;
3727 goto icmd_if_fcmpg_tail;
3729 iptr->opc = ICMD_IF_FCMPG_LE;
3730 goto icmd_if_fcmpg_tail;
3732 iptr->opc = ICMD_IF_FCMPG_GE;
3733 goto icmd_if_fcmpg_tail;
3740 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3744 COUNT(count_pcmd_op);
3745 if ((len == 0) || (iptr[1].sx.val.i != 0))
3748 switch (iptr[1].opc) {
3750 iptr->opc = ICMD_IF_DCMPEQ;
3752 iptr->dst.insindex = iptr[1].dst.insindex;
3753 iptr[1].opc = ICMD_NOP;
3755 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3756 BRANCH(tbptr, copy);
3758 COUNT(count_pcmd_bra);
3761 iptr->opc = ICMD_IF_DCMPNE;
3762 goto icmd_if_dcmpl_tail;
3764 iptr->opc = ICMD_IF_DCMPL_LT;
3765 goto icmd_if_dcmpl_tail;
3767 iptr->opc = ICMD_IF_DCMPL_GT;
3768 goto icmd_if_dcmpl_tail;
3770 iptr->opc = ICMD_IF_DCMPL_LE;
3771 goto icmd_if_dcmpl_tail;
3773 iptr->opc = ICMD_IF_DCMPL_GE;
3774 goto icmd_if_dcmpl_tail;
3781 OPTT2_1(TYPE_DBL, TYPE_INT);
3785 COUNT(count_pcmd_op);
3786 if ((len == 0) || (iptr[1].sx.val.i != 0))
3789 switch (iptr[1].opc) {
3791 iptr->opc = ICMD_IF_DCMPEQ;
3793 iptr->dst.insindex = iptr[1].dst.insindex;
3794 iptr[1].opc = ICMD_NOP;
3796 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3797 BRANCH(tbptr, copy);
3799 COUNT(count_pcmd_bra);
3802 iptr->opc = ICMD_IF_DCMPNE;
3803 goto icmd_if_dcmpg_tail;
3805 iptr->opc = ICMD_IF_DCMPG_LT;
3806 goto icmd_if_dcmpg_tail;
3808 iptr->opc = ICMD_IF_DCMPG_GT;
3809 goto icmd_if_dcmpg_tail;
3811 iptr->opc = ICMD_IF_DCMPG_LE;
3812 goto icmd_if_dcmpg_tail;
3814 iptr->opc = ICMD_IF_DCMPG_GE;
3815 goto icmd_if_dcmpg_tail;
3822 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3827 COUNT(count_pcmd_op);
3828 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3833 COUNT(count_pcmd_op);
3834 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3843 case ICMD_INT2SHORT:
3844 COUNT(count_pcmd_op);
3845 OP1_1(TYPE_INT, TYPE_INT);
3848 COUNT(count_pcmd_op);
3849 OP1_1(TYPE_LNG, TYPE_LNG);
3852 COUNT(count_pcmd_op);
3853 OP1_1(TYPE_FLT, TYPE_FLT);
3856 COUNT(count_pcmd_op);
3857 OP1_1(TYPE_DBL, TYPE_DBL);
3861 COUNT(count_pcmd_op);
3862 OP1_1(TYPE_INT, TYPE_LNG);
3865 COUNT(count_pcmd_op);
3866 OP1_1(TYPE_INT, TYPE_FLT);
3869 COUNT(count_pcmd_op);
3870 OP1_1(TYPE_INT, TYPE_DBL);
3873 COUNT(count_pcmd_op);
3874 OP1_1(TYPE_LNG, TYPE_INT);
3877 COUNT(count_pcmd_op);
3878 OP1_1(TYPE_LNG, TYPE_FLT);
3881 COUNT(count_pcmd_op);
3882 OP1_1(TYPE_LNG, TYPE_DBL);
3885 COUNT(count_pcmd_op);
3886 OP1_1(TYPE_FLT, TYPE_INT);
3889 COUNT(count_pcmd_op);
3890 OP1_1(TYPE_FLT, TYPE_LNG);
3893 COUNT(count_pcmd_op);
3894 OP1_1(TYPE_FLT, TYPE_DBL);
3897 COUNT(count_pcmd_op);
3898 OP1_1(TYPE_DBL, TYPE_INT);
3901 COUNT(count_pcmd_op);
3902 OP1_1(TYPE_DBL, TYPE_LNG);
3905 COUNT(count_pcmd_op);
3906 OP1_1(TYPE_DBL, TYPE_FLT);
3909 case ICMD_CHECKCAST:
3910 coalescing_boundary = sd.new;
3911 if (iptr->flags.bits & INS_FLAG_ARRAY) {
3912 /* array type cast-check */
3914 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
3917 if (md->memuse > rd->memuse)
3918 rd->memuse = md->memuse;
3919 if (md->argintreguse > rd->argintreguse)
3920 rd->argintreguse = md->argintreguse;
3922 /* make all stack variables saved */
3926 sd.var[copy->varnum].flags |= SAVEDVAR;
3927 copy->flags |= SAVEDVAR;
3931 OP1_1(TYPE_ADR, TYPE_ADR);
3934 case ICMD_INSTANCEOF:
3935 case ICMD_ARRAYLENGTH:
3936 coalescing_boundary = sd.new;
3937 OP1_1(TYPE_ADR, TYPE_INT);
3941 case ICMD_ANEWARRAY:
3942 coalescing_boundary = sd.new;
3943 OP1_1(TYPE_INT, TYPE_ADR);
3947 coalescing_boundary = sd.new;
3948 COUNT(count_check_null);
3949 COUNT(count_pcmd_mem);
3950 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3951 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
3956 case ICMD_GETSTATIC:
3957 coalescing_boundary = sd.new;
3958 COUNT(count_pcmd_mem);
3959 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3960 OP0_1(fmiref->parseddesc.fd->type);
3964 coalescing_boundary = sd.new;
3971 assert(sd.bptr->next); /* XXX exception */
3972 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
3974 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
3975 tbptr->type = BBTYPE_SBR;
3977 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
3981 iptr->sx.s23.s3.jsrtarget.block = tbptr;
3983 /* We need to check for overflow right here because
3984 * the pushed value is poped afterwards */
3987 superblockend = true;
3988 /* XXX should not be marked as interface, as it does not need to be */
3989 /* allocated. Same for the invar of the target. */
3992 /* pop many push any */
3996 bte = iptr->sx.s23.s3.bte;
4000 case ICMD_INVOKESTATIC:
4001 case ICMD_INVOKESPECIAL:
4002 case ICMD_INVOKEVIRTUAL:
4003 case ICMD_INVOKEINTERFACE:
4004 COUNT(count_pcmd_met);
4006 /* Check for functions to replace with builtin
4009 if (builtintable_replace_function(iptr))
4012 INSTRUCTION_GET_METHODDESC(iptr, md);
4013 /* XXX resurrect this COUNT? */
4014 /* if (lm->flags & ACC_STATIC) */
4015 /* {COUNT(count_check_null);} */
4019 coalescing_boundary = sd.new;
4023 if (md->memuse > rd->memuse)
4024 rd->memuse = md->memuse;
4025 if (md->argintreguse > rd->argintreguse)
4026 rd->argintreguse = md->argintreguse;
4027 if (md->argfltreguse > rd->argfltreguse)
4028 rd->argfltreguse = md->argfltreguse;
4032 /* XXX optimize for <= 2 args */
4033 /* XXX not for ICMD_BUILTIN */
4034 iptr->s1.argcount = stackdepth;
4035 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4038 for (i-- ; i >= 0; i--) {
4039 iptr->sx.s23.s2.args[i] = copy->varnum;
4041 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4042 /* -> won't help anyway */
4043 if (!(IS_OUTVAR(copy) || IS_LOCALVAR(copy))) {
4045 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4046 /* If we pass float arguments in integer argument registers, we
4047 * are not allowed to precolor them here. Floats have to be moved
4048 * to this regs explicitly in codegen().
4049 * Only arguments that are passed by stack anyway can be precolored
4050 * (michi 2005/07/24) */
4051 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4052 (!IS_FLT_DBL_TYPE(copy->type)
4053 || md->params[i].inmemory)) {
4055 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4060 #if defined(ENABLE_INTRP)
4063 if (md->params[i].inmemory) {
4064 sd.var[copy->varnum].vv.regoff =
4065 md->params[i].regoff;
4066 sd.var[copy->varnum].flags |=
4070 if (IS_FLT_DBL_TYPE(copy->type)) {
4071 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4072 assert(0); /* XXX is this assert ok? */
4074 sd.var[copy->varnum].vv.regoff =
4075 rd->argfltregs[md->params[i].regoff];
4076 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4079 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4080 if (IS_2_WORD_TYPE(copy->type))
4081 sd.var[copy->varnum].vv.regoff =
4082 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4083 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4086 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4087 sd.var[copy->varnum].vv.regoff =
4088 rd->argintregs[md->params[i].regoff];
4091 #if defined(ENABLE_INTRP)
4092 } /* end if (!opt_intrp) */
4099 /* deal with live-through stack slots "under" the */
4101 /* XXX not for ICMD_BUILTIN */
4107 iptr->sx.s23.s2.args[i++] = copy->varnum;
4108 sd.var[copy->varnum].flags |= SAVEDVAR;
4112 /* pop the arguments */
4121 /* push the return value */
4123 if (md->returntype.type != TYPE_VOID) {
4124 GET_NEW_VAR(sd, new_index, md->returntype.type);
4125 DST(md->returntype.type, new_index);
4130 case ICMD_INLINE_START:
4131 case ICMD_INLINE_END:
4136 case ICMD_MULTIANEWARRAY:
4137 coalescing_boundary = sd.new;
4138 if (rd->argintreguse < 3)
4139 rd->argintreguse = 3;
4141 i = iptr->s1.argcount;
4145 iptr->sx.s23.s2.args = DMNEW(s4, i);
4147 #if defined(SPECIALMEMUSE)
4148 # if defined(__DARWIN__)
4149 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4150 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4152 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4153 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4156 # if defined(__I386__)
4157 if (rd->memuse < i + 3)
4158 rd->memuse = i + 3; /* n integer args spilled on stack */
4159 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4160 if (rd->memuse < i + 2)
4161 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4164 rd->memuse = i; /* n integer args spilled on stack */
4165 # endif /* defined(__I386__) */
4169 /* check INT type here? Currently typecheck does this. */
4170 iptr->sx.s23.s2.args[i] = copy->varnum;
4171 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4172 && (!IS_OUTVAR(copy))
4173 && (!IS_LOCALVAR(copy)) ) {
4174 copy->varkind = ARGVAR;
4175 sd.var[copy->varnum].flags |=
4176 INMEMORY & PREALLOC;
4177 #if defined(SPECIALMEMUSE)
4178 # if defined(__DARWIN__)
4179 sd.var[copy->varnum].vv.regoff = i +
4180 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4182 sd.var[copy->varnum].vv.regoff = i +
4183 LA_SIZE_IN_POINTERS + 3;
4186 # if defined(__I386__)
4187 sd.var[copy->varnum].vv.regoff = i + 3;
4188 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4189 sd.var[copy->varnum].vv.regoff = i + 2;
4191 sd.var[copy->varnum].vv.regoff = i;
4192 # endif /* defined(__I386__) */
4193 #endif /* defined(SPECIALMEMUSE) */
4198 sd.var[copy->varnum].flags |= SAVEDVAR;
4202 i = iptr->s1.argcount;
4207 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4208 DST(TYPE_ADR, new_index);
4214 new_internalerror("Unknown ICMD %d", opcode);
4220 } /* while instructions */
4222 /* stack slots at basic block end become interfaces */
4224 sd.bptr->outdepth = stackdepth;
4225 sd.bptr->outvars = DMNEW(s4, stackdepth);
4228 for (copy = curstack; copy; i--, copy = copy->prev) {
4232 /* with the new vars rd->interfaces will be removed */
4233 /* and all in and outvars have to be STACKVARS! */
4234 /* in the moment i.e. SWAP with in and out vars can */
4235 /* create an unresolvable conflict */
4242 v = sd.var + copy->varnum;
4245 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4246 /* no interface var until now for this depth and */
4248 jd->interface_map[i*5 + t].flags = v->flags;
4251 jd->interface_map[i*5 + t].flags |= v->flags;
4254 sd.bptr->outvars[i] = copy->varnum;
4257 /* check if interface slots at basic block begin must be saved */
4259 for (i=0; i<sd.bptr->indepth; ++i) {
4260 varinfo *v = sd.var + sd.bptr->invars[i];
4267 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4268 /* no interface var until now for this depth and */
4270 jd->interface_map[i*5 + t].flags = v->flags;
4273 jd->interface_map[i*5 + t].flags |= v->flags;
4278 /* store the number of this block's variables */
4280 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4282 #if defined(STACK_VERBOSE)
4283 stack_verbose_block_exit(&sd, superblockend);
4286 /* reach the following block, if any */
4289 if (!stack_reach_next_block(&sd))
4294 } while (sd.repeat && !deadcode);
4296 /* XXX reset TYPE_RET to TYPE_ADR */
4298 for (i=0; i<sd.vartop; ++i) {
4299 if (sd.var[i].type == TYPE_RET)
4300 sd.var[i].type = TYPE_ADR;
4303 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4305 ex = cd->exceptiontable;
4306 for (; ex != NULL; ex = ex->down) {
4307 if (ex->start == ex->end) {
4308 assert(ex->end->next);
4309 ex->end = ex->end->next;
4313 /* gather statistics *****************************************************/
4315 #if defined(ENABLE_STATISTICS)
4317 if (jd->new_basicblockcount > count_max_basic_blocks)
4318 count_max_basic_blocks = jd->new_basicblockcount;
4319 count_basic_blocks += jd->new_basicblockcount;
4320 if (jd->new_instructioncount > count_max_javainstr)
4321 count_max_javainstr = jd->new_instructioncount;
4322 count_javainstr += jd->new_instructioncount;
4323 if (jd->new_stackcount > count_upper_bound_new_stack)
4324 count_upper_bound_new_stack = jd->new_stackcount;
4325 if ((sd.new - jd->new_stack) > count_max_new_stack)
4326 count_max_new_stack = (sd.new - jd->new_stack);
4328 sd.bptr = jd->new_basicblocks;
4329 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4330 if (sd.bptr->flags > BBREACHED) {
4331 if (sd.bptr->indepth >= 10)
4332 count_block_stack[10]++;
4334 count_block_stack[sd.bptr->indepth]++;
4335 len = sd.bptr->icount;
4337 count_block_size_distribution[len]++;
4339 count_block_size_distribution[10]++;
4341 count_block_size_distribution[11]++;
4343 count_block_size_distribution[12]++;
4345 count_block_size_distribution[13]++;
4347 count_block_size_distribution[14]++;
4349 count_block_size_distribution[15]++;
4351 count_block_size_distribution[16]++;
4353 count_block_size_distribution[17]++;
4357 if (iteration_count == 1)
4358 count_analyse_iterations[0]++;
4359 else if (iteration_count == 2)
4360 count_analyse_iterations[1]++;
4361 else if (iteration_count == 3)
4362 count_analyse_iterations[2]++;
4363 else if (iteration_count == 4)
4364 count_analyse_iterations[3]++;
4366 count_analyse_iterations[4]++;
4368 if (jd->new_basicblockcount <= 5)
4369 count_method_bb_distribution[0]++;
4370 else if (jd->new_basicblockcount <= 10)
4371 count_method_bb_distribution[1]++;
4372 else if (jd->new_basicblockcount <= 15)
4373 count_method_bb_distribution[2]++;
4374 else if (jd->new_basicblockcount <= 20)
4375 count_method_bb_distribution[3]++;
4376 else if (jd->new_basicblockcount <= 30)
4377 count_method_bb_distribution[4]++;
4378 else if (jd->new_basicblockcount <= 40)
4379 count_method_bb_distribution[5]++;
4380 else if (jd->new_basicblockcount <= 50)
4381 count_method_bb_distribution[6]++;
4382 else if (jd->new_basicblockcount <= 75)
4383 count_method_bb_distribution[7]++;
4385 count_method_bb_distribution[8]++;
4387 #endif /* defined(ENABLE_STATISTICS) */
4389 /* everything's ok *******************************************************/
4393 /* goto labels for throwing verifier exceptions **************************/
4395 #if defined(ENABLE_VERIFIER)
4397 throw_stack_underflow:
4398 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4401 throw_stack_overflow:
4402 exceptions_throw_verifyerror(m, "Stack size too large");
4405 throw_stack_depth_error:
4406 exceptions_throw_verifyerror(m,"Stack depth mismatch");
4409 throw_stack_type_error:
4410 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4413 throw_stack_category_error:
4414 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4421 /* functions for verbose stack analysis output ********************************/
4423 #if defined(STACK_VERBOSE)
4424 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4426 printf("%c", show_jit_type_letters[v->type]);
4427 if (v->type == TYPE_RET)
4428 printf("{L%03d}", v->vv.retaddr->nr);
4432 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4434 assert(index >= 0 && index < sd->vartop);
4435 stack_verbose_show_varinfo(sd, sd->var + index);
4439 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4443 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4445 for (i=0; i<bptr->indepth; ++i) {
4448 stack_verbose_show_variable(sd, bptr->invars[i]);
4453 printf("] inlocals [");
4454 if (bptr->inlocals) {
4455 for (i=0; i<sd->localcount; ++i) {
4458 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4463 printf("] out:%d [", bptr->outdepth);
4464 if (bptr->outvars) {
4465 for (i=0; i<bptr->outdepth; ++i) {
4468 stack_verbose_show_variable(sd, bptr->outvars[i]);
4476 printf(" (clone of L%03d)", bptr->original->nr);
4478 basicblock *b = bptr->copied_to;
4480 printf(" (copied to ");
4481 for (; b; b = b->copied_to)
4482 printf("L%03d ", b->nr);
4489 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4493 printf("======================================== STACK %sANALYSE BLOCK ",
4494 (reanalyse) ? "RE-" : "");
4495 stack_verbose_show_block(sd, sd->bptr);
4498 if (sd->handlers[0]) {
4499 printf("HANDLERS: ");
4500 for (i=0; sd->handlers[i]; ++i) {
4501 printf("L%03d ", sd->handlers[i]->handler->nr);
4509 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4511 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4512 stack_verbose_show_block(sd, sd->bptr);
4519 * These are local overrides for various environment variables in Emacs.
4520 * Please do not remove this and leave it at the end of the file, where
4521 * Emacs will automagically detect them.
4522 * ---------------------------------------------------------------------
4525 * indent-tabs-mode: t
4529 * vim:noexpandtab:sw=4:ts=4: