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 5675 2006-10-04 19:38:28Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/show.h"
67 #if defined(ENABLE_DISASSEMBLER)
68 # include "vm/jit/disass.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/stack.h"
74 #if defined(ENABLE_SSA)
75 # include "vm/jit/optimizing/lsra.h"
76 # include "vm/jit/optimizing/ssa.h"
77 #elif defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
81 /*#define STACK_VERBOSE*/
84 /* macro for saving #ifdefs ***************************************************/
86 #if defined(ENABLE_STATISTICS)
87 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
90 if (stackdepth >= 10) \
91 count_store_depth[10]++; \
93 count_store_depth[stackdepth]++; \
96 #else /* !defined(ENABLE_STATISTICS) */
97 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
100 /* stackdata_t *****************************************************************
102 This struct holds internal data during stack analysis.
104 *******************************************************************************/
106 typedef struct stackdata_t stackdata_t;
109 basicblock *bptr; /* the current basic block being analysed */
110 stackptr new; /* next free stackelement */
111 s4 vartop; /* next free variable index */
112 s4 localcount; /* number of locals (at the start of var) */
113 s4 varcount; /* total number of variables allocated */
114 varinfo *var; /* variable array (same as jd->var) */
115 methodinfo *m; /* the method being analysed */
116 jitdata *jd; /* current jitdata */
117 basicblock *last_real_block; /* the last block before the empty one */
118 bool repeat; /* if true, iterate the analysis again */
119 exceptiontable **handlers; /* exception handlers for the current block */
120 exceptiontable *extableend; /* points to the last exception entry */
121 stackelement exstack; /* instack for exception handlers */
125 /* macros for allocating/releasing variable indices *****************/
127 #define GET_NEW_INDEX(sd, new_varindex) \
129 assert((sd).vartop < (sd).varcount); \
130 (new_varindex) = ((sd).vartop)++; \
133 /* Not implemented now - could be used to reuse varindices. */
134 /* Pay attention to not release a localvar once implementing it! */
135 #define RELEASE_INDEX(sd, varindex)
137 #define GET_NEW_VAR(sd, new_varindex, newtype) \
139 GET_NEW_INDEX((sd), (new_varindex)); \
140 (sd).var[new_index].type = (newtype); \
144 /* macros for querying variable properties **************************/
146 #define IS_INOUT(sp) \
147 (sd.var[(sp)->varnum].flags & INOUT)
149 #define IS_PREALLOC(sp) \
150 (sd.var[(sp)->varnum].flags & PREALLOC)
152 #define IS_TEMPVAR(sp) \
153 ( ((sp)->varnum >= sd.localcount) \
154 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
157 #define IS_LOCALVAR_SD(sd, sp) \
158 ((sp)->varnum < (sd).localcount)
160 #define IS_LOCALVAR(sp) \
161 IS_LOCALVAR_SD(sd, (sp))
164 /* macros for setting variable properties ****************************/
166 #define SET_TEMPVAR(sp) \
168 if (IS_LOCALVAR((sp))) { \
169 GET_NEW_VAR(sd, new_index, (sp)->type); \
170 sd.var[new_index].flags = (sp)->flags; \
171 (sp)->varnum = new_index; \
172 (sp)->varkind = TEMPVAR; \
174 (sp)->creator->dst.varindex = new_index; \
176 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
179 #define SET_PREALLOC(sp) \
181 assert(!IS_LOCALVAR((sp))); \
182 sd.var[(sp)->varnum].flags |= PREALLOC; \
186 /* macros for source operands ***************************************/
189 (iptr->s1.varindex = -1)
191 #define USE_S1(type1) \
194 CHECK_BASIC_TYPE(type1, curstack->type); \
195 iptr->s1.varindex = curstack->varnum; \
201 iptr->s1.varindex = curstack->varnum; \
204 #define USE_S1_S2(type1, type2) \
207 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
208 CHECK_BASIC_TYPE(type2, curstack->type); \
209 iptr->sx.s23.s2.varindex = curstack->varnum; \
210 iptr->s1.varindex = curstack->prev->varnum; \
213 #define USE_S1_S2_ANY_ANY \
216 iptr->sx.s23.s2.varindex = curstack->varnum; \
217 iptr->s1.varindex = curstack->prev->varnum; \
220 #define USE_S1_S2_S3(type1, type2, type3) \
223 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
224 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
225 CHECK_BASIC_TYPE(type3, curstack->type); \
226 iptr->sx.s23.s3.varindex = curstack->varnum; \
227 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
228 iptr->s1.varindex = curstack->prev->prev->varnum; \
231 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
234 if (curstack->varkind == UNDEFVAR) \
235 curstack->varkind = TEMPVAR; \
236 curstack = curstack->prev; \
239 #define POP_S1(type1) \
242 if (curstack->varkind == UNDEFVAR) \
243 curstack->varkind = TEMPVAR; \
244 curstack = curstack->prev; \
250 if (curstack->varkind == UNDEFVAR) \
251 curstack->varkind = TEMPVAR; \
252 curstack = curstack->prev; \
255 #define POP_S1_S2(type1, type2) \
257 USE_S1_S2(type1, type2); \
258 if (curstack->varkind == UNDEFVAR) \
259 curstack->varkind = TEMPVAR; \
260 if (curstack->prev->varkind == UNDEFVAR) \
261 curstack->prev->varkind = TEMPVAR; \
262 curstack = curstack->prev->prev; \
265 #define POP_S1_S2_ANY_ANY \
268 if (curstack->varkind == UNDEFVAR) \
269 curstack->varkind = TEMPVAR; \
270 if (curstack->prev->varkind == UNDEFVAR) \
271 curstack->prev->varkind = TEMPVAR; \
272 curstack = curstack->prev->prev; \
275 #define POP_S1_S2_S3(type1, type2, type3) \
277 USE_S1_S2_S3(type1, type2, type3); \
278 if (curstack->varkind == UNDEFVAR) \
279 curstack->varkind = TEMPVAR; \
280 if (curstack->prev->varkind == UNDEFVAR) \
281 curstack->prev->varkind = TEMPVAR; \
282 if (curstack->prev->prev->varkind == UNDEFVAR) \
283 curstack->prev->prev->varkind = TEMPVAR; \
284 curstack = curstack->prev->prev->prev; \
291 /* macros for setting the destination operand ***********************/
294 (iptr->dst.varindex = -1)
296 #define DST(typed, index) \
298 NEWSTACKn((typed),(index)); \
299 curstack->creator = iptr; \
300 iptr->dst.varindex = (index); \
303 #define DST_LOCALVAR(typed, index) \
305 NEWSTACK((typed), LOCALVAR, (index)); \
306 curstack->creator = iptr; \
307 iptr->dst.varindex = (index); \
311 /* macro for propagating constant values ****************************/
313 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
315 (sd).var[(dindex)].type = (sd).var[(sindex)].type; \
316 (sd).var[(dindex)].vv = (sd).var[(sindex)].vv; \
320 /* stack modelling macros *******************************************/
322 #define OP0_1(typed) \
325 GET_NEW_VAR(sd, new_index, (typed)); \
326 DST((typed), new_index); \
337 #define OP1_BRANCH(type1) \
343 #define OP1_1(type1, typed) \
346 GET_NEW_VAR(sd, new_index, (typed)); \
347 DST(typed, new_index); \
350 #define OP2_1(type1, type2, typed) \
352 POP_S1_S2(type1, type2); \
353 GET_NEW_VAR(sd, new_index, (typed)); \
354 DST(typed, new_index); \
369 #define OP1_0(type1) \
376 #define OP2_0(type1, type2) \
378 POP_S1_S2(type1, type2); \
383 #define OP2_BRANCH(type1, type2) \
385 POP_S1_S2(type1, type2); \
389 #define OP2_0_ANY_ANY \
396 #define OP3_0(type1, type2, type3) \
398 POP_S1_S2_S3(type1, type2, type3); \
403 #define LOAD(type1, index) \
405 DST_LOCALVAR(type1, index); \
409 #define STORE(type1, index) \
416 /* macros for DUP elimination ***************************************/
418 /* XXX replace NEW_VAR with NEW_INDEX */
419 #define DUP_SLOT(sp) \
421 GET_NEW_VAR(sd, new_index, (sp)->type); \
422 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
423 NEWSTACK((sp)->type, TEMPVAR, new_index); \
426 /* does not check input stackdepth */
427 #define MOVE_UP(sp) \
429 iptr->opc = ICMD_MOVE; \
430 iptr->s1.varindex = (sp)->varnum; \
432 curstack->creator = iptr; \
433 iptr->dst.varindex = curstack->varnum; \
437 /* does not check input stackdepth */
438 #define COPY_UP(sp) \
441 iptr->opc = ICMD_COPY; \
442 iptr->s1.varindex = (sp)->varnum; \
444 curstack->creator = iptr; \
445 iptr->dst.varindex = curstack->varnum; \
449 #define COPY_DOWN(s, d) \
452 iptr->opc = ICMD_COPY; \
453 iptr->s1.varindex = (s)->varnum; \
454 iptr->dst.varindex = (d)->varnum; \
455 (d)->creator = iptr; \
458 #define MOVE_TO_TEMP(sp) \
460 GET_NEW_INDEX(sd, new_index); \
461 iptr->opc = ICMD_MOVE; \
462 iptr->s1.varindex = (sp)->varnum; \
463 iptr->dst.varindex = new_index; \
464 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
465 (sp)->varnum = new_index; \
466 (sp)->varkind = TEMPVAR; \
469 /* macros for branching / reaching basic blocks *********************/
471 #define BRANCH_TARGET(bt, tempbptr) \
473 tempbptr = BLOCK_OF((bt).insindex); \
474 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
476 if (tempbptr == NULL) \
478 (bt).block = tempbptr; \
481 #define BRANCH(tempbptr) \
482 BRANCH_TARGET(iptr->dst, tempbptr)
485 /* forward declarations *******************************************************/
487 static void stack_create_invars(stackdata_t *sd, basicblock *b,
488 stackptr curstack, int stackdepth);
489 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
491 #if defined(STACK_VERBOSE)
492 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
493 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
494 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
495 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
496 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
500 /* stack_init ******************************************************************
502 Initialized the stack analysis subsystem (called by jit_init).
504 *******************************************************************************/
506 bool stack_init(void)
512 /* stack_grow_variable_array ***************************************************
514 Grow the variable array so the given number of additional variables fits in.
517 sd...........stack analysis data
518 num..........number of additional variables
520 *******************************************************************************/
522 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
531 /* XXX avoid too many reallocations */
532 newcount = sd->varcount + num;
534 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
535 sd->varcount = newcount;
536 sd->jd->var = sd->var;
537 sd->jd->varcount = newcount;
541 /* stack_append_block **********************************************************
543 Append the given block after the last real block of the method (before
544 the pseudo-block at the end).
547 sd...........stack analysis data
548 b............the block to append
550 *******************************************************************************/
552 static void stack_append_block(stackdata_t *sd, basicblock *b)
554 #if defined(STACK_VERBOSE)
555 printf("APPENDING BLOCK L%0d\n", b->nr);
558 b->next = sd->last_real_block->next;
559 sd->last_real_block->next = b;
560 sd->last_real_block = b;
561 sd->jd->basicblockcount++;
565 /* stack_clone_block ***********************************************************
567 Create a copy of the given block and insert it at the end of the method.
569 CAUTION: This function does not copy the any variables or the instruction
570 list. It _does_, however, reserve space for the block's invars in the
574 sd...........stack analysis data
575 b............the block to clone
578 a pointer to the copy
580 *******************************************************************************/
582 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
586 clone = DNEW(basicblock);
589 clone->iinstr = NULL;
590 clone->inlocals = NULL;
591 clone->invars = NULL;
593 clone->original = (b->original) ? b->original : b;
594 clone->copied_to = clone->original->copied_to;
595 clone->original->copied_to = clone;
596 clone->nr = sd->m->c_block_nr++;
598 clone->flags = BBREACHED;
600 stack_append_block(sd, clone);
602 /* allocate space for the invars of the clone */
604 stack_grow_variable_array(sd, b->indepth);
606 #if defined(STACK_VERBOSE)
607 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
614 /* stack_create_invars *********************************************************
616 Create the invars for the given basic block. Also make a copy of the locals.
619 sd...........stack analysis data
620 b............block to create the invars for
621 curstack.....current stack top
622 stackdepth...current stack depth
624 This function creates STACKDEPTH invars and sets their types to the
625 types to the types of the corresponding slot in the current stack.
627 *******************************************************************************/
629 static void stack_create_invars(stackdata_t *sd, basicblock *b,
630 stackptr curstack, int stackdepth)
637 assert(sd->vartop + stackdepth <= sd->varcount);
639 b->indepth = stackdepth;
640 b->invars = DMNEW(s4, stackdepth);
642 /* allocate the variable indices */
643 index = (sd->vartop += stackdepth);
646 for (sp = curstack; i--; sp = sp->prev) {
647 b->invars[i] = --index;
651 v->vv = sd->var[sp->varnum].vv;
652 #if defined(STACK_VERBOSE) && 0
653 printf("\tinvar[%d]: %d\n", i, sd->var[b->invars[i]]);
657 /* copy the current state of the local variables */
658 /* (one extra local is needed by the verifier) */
660 v = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
662 for (i=0; i<sd->localcount; ++i)
667 /* stack_create_invars_from_outvars ********************************************
669 Create the invars for the given basic block. Also make a copy of the locals.
670 Types are propagated from the outvars of the current block.
673 sd...........stack analysis data
674 b............block to create the invars for
676 *******************************************************************************/
678 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
684 n = sd->bptr->outdepth;
685 assert(sd->vartop + n <= sd->varcount);
688 b->invars = DMNEW(s4, n);
691 dv = sd->var + sd->vartop;
693 /* allocate the invars */
695 for (i=0; i<n; ++i, ++dv) {
696 sv = sd->var + sd->bptr->outvars[i];
697 b->invars[i] = sd->vartop++;
704 /* copy the current state of the local variables */
705 /* (one extra local is needed by the verifier) */
707 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
709 for (i=0; i<sd->localcount; ++i)
714 /* stack_check_invars **********************************************************
716 Check the current stack against the invars of the given basic block.
717 Depth and types must match.
720 sd...........stack analysis data
721 b............block which invars to check against
722 curstack.....current stack top
723 stackdepth...current stack depth
727 NULL.........a VerifyError has been thrown
729 *******************************************************************************/
731 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
732 stackptr curstack, int stackdepth)
739 #if defined(STACK_VERBOSE)
740 printf("stack_check_invars(L%03d)\n", b->nr);
743 /* find original of b */
748 #if defined(STACK_VERBOSE)
749 printf("original is L%03d\n", orig->nr);
754 if (i != stackdepth) {
755 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
762 #if defined(STACK_VERBOSE)
763 printf("checking against ");
764 stack_verbose_show_block(sd, b); printf("\n");
768 for (i = orig->indepth; i--; sp = sp->prev) {
769 if (sd->var[b->invars[i]].type != sp->type) {
770 exceptions_throw_verifyerror_for_stack(sd->m,
771 sd->var[b->invars[i]].type);
775 if (sp->type == TYPE_RET) {
776 if (sd->var[b->invars[i]].vv.retaddr != sd->var[sp->varnum].vv.retaddr) {
784 for (i=0; i<sd->localcount; ++i) {
785 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
786 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
795 /* XXX mark mixed type variables void */
796 /* XXX cascading collapse? */
797 #if defined(STACK_VERBOSE)
798 printf("------> using L%03d\n", b->nr);
802 } while ((b = b->copied_to) != NULL);
804 b = stack_clone_block(sd, orig);
808 stack_create_invars(sd, b, curstack, stackdepth);
813 /* stack_check_invars_from_outvars *********************************************
815 Check the outvars of the current block against the invars of the given block.
816 Depth and types must match.
819 sd...........stack analysis data
820 b............block which invars to check against
824 NULL.........a VerifyError has been thrown
826 *******************************************************************************/
828 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
836 #if defined(STACK_VERBOSE)
837 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
840 /* find original of b */
845 #if defined(STACK_VERBOSE)
846 printf("original is L%03d\n", orig->nr);
850 n = sd->bptr->outdepth;
853 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
860 #if defined(STACK_VERBOSE)
861 printf("checking against ");
862 stack_verbose_show_block(sd, b); printf("\n");
866 dv = sd->var + b->invars[0];
868 for (i=0; i<n; ++i, ++dv) {
869 sv = sd->var + sd->bptr->outvars[i];
870 if (sv->type != dv->type) {
871 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
875 if (dv->type == TYPE_RET) {
876 if (sv->vv.retaddr != dv->vv.retaddr) {
885 for (i=0; i<sd->localcount; ++i) {
886 if (sd->var[i].type == TYPE_RET && b->inlocals[i].type == TYPE_RET) {
887 if (sd->var[i].vv.retaddr != b->inlocals[i].vv.retaddr) {
896 /* XXX mark mixed type variables void */
897 /* XXX cascading collapse? */
898 #if defined(STACK_VERBOSE)
899 printf("------> using L%03d\n", b->nr);
903 } while ((b = b->copied_to) != NULL);
905 b = stack_clone_block(sd, orig);
909 stack_create_invars_from_outvars(sd, b);
914 /* stack_create_instack ********************************************************
916 Create the instack of the current basic block.
919 sd...........stack analysis data
922 the current stack top at the start of the basic block.
924 *******************************************************************************/
926 static stackptr stack_create_instack(stackdata_t *sd)
932 if ((depth = sd->bptr->indepth) == 0)
935 sp = (sd->new += depth);
939 index = sd->bptr->invars[depth];
941 sp->type = sd->var[index].type;
945 sp->varkind = STACKVAR;
949 /* return the top of the created stack */
954 /* stack_mark_reached **********************************************************
956 Mark the given block reached and propagate the current stack and locals to
957 it. This function specializes the target block, if necessary, and returns
958 a pointer to the specialized target.
961 sd...........stack analysis data
962 b............the block to reach
963 curstack.....the current stack top
964 stackdepth...the current stack depth
967 a pointer to (a specialized version of) the target
968 NULL.........a VerifyError has been thrown
970 *******************************************************************************/
972 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
974 #if defined(STACK_VERBOSE)
975 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
977 /* mark targets of backward branches */
979 b->bitflags |= BBFLAG_REPLACEMENT;
981 if (b->flags < BBREACHED) {
982 /* b is reached for the first time. Create its invars. */
984 #if defined(STACK_VERBOSE)
985 printf("reached L%03d for the first time\n", b->nr);
988 stack_create_invars(sd, b, curstack, stackdepth);
990 b->flags = BBREACHED;
995 /* b has been reached before. Check that its invars match. */
997 return stack_check_invars(sd, b, curstack, stackdepth);
1002 /* stack_mark_reached_from_outvars *********************************************
1004 Mark the given block reached and propagate the outvars of the current block
1005 and the current locals to it. This function specializes the target block,
1006 if necessary, and returns a pointer to the specialized target.
1009 sd...........stack analysis data
1010 b............the block to reach
1013 a pointer to (a specialized version of) the target
1014 NULL.........a VerifyError has been thrown
1016 *******************************************************************************/
1018 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1020 #if defined(STACK_VERBOSE)
1021 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1023 /* mark targets of backward branches */
1025 b->bitflags |= BBFLAG_REPLACEMENT;
1027 if (b->flags < BBREACHED) {
1028 /* b is reached for the first time. Create its invars. */
1030 #if defined(STACK_VERBOSE)
1031 printf("reached L%03d for the first time\n", b->nr);
1034 stack_create_invars_from_outvars(sd, b);
1036 b->flags = BBREACHED;
1041 /* b has been reached before. Check that its invars match. */
1043 return stack_check_invars_from_outvars(sd, b);
1048 /* stack_reach_next_block ******************************************************
1050 Mark the following block reached and propagate the outvars of the current block
1051 and the current locals to it. This function specializes the target block,
1052 if necessary, and returns a pointer to the specialized target.
1055 sd...........stack analysis data
1058 a pointer to (a specialized version of) the following block
1059 NULL.........a VerifyError has been thrown
1061 *******************************************************************************/
1063 static bool stack_reach_next_block(stackdata_t *sd)
1068 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1069 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1073 if (tbptr != sd->bptr->next) {
1074 #if defined(STACK_VERBOSE)
1075 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1077 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1078 assert(iptr->opc == ICMD_NOP);
1079 iptr->opc = ICMD_GOTO;
1080 iptr->dst.block = tbptr;
1082 if (tbptr->flags < BBFINISHED)
1083 sd->repeat = true; /* XXX check if we really need to repeat */
1090 /* stack_reach_handlers ********************************************************
1092 Reach the exception handlers for the current block.
1095 sd...........stack analysis data
1098 true.........everything ok
1099 false........a VerifyError has been thrown
1101 *******************************************************************************/
1103 static bool stack_reach_handlers(stackdata_t *sd)
1108 #if defined(STACK_VERBOSE)
1109 printf("reaching exception handlers...\n");
1112 for (i=0; sd->handlers[i]; ++i) {
1113 tbptr = sd->handlers[i]->handler;
1115 tbptr->type = BBTYPE_EXH;
1116 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1118 /* reach (and specialize) the handler block */
1120 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1125 sd->handlers[i]->handler = tbptr;
1132 /* stack_reanalyse_block ******************************************************
1134 Re-analyse the current block. This is called if either the block itself
1135 has already been analysed before, or the current block is a clone of an
1136 already analysed block, and this clone is reached for the first time.
1137 In the latter case, this function does all that is necessary for fully
1138 cloning the block (cloning the instruction list and variables, etc.).
1141 sd...........stack analysis data
1144 true.........everything ok
1145 false........a VerifyError has been thrown
1147 *******************************************************************************/
1149 #define RELOCATE(index) \
1151 if ((index) >= blockvarstart) \
1152 (index) += blockvarshift; \
1153 else if ((index) >= invarstart) \
1154 (index) += invarshift; \
1157 bool stack_reanalyse_block(stackdata_t *sd)
1169 branch_target_t *table;
1170 lookup_target_t *lookup;
1173 bool cloneinstructions;
1176 #if defined(STACK_VERBOSE)
1177 stack_verbose_block_enter(sd, true);
1184 assert(orig != NULL);
1186 /* clone the instruction list */
1188 cloneinstructions = true;
1190 assert(orig->iinstr);
1192 iptr = DMNEW(instruction, len + 1);
1194 MCOPY(iptr, orig->iinstr, instruction, len);
1195 iptr[len].opc = ICMD_NOP;
1199 /* allocate space for the clone's block variables */
1201 stack_grow_variable_array(sd, orig->varcount);
1203 /* we already have the invars set */
1205 assert(b->indepth == orig->indepth);
1207 /* calculate relocation shifts for invars and block variables */
1209 if (orig->indepth) {
1210 invarstart = orig->invars[0];
1211 invarshift = b->invars[0] - invarstart;
1214 invarstart = INT_MAX;
1217 blockvarstart = orig->varstart;
1218 blockvarshift = sd->vartop - blockvarstart;
1220 /* copy block variables */
1222 b->varstart = sd->vartop;
1223 b->varcount = orig->varcount;
1224 sd->vartop += b->varcount;
1225 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1229 b->outdepth = orig->outdepth;
1230 b->outvars = DMNEW(s4, orig->outdepth);
1231 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1233 /* clone exception handlers */
1235 for (i=0; sd->handlers[i]; ++i) {
1236 ex = DNEW(exceptiontable);
1237 ex->handler = sd->handlers[i]->handler;
1239 ex->end = b; /* XXX hack, see end of stack_analyse */
1240 ex->catchtype = sd->handlers[i]->catchtype;
1243 assert(sd->extableend->down == NULL);
1244 sd->extableend->down = ex;
1245 sd->extableend = ex;
1246 sd->jd->cd->exceptiontablelength++;
1248 sd->handlers[i] = ex;
1252 cloneinstructions = false;
1255 invarstart = sd->vartop;
1256 blockvarstart = sd->vartop;
1261 /* find exception handlers for the cloned block */
1263 ex = sd->jd->cd->exceptiontable;
1264 for (; ex != NULL; ex = ex->down) {
1265 /* XXX the cloned exception handlers have identical */
1266 /* start end end blocks. */
1267 if ((ex->start == b) && (ex->end == b)) {
1268 sd->handlers[len++] = ex;
1271 sd->handlers[len] = NULL;
1274 #if defined(STACK_VERBOSE)
1275 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1276 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1279 /* mark block as finished */
1281 b->flags = BBFINISHED;
1283 /* initialize locals at the start of this block */
1286 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1288 /* reach exception handlers for this block */
1290 if (!stack_reach_handlers(sd))
1293 superblockend = false;
1295 for (len = b->icount; len--; iptr++) {
1296 #if defined(STACK_VERBOSE)
1297 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1303 switch (iptr->opc) {
1305 j = iptr->s1.varindex;
1307 if (sd->var[j].type != TYPE_RET) {
1308 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1312 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1313 superblockend = true;
1317 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1318 superblockend = true;
1322 superblockend = true;
1325 case ICMD_CHECKNULL:
1326 case ICMD_PUTSTATICCONST:
1332 case ICMD_INLINE_START:
1333 case ICMD_INLINE_END:
1334 case ICMD_INLINE_GOTO:
1338 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1339 superblockend = true;
1342 /* pop 0 push 1 const */
1351 /* pop 0 push 1 load */
1358 RELOCATE(iptr->dst.varindex);
1371 RELOCATE(iptr->sx.s23.s2.varindex);
1372 RELOCATE(iptr->s1.varindex);
1373 RELOCATE(iptr->dst.varindex);
1387 RELOCATE(iptr->sx.s23.s3.varindex);
1388 RELOCATE(iptr->sx.s23.s2.varindex);
1389 RELOCATE(iptr->s1.varindex);
1393 /* pop 1 push 0 store */
1400 RELOCATE(iptr->s1.varindex);
1402 j = iptr->dst.varindex;
1403 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1415 RELOCATE(iptr->s1.varindex);
1416 superblockend = true;
1419 case ICMD_PUTSTATIC:
1420 case ICMD_PUTFIELDCONST:
1423 RELOCATE(iptr->s1.varindex);
1426 /* pop 1 push 0 branch */
1429 case ICMD_IFNONNULL:
1444 RELOCATE(iptr->s1.varindex);
1445 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1448 /* pop 1 push 0 table branch */
1450 case ICMD_TABLESWITCH:
1451 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1453 if (cloneinstructions) {
1454 table = DMNEW(branch_target_t, i);
1455 MCOPY(table, iptr->dst.table, branch_target_t, i);
1456 iptr->dst.table = table;
1459 table = iptr->dst.table;
1462 RELOCATE(iptr->s1.varindex);
1464 table->block = stack_mark_reached_from_outvars(sd, table->block);
1467 superblockend = true;
1470 case ICMD_LOOKUPSWITCH:
1471 i = iptr->sx.s23.s2.lookupcount;
1472 if (cloneinstructions) {
1473 lookup = DMNEW(lookup_target_t, i);
1474 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1475 iptr->dst.lookup = lookup;
1478 lookup = iptr->dst.lookup;
1480 RELOCATE(iptr->s1.varindex);
1482 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1485 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1486 superblockend = true;
1489 case ICMD_MONITORENTER:
1490 case ICMD_MONITOREXIT:
1491 RELOCATE(iptr->s1.varindex);
1495 /* pop 2 push 0 branch */
1497 case ICMD_IF_ICMPEQ:
1498 case ICMD_IF_ICMPNE:
1499 case ICMD_IF_ICMPLT:
1500 case ICMD_IF_ICMPGE:
1501 case ICMD_IF_ICMPGT:
1502 case ICMD_IF_ICMPLE:
1504 case ICMD_IF_LCMPEQ:
1505 case ICMD_IF_LCMPNE:
1506 case ICMD_IF_LCMPLT:
1507 case ICMD_IF_LCMPGE:
1508 case ICMD_IF_LCMPGT:
1509 case ICMD_IF_LCMPLE:
1511 case ICMD_IF_FCMPEQ:
1512 case ICMD_IF_FCMPNE:
1514 case ICMD_IF_FCMPL_LT:
1515 case ICMD_IF_FCMPL_GE:
1516 case ICMD_IF_FCMPL_GT:
1517 case ICMD_IF_FCMPL_LE:
1519 case ICMD_IF_FCMPG_LT:
1520 case ICMD_IF_FCMPG_GE:
1521 case ICMD_IF_FCMPG_GT:
1522 case ICMD_IF_FCMPG_LE:
1524 case ICMD_IF_DCMPEQ:
1525 case ICMD_IF_DCMPNE:
1527 case ICMD_IF_DCMPL_LT:
1528 case ICMD_IF_DCMPL_GE:
1529 case ICMD_IF_DCMPL_GT:
1530 case ICMD_IF_DCMPL_LE:
1532 case ICMD_IF_DCMPG_LT:
1533 case ICMD_IF_DCMPG_GE:
1534 case ICMD_IF_DCMPG_GT:
1535 case ICMD_IF_DCMPG_LE:
1537 case ICMD_IF_ACMPEQ:
1538 case ICMD_IF_ACMPNE:
1539 RELOCATE(iptr->sx.s23.s2.varindex);
1540 RELOCATE(iptr->s1.varindex);
1541 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1547 case ICMD_IASTORECONST:
1548 case ICMD_LASTORECONST:
1549 case ICMD_AASTORECONST:
1550 case ICMD_BASTORECONST:
1551 case ICMD_CASTORECONST:
1552 case ICMD_SASTORECONST:
1555 RELOCATE(iptr->sx.s23.s2.varindex);
1556 RELOCATE(iptr->s1.varindex);
1559 /* pop 0 push 1 copy */
1563 RELOCATE(iptr->dst.varindex);
1564 RELOCATE(iptr->s1.varindex);
1565 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1608 RELOCATE(iptr->sx.s23.s2.varindex);
1609 RELOCATE(iptr->s1.varindex);
1610 RELOCATE(iptr->dst.varindex);
1615 case ICMD_CHECKCAST:
1616 case ICMD_ARRAYLENGTH:
1617 case ICMD_INSTANCEOF:
1619 case ICMD_ANEWARRAY:
1622 case ICMD_IADDCONST:
1623 case ICMD_ISUBCONST:
1624 case ICMD_IMULCONST:
1628 case ICMD_IANDCONST:
1630 case ICMD_IXORCONST:
1631 case ICMD_ISHLCONST:
1632 case ICMD_ISHRCONST:
1633 case ICMD_IUSHRCONST:
1634 case ICMD_LADDCONST:
1635 case ICMD_LSUBCONST:
1636 case ICMD_LMULCONST:
1640 case ICMD_LANDCONST:
1642 case ICMD_LXORCONST:
1643 case ICMD_LSHLCONST:
1644 case ICMD_LSHRCONST:
1645 case ICMD_LUSHRCONST:
1649 case ICMD_INT2SHORT:
1665 RELOCATE(iptr->s1.varindex);
1666 RELOCATE(iptr->dst.varindex);
1671 case ICMD_GETSTATIC:
1674 RELOCATE(iptr->dst.varindex);
1677 /* pop many push any */
1679 case ICMD_INVOKESTATIC:
1680 case ICMD_INVOKESPECIAL:
1681 case ICMD_INVOKEVIRTUAL:
1682 case ICMD_INVOKEINTERFACE:
1684 case ICMD_MULTIANEWARRAY:
1685 i = iptr->s1.argcount;
1686 if (cloneinstructions) {
1687 argp = DMNEW(s4, i);
1688 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1689 iptr->sx.s23.s2.args = argp;
1692 argp = iptr->sx.s23.s2.args;
1700 RELOCATE(iptr->dst.varindex);
1705 new_internalerror("Unknown ICMD %d during stack re-analysis",
1710 #if defined(STACK_VERBOSE)
1711 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1716 /* relocate outvars */
1718 for (i=0; i<b->outdepth; ++i) {
1719 RELOCATE(b->outvars[i]);
1722 #if defined(STACK_VERBOSE)
1723 stack_verbose_block_exit(sd, superblockend);
1726 /* propagate to the next block */
1729 if (!stack_reach_next_block(sd))
1736 /* stack_analyse ***************************************************************
1738 Analyse_stack uses the intermediate code created by parse.c to
1739 build a model of the JVM operand stack for the current method.
1741 The following checks are performed:
1742 - check for operand stack underflow (before each instruction)
1743 - check for operand stack overflow (after[1] each instruction)
1744 - check for matching stack depth at merging points
1745 - check for matching basic types[2] at merging points
1746 - check basic types for instruction input (except for BUILTIN*
1747 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1749 [1]) Checking this after the instruction should be ok. parse.c
1750 counts the number of required stack slots in such a way that it is
1751 only vital that we don't exceed `maxstack` at basic block
1754 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1755 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1756 types are not discerned.
1758 *******************************************************************************/
1760 bool stack_analyse(jitdata *jd)
1762 methodinfo *m; /* method being analyzed */
1767 #if defined(ENABLE_SSA)
1770 int b_index; /* basic block index */
1772 stackptr curstack; /* current stack top */
1774 int opcode; /* opcode of current instruction */
1777 int len; /* # of instructions after the current one */
1778 bool superblockend; /* if true, no fallthrough to next block */
1779 bool deadcode; /* true if no live code has been reached */
1780 instruction *iptr; /* the current instruction */
1782 basicblock *original;
1785 stackptr *last_store_boundary;
1786 stackptr coalescing_boundary;
1788 stackptr src1, src2, src3, src4, dst1, dst2;
1790 branch_target_t *table;
1791 lookup_target_t *lookup;
1792 #if defined(ENABLE_VERIFIER)
1793 int expectedtype; /* used by CHECK_BASIC_TYPE */
1795 builtintable_entry *bte;
1797 constant_FMIref *fmiref;
1798 #if defined(ENABLE_STATISTICS)
1799 int iteration_count; /* number of iterations of analysis */
1801 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1803 #if defined(STACK_VERBOSE)
1804 show_method(jd, SHOW_PARSE);
1807 /* get required compiler data - initialization */
1813 #if defined(ENABLE_SSA)
1817 /* initialize the stackdata_t struct */
1821 sd.varcount = jd->varcount;
1822 sd.vartop = jd->vartop;
1823 sd.localcount = jd->localcount;
1825 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1826 sd.exstack.type = TYPE_ADR;
1827 sd.exstack.prev = NULL;
1828 sd.exstack.varnum = 0; /* XXX do we need a real variable index here? */
1830 #if defined(ENABLE_LSRA)
1831 m->maxlifetimes = 0;
1834 #if defined(ENABLE_STATISTICS)
1835 iteration_count = 0;
1838 /* find the last real basic block */
1840 sd.last_real_block = NULL;
1841 tbptr = jd->basicblocks;
1842 while (tbptr->next) {
1843 sd.last_real_block = tbptr;
1844 tbptr = tbptr->next;
1846 assert(sd.last_real_block);
1848 /* find the last exception handler */
1850 if (cd->exceptiontablelength)
1851 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
1853 sd.extableend = NULL;
1855 /* init jd->interface_map */
1857 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
1858 for (i = 0; i < m->maxstack * 5; i++)
1859 jd->interface_map[i].flags = UNUSED;
1861 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
1863 /* initialize flags and invars (none) of first block */
1865 jd->basicblocks[0].flags = BBREACHED;
1866 jd->basicblocks[0].invars = NULL;
1867 jd->basicblocks[0].indepth = 0;
1868 jd->basicblocks[0].inlocals =
1869 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
1870 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
1871 jd->localcount + VERIFIER_EXTRA_LOCALS);
1873 /* stack analysis loop (until fixpoint reached) **************************/
1876 #if defined(ENABLE_STATISTICS)
1880 /* initialize loop over basic blocks */
1882 sd.bptr = jd->basicblocks;
1883 superblockend = true;
1885 curstack = NULL; stackdepth = 0;
1888 /* iterate over basic blocks *****************************************/
1890 for (; sd.bptr; sd.bptr = sd.bptr->next) {
1892 if (sd.bptr->flags == BBDELETED) {
1893 /* This block has been deleted - do nothing. */
1898 if (superblockend && (sd.bptr->flags < BBREACHED)) {
1899 /* This block has not been reached so far, and we */
1900 /* don't fall into it, so we'll have to iterate again. */
1906 if (sd.bptr->flags > BBREACHED) {
1907 /* This block is already finished. */
1909 superblockend = true;
1913 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
1914 /* This block is a clone and the original has not been */
1915 /* analysed, yet. Analyse it on the next iteration. */
1921 /* This block has to be analysed now. */
1923 /* XXX The rest of this block is still indented one level too */
1924 /* much in order to avoid a giant diff by changing that. */
1926 /* We know that sd.bptr->flags == BBREACHED. */
1927 /* This block has been reached before. */
1929 assert(sd.bptr->flags == BBREACHED);
1930 stackdepth = sd.bptr->indepth;
1932 /* find exception handlers for this block */
1934 /* determine the active exception handlers for this block */
1935 /* XXX could use a faster algorithm with sorted lists or */
1938 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
1941 ex = cd->exceptiontable;
1942 for (; ex != NULL; ex = ex->down) {
1943 if ((ex->start <= original) && (ex->end > original)) {
1944 sd.handlers[len++] = ex;
1947 sd.handlers[len] = NULL;
1950 /* reanalyse cloned block */
1952 if (sd.bptr->original) {
1953 if (!stack_reanalyse_block(&sd))
1958 /* reset the new pointer for allocating stackslots */
1962 /* create the instack of this block */
1964 curstack = stack_create_instack(&sd);
1966 /* initialize locals at the start of this block */
1968 if (sd.bptr->inlocals)
1969 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
1971 /* set up local variables for analyzing this block */
1974 superblockend = false;
1975 len = sd.bptr->icount;
1976 iptr = sd.bptr->iinstr;
1977 b_index = sd.bptr - jd->basicblocks;
1979 /* mark the block as analysed */
1981 sd.bptr->flags = BBFINISHED;
1983 /* reset variables for dependency checking */
1985 coalescing_boundary = sd.new;
1986 for( i = 0; i < cd->maxlocals; i++)
1987 last_store_boundary[i] = sd.new;
1989 /* remember the start of this block's variables */
1991 sd.bptr->varstart = sd.vartop;
1993 #if defined(STACK_VERBOSE)
1994 stack_verbose_block_enter(&sd, false);
1997 /* reach exception handlers for this block */
1999 if (!stack_reach_handlers(&sd))
2002 /* iterate over ICMDs ****************************************/
2004 while (--len >= 0) {
2006 #if defined(STACK_VERBOSE)
2007 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2008 for( copy = curstack; copy; copy = copy->prev ) {
2009 printf("%2d(%d", copy->varnum, copy->type);
2012 if (IS_PREALLOC(copy))
2019 /* fetch the current opcode */
2023 /* automatically replace some ICMDs with builtins */
2025 #if defined(USEBUILTINTABLE)
2026 bte = builtintable_get_automatic(opcode);
2028 if (bte && bte->opcode == opcode) {
2029 iptr->opc = ICMD_BUILTIN;
2030 iptr->flags.bits = 0;
2031 iptr->sx.s23.s3.bte = bte;
2032 /* iptr->line is already set */
2033 jd->isleafmethod = false;
2036 #endif /* defined(USEBUILTINTABLE) */
2038 /* main opcode switch *************************************/
2050 case ICMD_CHECKNULL:
2051 coalescing_boundary = sd.new;
2052 COUNT(count_check_null);
2055 CLR_DST; /* XXX live through? */
2059 j = iptr->s1.varindex =
2060 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2062 if (sd.var[j].type != TYPE_RET) {
2063 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2069 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2070 superblockend = true;
2074 COUNT(count_pcmd_return);
2077 superblockend = true;
2081 /* pop 0 push 1 const */
2083 /************************** ICONST OPTIMIZATIONS **************************/
2086 COUNT(count_pcmd_load);
2090 switch (iptr[1].opc) {
2092 iptr->opc = ICMD_IADDCONST;
2096 iptr[1].opc = ICMD_NOP;
2097 OP1_1(TYPE_INT, TYPE_INT);
2098 COUNT(count_pcmd_op);
2102 iptr->opc = ICMD_ISUBCONST;
2103 goto icmd_iconst_tail;
2104 #if SUPPORT_CONST_MUL
2106 iptr->opc = ICMD_IMULCONST;
2107 goto icmd_iconst_tail;
2108 #else /* SUPPORT_CONST_MUL */
2110 if (iptr->sx.val.i == 0x00000002)
2112 else if (iptr->sx.val.i == 0x00000004)
2114 else if (iptr->sx.val.i == 0x00000008)
2116 else if (iptr->sx.val.i == 0x00000010)
2118 else if (iptr->sx.val.i == 0x00000020)
2120 else if (iptr->sx.val.i == 0x00000040)
2122 else if (iptr->sx.val.i == 0x00000080)
2124 else if (iptr->sx.val.i == 0x00000100)
2126 else if (iptr->sx.val.i == 0x00000200)
2128 else if (iptr->sx.val.i == 0x00000400)
2129 iptr->sx.val.i = 10;
2130 else if (iptr->sx.val.i == 0x00000800)
2131 iptr->sx.val.i = 11;
2132 else if (iptr->sx.val.i == 0x00001000)
2133 iptr->sx.val.i = 12;
2134 else if (iptr->sx.val.i == 0x00002000)
2135 iptr->sx.val.i = 13;
2136 else if (iptr->sx.val.i == 0x00004000)
2137 iptr->sx.val.i = 14;
2138 else if (iptr->sx.val.i == 0x00008000)
2139 iptr->sx.val.i = 15;
2140 else if (iptr->sx.val.i == 0x00010000)
2141 iptr->sx.val.i = 16;
2142 else if (iptr->sx.val.i == 0x00020000)
2143 iptr->sx.val.i = 17;
2144 else if (iptr->sx.val.i == 0x00040000)
2145 iptr->sx.val.i = 18;
2146 else if (iptr->sx.val.i == 0x00080000)
2147 iptr->sx.val.i = 19;
2148 else if (iptr->sx.val.i == 0x00100000)
2149 iptr->sx.val.i = 20;
2150 else if (iptr->sx.val.i == 0x00200000)
2151 iptr->sx.val.i = 21;
2152 else if (iptr->sx.val.i == 0x00400000)
2153 iptr->sx.val.i = 22;
2154 else if (iptr->sx.val.i == 0x00800000)
2155 iptr->sx.val.i = 23;
2156 else if (iptr->sx.val.i == 0x01000000)
2157 iptr->sx.val.i = 24;
2158 else if (iptr->sx.val.i == 0x02000000)
2159 iptr->sx.val.i = 25;
2160 else if (iptr->sx.val.i == 0x04000000)
2161 iptr->sx.val.i = 26;
2162 else if (iptr->sx.val.i == 0x08000000)
2163 iptr->sx.val.i = 27;
2164 else if (iptr->sx.val.i == 0x10000000)
2165 iptr->sx.val.i = 28;
2166 else if (iptr->sx.val.i == 0x20000000)
2167 iptr->sx.val.i = 29;
2168 else if (iptr->sx.val.i == 0x40000000)
2169 iptr->sx.val.i = 30;
2170 else if (iptr->sx.val.i == 0x80000000)
2171 iptr->sx.val.i = 31;
2175 iptr->opc = ICMD_IMULPOW2;
2176 goto icmd_iconst_tail;
2177 #endif /* SUPPORT_CONST_MUL */
2179 if (iptr->sx.val.i == 0x00000002)
2181 else if (iptr->sx.val.i == 0x00000004)
2183 else if (iptr->sx.val.i == 0x00000008)
2185 else if (iptr->sx.val.i == 0x00000010)
2187 else if (iptr->sx.val.i == 0x00000020)
2189 else if (iptr->sx.val.i == 0x00000040)
2191 else if (iptr->sx.val.i == 0x00000080)
2193 else if (iptr->sx.val.i == 0x00000100)
2195 else if (iptr->sx.val.i == 0x00000200)
2197 else if (iptr->sx.val.i == 0x00000400)
2198 iptr->sx.val.i = 10;
2199 else if (iptr->sx.val.i == 0x00000800)
2200 iptr->sx.val.i = 11;
2201 else if (iptr->sx.val.i == 0x00001000)
2202 iptr->sx.val.i = 12;
2203 else if (iptr->sx.val.i == 0x00002000)
2204 iptr->sx.val.i = 13;
2205 else if (iptr->sx.val.i == 0x00004000)
2206 iptr->sx.val.i = 14;
2207 else if (iptr->sx.val.i == 0x00008000)
2208 iptr->sx.val.i = 15;
2209 else if (iptr->sx.val.i == 0x00010000)
2210 iptr->sx.val.i = 16;
2211 else if (iptr->sx.val.i == 0x00020000)
2212 iptr->sx.val.i = 17;
2213 else if (iptr->sx.val.i == 0x00040000)
2214 iptr->sx.val.i = 18;
2215 else if (iptr->sx.val.i == 0x00080000)
2216 iptr->sx.val.i = 19;
2217 else if (iptr->sx.val.i == 0x00100000)
2218 iptr->sx.val.i = 20;
2219 else if (iptr->sx.val.i == 0x00200000)
2220 iptr->sx.val.i = 21;
2221 else if (iptr->sx.val.i == 0x00400000)
2222 iptr->sx.val.i = 22;
2223 else if (iptr->sx.val.i == 0x00800000)
2224 iptr->sx.val.i = 23;
2225 else if (iptr->sx.val.i == 0x01000000)
2226 iptr->sx.val.i = 24;
2227 else if (iptr->sx.val.i == 0x02000000)
2228 iptr->sx.val.i = 25;
2229 else if (iptr->sx.val.i == 0x04000000)
2230 iptr->sx.val.i = 26;
2231 else if (iptr->sx.val.i == 0x08000000)
2232 iptr->sx.val.i = 27;
2233 else if (iptr->sx.val.i == 0x10000000)
2234 iptr->sx.val.i = 28;
2235 else if (iptr->sx.val.i == 0x20000000)
2236 iptr->sx.val.i = 29;
2237 else if (iptr->sx.val.i == 0x40000000)
2238 iptr->sx.val.i = 30;
2239 else if (iptr->sx.val.i == 0x80000000)
2240 iptr->sx.val.i = 31;
2244 iptr->opc = ICMD_IDIVPOW2;
2245 goto icmd_iconst_tail;
2248 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2249 if ((iptr->sx.val.i == 0x00000002) ||
2250 (iptr->sx.val.i == 0x00000004) ||
2251 (iptr->sx.val.i == 0x00000008) ||
2252 (iptr->sx.val.i == 0x00000010) ||
2253 (iptr->sx.val.i == 0x00000020) ||
2254 (iptr->sx.val.i == 0x00000040) ||
2255 (iptr->sx.val.i == 0x00000080) ||
2256 (iptr->sx.val.i == 0x00000100) ||
2257 (iptr->sx.val.i == 0x00000200) ||
2258 (iptr->sx.val.i == 0x00000400) ||
2259 (iptr->sx.val.i == 0x00000800) ||
2260 (iptr->sx.val.i == 0x00001000) ||
2261 (iptr->sx.val.i == 0x00002000) ||
2262 (iptr->sx.val.i == 0x00004000) ||
2263 (iptr->sx.val.i == 0x00008000) ||
2264 (iptr->sx.val.i == 0x00010000) ||
2265 (iptr->sx.val.i == 0x00020000) ||
2266 (iptr->sx.val.i == 0x00040000) ||
2267 (iptr->sx.val.i == 0x00080000) ||
2268 (iptr->sx.val.i == 0x00100000) ||
2269 (iptr->sx.val.i == 0x00200000) ||
2270 (iptr->sx.val.i == 0x00400000) ||
2271 (iptr->sx.val.i == 0x00800000) ||
2272 (iptr->sx.val.i == 0x01000000) ||
2273 (iptr->sx.val.i == 0x02000000) ||
2274 (iptr->sx.val.i == 0x04000000) ||
2275 (iptr->sx.val.i == 0x08000000) ||
2276 (iptr->sx.val.i == 0x10000000) ||
2277 (iptr->sx.val.i == 0x20000000) ||
2278 (iptr->sx.val.i == 0x40000000) ||
2279 (iptr->sx.val.i == 0x80000000))
2281 iptr->opc = ICMD_IREMPOW2;
2282 iptr->sx.val.i -= 1;
2283 goto icmd_iconst_tail;
2286 #if SUPPORT_CONST_LOGICAL
2288 iptr->opc = ICMD_IANDCONST;
2289 goto icmd_iconst_tail;
2292 iptr->opc = ICMD_IORCONST;
2293 goto icmd_iconst_tail;
2296 iptr->opc = ICMD_IXORCONST;
2297 goto icmd_iconst_tail;
2299 #endif /* SUPPORT_CONST_LOGICAL */
2301 iptr->opc = ICMD_ISHLCONST;
2302 goto icmd_iconst_tail;
2305 iptr->opc = ICMD_ISHRCONST;
2306 goto icmd_iconst_tail;
2309 iptr->opc = ICMD_IUSHRCONST;
2310 goto icmd_iconst_tail;
2311 #if SUPPORT_LONG_SHIFT
2313 iptr->opc = ICMD_LSHLCONST;
2314 goto icmd_lconst_tail;
2317 iptr->opc = ICMD_LSHRCONST;
2318 goto icmd_lconst_tail;
2321 iptr->opc = ICMD_LUSHRCONST;
2322 goto icmd_lconst_tail;
2323 #endif /* SUPPORT_LONG_SHIFT */
2324 case ICMD_IF_ICMPEQ:
2325 iptr[1].opc = ICMD_IFEQ;
2329 /* set the constant for the following icmd */
2330 iptr[1].sx.val.i = iptr->sx.val.i;
2332 /* this instruction becomes a nop */
2333 iptr->opc = ICMD_NOP;
2336 case ICMD_IF_ICMPLT:
2337 iptr[1].opc = ICMD_IFLT;
2338 goto icmd_if_icmp_tail;
2340 case ICMD_IF_ICMPLE:
2341 iptr[1].opc = ICMD_IFLE;
2342 goto icmd_if_icmp_tail;
2344 case ICMD_IF_ICMPNE:
2345 iptr[1].opc = ICMD_IFNE;
2346 goto icmd_if_icmp_tail;
2348 case ICMD_IF_ICMPGT:
2349 iptr[1].opc = ICMD_IFGT;
2350 goto icmd_if_icmp_tail;
2352 case ICMD_IF_ICMPGE:
2353 iptr[1].opc = ICMD_IFGE;
2354 goto icmd_if_icmp_tail;
2356 #if SUPPORT_CONST_STORE
2361 # if SUPPORT_CONST_STORE_ZERO_ONLY
2362 if (iptr->sx.val.i != 0)
2365 switch (iptr[1].opc) {
2367 iptr->opc = ICMD_IASTORECONST;
2368 iptr->flags.bits |= INS_FLAG_CHECK;
2371 iptr->opc = ICMD_BASTORECONST;
2372 iptr->flags.bits |= INS_FLAG_CHECK;
2375 iptr->opc = ICMD_CASTORECONST;
2376 iptr->flags.bits |= INS_FLAG_CHECK;
2379 iptr->opc = ICMD_SASTORECONST;
2380 iptr->flags.bits |= INS_FLAG_CHECK;
2384 iptr[1].opc = ICMD_NOP;
2386 /* copy the constant to s3 */
2387 /* XXX constval -> astoreconstval? */
2388 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2389 OP2_0(TYPE_ADR, TYPE_INT);
2390 COUNT(count_pcmd_op);
2393 case ICMD_PUTSTATIC:
2395 # if SUPPORT_CONST_STORE_ZERO_ONLY
2396 if (iptr->sx.val.i != 0)
2399 /* XXX check field type? */
2401 /* copy the constant to s2 */
2402 /* XXX constval -> fieldconstval? */
2403 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2406 /* set the field reference (s3) */
2407 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2408 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2409 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2412 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2415 switch (iptr[1].opc) {
2416 case ICMD_PUTSTATIC:
2417 iptr->opc = ICMD_PUTSTATICCONST;
2421 iptr->opc = ICMD_PUTFIELDCONST;
2426 iptr[1].opc = ICMD_NOP;
2427 COUNT(count_pcmd_op);
2429 #endif /* SUPPORT_CONST_STORE */
2435 /* if we get here, the ICONST has been optimized */
2439 /* normal case of an unoptimized ICONST */
2443 /************************** LCONST OPTIMIZATIONS **************************/
2446 COUNT(count_pcmd_load);
2450 /* switch depending on the following instruction */
2452 switch (iptr[1].opc) {
2453 #if SUPPORT_LONG_ADD
2455 iptr->opc = ICMD_LADDCONST;
2459 /* instruction of type LONG -> LONG */
2460 iptr[1].opc = ICMD_NOP;
2461 OP1_1(TYPE_LNG, TYPE_LNG);
2462 COUNT(count_pcmd_op);
2466 iptr->opc = ICMD_LSUBCONST;
2467 goto icmd_lconst_tail;
2469 #endif /* SUPPORT_LONG_ADD */
2470 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2472 iptr->opc = ICMD_LMULCONST;
2473 goto icmd_lconst_tail;
2474 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2475 # if SUPPORT_LONG_SHIFT
2477 if (iptr->sx.val.l == 0x00000002)
2479 else if (iptr->sx.val.l == 0x00000004)
2481 else if (iptr->sx.val.l == 0x00000008)
2483 else if (iptr->sx.val.l == 0x00000010)
2485 else if (iptr->sx.val.l == 0x00000020)
2487 else if (iptr->sx.val.l == 0x00000040)
2489 else if (iptr->sx.val.l == 0x00000080)
2491 else if (iptr->sx.val.l == 0x00000100)
2493 else if (iptr->sx.val.l == 0x00000200)
2495 else if (iptr->sx.val.l == 0x00000400)
2496 iptr->sx.val.i = 10;
2497 else if (iptr->sx.val.l == 0x00000800)
2498 iptr->sx.val.i = 11;
2499 else if (iptr->sx.val.l == 0x00001000)
2500 iptr->sx.val.i = 12;
2501 else if (iptr->sx.val.l == 0x00002000)
2502 iptr->sx.val.i = 13;
2503 else if (iptr->sx.val.l == 0x00004000)
2504 iptr->sx.val.i = 14;
2505 else if (iptr->sx.val.l == 0x00008000)
2506 iptr->sx.val.i = 15;
2507 else if (iptr->sx.val.l == 0x00010000)
2508 iptr->sx.val.i = 16;
2509 else if (iptr->sx.val.l == 0x00020000)
2510 iptr->sx.val.i = 17;
2511 else if (iptr->sx.val.l == 0x00040000)
2512 iptr->sx.val.i = 18;
2513 else if (iptr->sx.val.l == 0x00080000)
2514 iptr->sx.val.i = 19;
2515 else if (iptr->sx.val.l == 0x00100000)
2516 iptr->sx.val.i = 20;
2517 else if (iptr->sx.val.l == 0x00200000)
2518 iptr->sx.val.i = 21;
2519 else if (iptr->sx.val.l == 0x00400000)
2520 iptr->sx.val.i = 22;
2521 else if (iptr->sx.val.l == 0x00800000)
2522 iptr->sx.val.i = 23;
2523 else if (iptr->sx.val.l == 0x01000000)
2524 iptr->sx.val.i = 24;
2525 else if (iptr->sx.val.l == 0x02000000)
2526 iptr->sx.val.i = 25;
2527 else if (iptr->sx.val.l == 0x04000000)
2528 iptr->sx.val.i = 26;
2529 else if (iptr->sx.val.l == 0x08000000)
2530 iptr->sx.val.i = 27;
2531 else if (iptr->sx.val.l == 0x10000000)
2532 iptr->sx.val.i = 28;
2533 else if (iptr->sx.val.l == 0x20000000)
2534 iptr->sx.val.i = 29;
2535 else if (iptr->sx.val.l == 0x40000000)
2536 iptr->sx.val.i = 30;
2537 else if (iptr->sx.val.l == 0x80000000)
2538 iptr->sx.val.i = 31;
2542 iptr->opc = ICMD_LMULPOW2;
2543 goto icmd_lconst_tail;
2544 # endif /* SUPPORT_LONG_SHIFT */
2545 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2546 #if SUPPORT_LONG_DIV_POW2
2548 if (iptr->sx.val.l == 0x00000002)
2550 else if (iptr->sx.val.l == 0x00000004)
2552 else if (iptr->sx.val.l == 0x00000008)
2554 else if (iptr->sx.val.l == 0x00000010)
2556 else if (iptr->sx.val.l == 0x00000020)
2558 else if (iptr->sx.val.l == 0x00000040)
2560 else if (iptr->sx.val.l == 0x00000080)
2562 else if (iptr->sx.val.l == 0x00000100)
2564 else if (iptr->sx.val.l == 0x00000200)
2566 else if (iptr->sx.val.l == 0x00000400)
2567 iptr->sx.val.i = 10;
2568 else if (iptr->sx.val.l == 0x00000800)
2569 iptr->sx.val.i = 11;
2570 else if (iptr->sx.val.l == 0x00001000)
2571 iptr->sx.val.i = 12;
2572 else if (iptr->sx.val.l == 0x00002000)
2573 iptr->sx.val.i = 13;
2574 else if (iptr->sx.val.l == 0x00004000)
2575 iptr->sx.val.i = 14;
2576 else if (iptr->sx.val.l == 0x00008000)
2577 iptr->sx.val.i = 15;
2578 else if (iptr->sx.val.l == 0x00010000)
2579 iptr->sx.val.i = 16;
2580 else if (iptr->sx.val.l == 0x00020000)
2581 iptr->sx.val.i = 17;
2582 else if (iptr->sx.val.l == 0x00040000)
2583 iptr->sx.val.i = 18;
2584 else if (iptr->sx.val.l == 0x00080000)
2585 iptr->sx.val.i = 19;
2586 else if (iptr->sx.val.l == 0x00100000)
2587 iptr->sx.val.i = 20;
2588 else if (iptr->sx.val.l == 0x00200000)
2589 iptr->sx.val.i = 21;
2590 else if (iptr->sx.val.l == 0x00400000)
2591 iptr->sx.val.i = 22;
2592 else if (iptr->sx.val.l == 0x00800000)
2593 iptr->sx.val.i = 23;
2594 else if (iptr->sx.val.l == 0x01000000)
2595 iptr->sx.val.i = 24;
2596 else if (iptr->sx.val.l == 0x02000000)
2597 iptr->sx.val.i = 25;
2598 else if (iptr->sx.val.l == 0x04000000)
2599 iptr->sx.val.i = 26;
2600 else if (iptr->sx.val.l == 0x08000000)
2601 iptr->sx.val.i = 27;
2602 else if (iptr->sx.val.l == 0x10000000)
2603 iptr->sx.val.i = 28;
2604 else if (iptr->sx.val.l == 0x20000000)
2605 iptr->sx.val.i = 29;
2606 else if (iptr->sx.val.l == 0x40000000)
2607 iptr->sx.val.i = 30;
2608 else if (iptr->sx.val.l == 0x80000000)
2609 iptr->sx.val.i = 31;
2613 iptr->opc = ICMD_LDIVPOW2;
2614 goto icmd_lconst_tail;
2615 #endif /* SUPPORT_LONG_DIV_POW2 */
2617 #if SUPPORT_LONG_REM_POW2
2619 if ((iptr->sx.val.l == 0x00000002) ||
2620 (iptr->sx.val.l == 0x00000004) ||
2621 (iptr->sx.val.l == 0x00000008) ||
2622 (iptr->sx.val.l == 0x00000010) ||
2623 (iptr->sx.val.l == 0x00000020) ||
2624 (iptr->sx.val.l == 0x00000040) ||
2625 (iptr->sx.val.l == 0x00000080) ||
2626 (iptr->sx.val.l == 0x00000100) ||
2627 (iptr->sx.val.l == 0x00000200) ||
2628 (iptr->sx.val.l == 0x00000400) ||
2629 (iptr->sx.val.l == 0x00000800) ||
2630 (iptr->sx.val.l == 0x00001000) ||
2631 (iptr->sx.val.l == 0x00002000) ||
2632 (iptr->sx.val.l == 0x00004000) ||
2633 (iptr->sx.val.l == 0x00008000) ||
2634 (iptr->sx.val.l == 0x00010000) ||
2635 (iptr->sx.val.l == 0x00020000) ||
2636 (iptr->sx.val.l == 0x00040000) ||
2637 (iptr->sx.val.l == 0x00080000) ||
2638 (iptr->sx.val.l == 0x00100000) ||
2639 (iptr->sx.val.l == 0x00200000) ||
2640 (iptr->sx.val.l == 0x00400000) ||
2641 (iptr->sx.val.l == 0x00800000) ||
2642 (iptr->sx.val.l == 0x01000000) ||
2643 (iptr->sx.val.l == 0x02000000) ||
2644 (iptr->sx.val.l == 0x04000000) ||
2645 (iptr->sx.val.l == 0x08000000) ||
2646 (iptr->sx.val.l == 0x10000000) ||
2647 (iptr->sx.val.l == 0x20000000) ||
2648 (iptr->sx.val.l == 0x40000000) ||
2649 (iptr->sx.val.l == 0x80000000))
2651 iptr->opc = ICMD_LREMPOW2;
2652 iptr->sx.val.l -= 1;
2653 goto icmd_lconst_tail;
2656 #endif /* SUPPORT_LONG_REM_POW2 */
2658 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2661 iptr->opc = ICMD_LANDCONST;
2662 goto icmd_lconst_tail;
2665 iptr->opc = ICMD_LORCONST;
2666 goto icmd_lconst_tail;
2669 iptr->opc = ICMD_LXORCONST;
2670 goto icmd_lconst_tail;
2671 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2673 #if SUPPORT_LONG_CMP_CONST
2675 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2678 /* switch on the instruction after LCONST - LCMP */
2680 switch (iptr[2].opc) {
2682 iptr->opc = ICMD_IF_LEQ;
2685 icmd_lconst_lcmp_tail:
2686 /* convert LCONST, LCMP, IFXX to IF_LXX */
2687 iptr->dst.insindex = iptr[2].dst.insindex;
2688 iptr[1].opc = ICMD_NOP;
2689 iptr[2].opc = ICMD_NOP;
2691 OP1_BRANCH(TYPE_LNG);
2693 COUNT(count_pcmd_bra);
2694 COUNT(count_pcmd_op);
2698 iptr->opc = ICMD_IF_LNE;
2699 goto icmd_lconst_lcmp_tail;
2702 iptr->opc = ICMD_IF_LLT;
2703 goto icmd_lconst_lcmp_tail;
2706 iptr->opc = ICMD_IF_LGT;
2707 goto icmd_lconst_lcmp_tail;
2710 iptr->opc = ICMD_IF_LLE;
2711 goto icmd_lconst_lcmp_tail;
2714 iptr->opc = ICMD_IF_LGE;
2715 goto icmd_lconst_lcmp_tail;
2719 } /* end switch on opcode after LCONST - LCMP */
2721 #endif /* SUPPORT_LONG_CMP_CONST */
2723 #if SUPPORT_CONST_STORE
2725 # if SUPPORT_CONST_STORE_ZERO_ONLY
2726 if (iptr->sx.val.l != 0)
2729 #if SIZEOF_VOID_P == 4
2730 /* the constant must fit into a ptrint */
2731 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2734 /* move the constant to s3 */
2735 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2737 iptr->opc = ICMD_LASTORECONST;
2738 iptr->flags.bits |= INS_FLAG_CHECK;
2739 OP2_0(TYPE_ADR, TYPE_INT);
2741 iptr[1].opc = ICMD_NOP;
2742 COUNT(count_pcmd_op);
2745 case ICMD_PUTSTATIC:
2747 # if SUPPORT_CONST_STORE_ZERO_ONLY
2748 if (iptr->sx.val.l != 0)
2751 #if SIZEOF_VOID_P == 4
2752 /* the constant must fit into a ptrint */
2753 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2756 /* XXX check field type? */
2758 /* copy the constant to s2 */
2759 /* XXX constval -> fieldconstval? */
2760 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2764 #endif /* SUPPORT_CONST_STORE */
2768 } /* end switch opcode after LCONST */
2770 /* if we get here, the LCONST has been optimized */
2774 /* the normal case of an unoptimized LCONST */
2778 /************************ END OF LCONST OPTIMIZATIONS *********************/
2781 COUNT(count_pcmd_load);
2786 COUNT(count_pcmd_load);
2790 /************************** ACONST OPTIMIZATIONS **************************/
2793 coalescing_boundary = sd.new;
2794 COUNT(count_pcmd_load);
2795 #if SUPPORT_CONST_STORE
2796 /* We can only optimize if the ACONST is resolved
2797 * and there is an instruction after it. */
2799 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2802 switch (iptr[1].opc) {
2804 /* We can only optimize for NULL values
2805 * here because otherwise a checkcast is
2807 if (iptr->sx.val.anyptr != NULL)
2810 /* copy the constant (NULL) to s3 */
2811 iptr->sx.s23.s3.constval = 0;
2812 iptr->opc = ICMD_AASTORECONST;
2813 iptr->flags.bits |= INS_FLAG_CHECK;
2814 OP2_0(TYPE_ADR, TYPE_INT);
2816 iptr[1].opc = ICMD_NOP;
2817 COUNT(count_pcmd_op);
2820 case ICMD_PUTSTATIC:
2822 # if SUPPORT_CONST_STORE_ZERO_ONLY
2823 if (iptr->sx.val.anyptr != NULL)
2826 /* XXX check field type? */
2827 /* copy the constant to s2 */
2828 /* XXX constval -> fieldconstval? */
2829 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
2837 /* if we get here the ACONST has been optimized */
2841 #endif /* SUPPORT_CONST_STORE */
2846 /* pop 0 push 1 load */
2853 COUNT(count_load_instruction);
2854 i = opcode - ICMD_ILOAD; /* type */
2856 j = iptr->s1.varindex =
2857 jd->local_map[iptr->s1.varindex * 5 + i];
2859 if (sd.var[j].type == TYPE_RET) {
2860 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
2864 #if defined(ENABLE_SSA)
2866 GET_NEW_VAR(sd, new_index, i);
2883 coalescing_boundary = sd.new;
2884 iptr->flags.bits |= INS_FLAG_CHECK;
2885 COUNT(count_check_null);
2886 COUNT(count_check_bound);
2887 COUNT(count_pcmd_mem);
2888 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
2895 coalescing_boundary = sd.new;
2896 iptr->flags.bits |= INS_FLAG_CHECK;
2897 COUNT(count_check_null);
2898 COUNT(count_check_bound);
2899 COUNT(count_pcmd_mem);
2900 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
2903 /* pop 0 push 0 iinc */
2906 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
2907 #if defined(ENABLE_SSA)
2910 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
2914 last_store_boundary[iptr->s1.varindex] = sd.new;
2917 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
2922 if ((copy->varkind == LOCALVAR) &&
2923 (copy->varnum == iptr->s1.varindex))
2925 assert(IS_LOCALVAR(copy));
2931 #if defined(ENABLE_SSA)
2935 iptr->dst.varindex = iptr->s1.varindex;
2938 /* pop 1 push 0 store */
2947 i = opcode - ICMD_ISTORE; /* type */
2948 javaindex = iptr->dst.varindex;
2949 j = iptr->dst.varindex =
2950 jd->local_map[javaindex * 5 + i];
2952 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
2954 #if defined(ENABLE_STATISTICS)
2957 i = sd.new - curstack;
2959 count_store_length[20]++;
2961 count_store_length[i]++;
2964 count_store_depth[10]++;
2966 count_store_depth[i]++;
2970 #if defined(ENABLE_SSA)
2973 /* check for conflicts as described in Figure 5.2 */
2975 copy = curstack->prev;
2978 if ((copy->varkind == LOCALVAR) &&
2979 (copy->varnum == j))
2981 copy->varkind = TEMPVAR;
2982 assert(IS_LOCALVAR(copy));
2989 /* if the variable is already coalesced, don't bother */
2991 /* We do not need to check against INOUT, as invars */
2992 /* are always before the coalescing boundary. */
2994 if (curstack->varkind == LOCALVAR)
2997 /* there is no STORE Lj while curstack is live */
2999 if (curstack < last_store_boundary[javaindex])
3000 goto assume_conflict;
3002 /* curstack must be after the coalescing boundary */
3004 if (curstack < coalescing_boundary)
3005 goto assume_conflict;
3007 /* there is no DEF LOCALVAR(j) while curstack is live */
3009 copy = sd.new; /* most recent stackslot created + 1 */
3010 while (--copy > curstack) {
3011 if (copy->varkind == LOCALVAR && copy->varnum == j)
3012 goto assume_conflict;
3015 /* coalesce the temporary variable with Lj */
3016 assert((curstack->varkind == TEMPVAR)
3017 || (curstack->varkind == UNDEFVAR));
3018 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3019 assert(!IS_INOUT(curstack));
3020 assert(!IS_PREALLOC(curstack));
3022 assert(curstack->creator);
3023 assert(curstack->creator->dst.varindex == curstack->varnum);
3024 RELEASE_INDEX(sd, curstack);
3025 curstack->varkind = LOCALVAR;
3026 curstack->varnum = j;
3027 curstack->creator->dst.varindex = j;
3030 /* revert the coalescing, if it has been done earlier */
3032 if ((curstack->varkind == LOCALVAR)
3033 && (curstack->varnum == j))
3035 assert(IS_LOCALVAR(curstack));
3036 SET_TEMPVAR(curstack);
3039 /* remember the stack boundary at this store */
3041 last_store_boundary[javaindex] = sd.new;
3042 #if defined(ENABLE_SSA)
3043 } /* if (ls != NULL) */
3046 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3049 STORE(opcode - ICMD_ISTORE, j);
3055 coalescing_boundary = sd.new;
3056 iptr->flags.bits |= INS_FLAG_CHECK;
3057 COUNT(count_check_null);
3058 COUNT(count_check_bound);
3059 COUNT(count_pcmd_mem);
3061 bte = builtintable_get_internal(BUILTIN_canstore);
3064 if (md->memuse > rd->memuse)
3065 rd->memuse = md->memuse;
3066 if (md->argintreguse > rd->argintreguse)
3067 rd->argintreguse = md->argintreguse;
3068 /* XXX non-leaf method? */
3070 /* make all stack variables saved */
3074 sd.var[copy->varnum].flags |= SAVEDVAR;
3075 /* in case copy->varnum is/will be a LOCALVAR */
3076 /* once and set back to a non LOCALVAR */
3077 /* the correct SAVEDVAR flag has to be */
3078 /* remembered in copy->flags, too */
3079 copy->flags |= SAVEDVAR;
3083 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3090 coalescing_boundary = sd.new;
3091 iptr->flags.bits |= INS_FLAG_CHECK;
3092 COUNT(count_check_null);
3093 COUNT(count_check_bound);
3094 COUNT(count_pcmd_mem);
3095 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3102 coalescing_boundary = sd.new;
3103 iptr->flags.bits |= INS_FLAG_CHECK;
3104 COUNT(count_check_null);
3105 COUNT(count_check_bound);
3106 COUNT(count_pcmd_mem);
3107 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3113 #ifdef ENABLE_VERIFIER
3116 if (IS_2_WORD_TYPE(curstack->type))
3117 goto throw_stack_category_error;
3128 coalescing_boundary = sd.new;
3129 /* Assert here that no LOCAL or INOUTS get */
3130 /* preallocated, since tha macros are not */
3131 /* available in md-abi.c! */
3132 if (IS_TEMPVAR(curstack))
3133 md_return_alloc(jd, curstack);
3134 COUNT(count_pcmd_return);
3135 OP1_0(opcode - ICMD_IRETURN);
3136 superblockend = true;
3140 coalescing_boundary = sd.new;
3141 COUNT(count_check_null);
3143 curstack = NULL; stackdepth = 0;
3144 superblockend = true;
3147 case ICMD_PUTSTATIC:
3148 coalescing_boundary = sd.new;
3149 COUNT(count_pcmd_mem);
3150 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3151 OP1_0(fmiref->parseddesc.fd->type);
3154 /* pop 1 push 0 branch */
3157 case ICMD_IFNONNULL:
3158 COUNT(count_pcmd_bra);
3159 OP1_BRANCH(TYPE_ADR);
3169 COUNT(count_pcmd_bra);
3170 /* iptr->sx.val.i is set implicitly in parse by
3171 clearing the memory or from IF_ICMPxx
3174 OP1_BRANCH(TYPE_INT);
3175 /* iptr->sx.val.i = 0; */
3179 /* pop 0 push 0 branch */
3182 COUNT(count_pcmd_bra);
3185 superblockend = true;
3188 /* pop 1 push 0 table branch */
3190 case ICMD_TABLESWITCH:
3191 COUNT(count_pcmd_table);
3192 OP1_BRANCH(TYPE_INT);
3194 table = iptr->dst.table;
3195 BRANCH_TARGET(*table, tbptr);
3198 i = iptr->sx.s23.s3.tablehigh
3199 - iptr->sx.s23.s2.tablelow + 1;
3202 BRANCH_TARGET(*table, tbptr);
3205 superblockend = true;
3208 /* pop 1 push 0 table branch */
3210 case ICMD_LOOKUPSWITCH:
3211 COUNT(count_pcmd_table);
3212 OP1_BRANCH(TYPE_INT);
3214 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3216 lookup = iptr->dst.lookup;
3218 i = iptr->sx.s23.s2.lookupcount;
3221 BRANCH_TARGET(lookup->target, tbptr);
3224 superblockend = true;
3227 case ICMD_MONITORENTER:
3228 case ICMD_MONITOREXIT:
3229 coalescing_boundary = sd.new;
3230 COUNT(count_check_null);
3234 /* pop 2 push 0 branch */
3236 case ICMD_IF_ICMPEQ:
3237 case ICMD_IF_ICMPNE:
3238 case ICMD_IF_ICMPLT:
3239 case ICMD_IF_ICMPGE:
3240 case ICMD_IF_ICMPGT:
3241 case ICMD_IF_ICMPLE:
3242 COUNT(count_pcmd_bra);
3243 OP2_BRANCH(TYPE_INT, TYPE_INT);
3247 case ICMD_IF_ACMPEQ:
3248 case ICMD_IF_ACMPNE:
3249 COUNT(count_pcmd_bra);
3250 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3257 coalescing_boundary = sd.new;
3258 COUNT(count_check_null);
3259 COUNT(count_pcmd_mem);
3260 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3261 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3266 if (!IS_2_WORD_TYPE(curstack->type)) {
3268 #ifdef ENABLE_VERIFIER
3271 if (IS_2_WORD_TYPE(curstack->prev->type))
3272 goto throw_stack_category_error;
3275 OP2_0_ANY_ANY; /* pop two slots */
3278 iptr->opc = ICMD_POP;
3279 OP1_0_ANY; /* pop one (two-word) slot */
3283 /* pop 0 push 1 dup */
3286 #ifdef ENABLE_VERIFIER
3289 if (IS_2_WORD_TYPE(curstack->type))
3290 goto throw_stack_category_error;
3293 COUNT(count_dup_instruction);
3299 coalescing_boundary = sd.new - 1;
3304 if (IS_2_WORD_TYPE(curstack->type)) {
3306 iptr->opc = ICMD_DUP;
3311 /* ..., ????, cat1 */
3312 #ifdef ENABLE_VERIFIER
3314 if (IS_2_WORD_TYPE(curstack->prev->type))
3315 goto throw_stack_category_error;
3318 src1 = curstack->prev;
3321 COPY_UP(src1); iptr++; len--;
3324 coalescing_boundary = sd.new;
3328 /* pop 2 push 3 dup */
3331 #ifdef ENABLE_VERIFIER
3334 if (IS_2_WORD_TYPE(curstack->type) ||
3335 IS_2_WORD_TYPE(curstack->prev->type))
3336 goto throw_stack_category_error;
3341 src1 = curstack->prev;
3346 /* move non-temporary sources out of the way */
3347 if (!IS_TEMPVAR(src2)) {
3348 MOVE_TO_TEMP(src2); iptr++; len--;
3351 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3353 MOVE_UP(src1); iptr++; len--;
3354 MOVE_UP(src2); iptr++; len--;
3356 COPY_DOWN(curstack, dst1);
3358 coalescing_boundary = sd.new;
3363 if (IS_2_WORD_TYPE(curstack->type)) {
3364 /* ..., ????, cat2 */
3365 #ifdef ENABLE_VERIFIER
3367 if (IS_2_WORD_TYPE(curstack->prev->type))
3368 goto throw_stack_category_error;
3371 iptr->opc = ICMD_DUP_X1;
3375 /* ..., ????, cat1 */
3376 #ifdef ENABLE_VERIFIER
3379 if (IS_2_WORD_TYPE(curstack->prev->type)
3380 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3381 goto throw_stack_category_error;
3386 src1 = curstack->prev->prev;
3387 src2 = curstack->prev;
3389 POPANY; POPANY; POPANY;
3392 /* move non-temporary sources out of the way */
3393 if (!IS_TEMPVAR(src2)) {
3394 MOVE_TO_TEMP(src2); iptr++; len--;
3396 if (!IS_TEMPVAR(src3)) {
3397 MOVE_TO_TEMP(src3); iptr++; len--;
3400 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3401 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3403 MOVE_UP(src1); iptr++; len--;
3404 MOVE_UP(src2); iptr++; len--;
3405 MOVE_UP(src3); iptr++; len--;
3407 COPY_DOWN(curstack, dst2); iptr++; len--;
3408 COPY_DOWN(curstack->prev, dst1);
3410 coalescing_boundary = sd.new;
3414 /* pop 3 push 4 dup */
3418 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3419 /* ..., cat2, ???? */
3420 #ifdef ENABLE_VERIFIER
3422 if (IS_2_WORD_TYPE(curstack->type))
3423 goto throw_stack_category_error;
3426 iptr->opc = ICMD_DUP_X1;
3430 /* ..., cat1, ???? */
3431 #ifdef ENABLE_VERIFIER
3434 if (IS_2_WORD_TYPE(curstack->type)
3435 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3436 goto throw_stack_category_error;
3440 src1 = curstack->prev->prev;
3441 src2 = curstack->prev;
3443 POPANY; POPANY; POPANY;
3446 /* move non-temporary sources out of the way */
3447 if (!IS_TEMPVAR(src2)) {
3448 MOVE_TO_TEMP(src2); iptr++; len--;
3450 if (!IS_TEMPVAR(src3)) {
3451 MOVE_TO_TEMP(src3); iptr++; len--;
3454 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3456 MOVE_UP(src1); iptr++; len--;
3457 MOVE_UP(src2); iptr++; len--;
3458 MOVE_UP(src3); iptr++; len--;
3460 COPY_DOWN(curstack, dst1);
3462 coalescing_boundary = sd.new;
3468 if (IS_2_WORD_TYPE(curstack->type)) {
3469 /* ..., ????, cat2 */
3470 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3471 /* ..., cat2, cat2 */
3472 iptr->opc = ICMD_DUP_X1;
3476 /* ..., cat1, cat2 */
3477 #ifdef ENABLE_VERIFIER
3480 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3481 goto throw_stack_category_error;
3484 iptr->opc = ICMD_DUP_X2;
3490 /* ..., ????, ????, cat1 */
3492 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3493 /* ..., cat2, ????, cat1 */
3494 #ifdef ENABLE_VERIFIER
3496 if (IS_2_WORD_TYPE(curstack->prev->type))
3497 goto throw_stack_category_error;
3500 iptr->opc = ICMD_DUP2_X1;
3504 /* ..., cat1, ????, cat1 */
3505 #ifdef ENABLE_VERIFIER
3508 if (IS_2_WORD_TYPE(curstack->prev->type)
3509 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3510 goto throw_stack_category_error;
3514 src1 = curstack->prev->prev->prev;
3515 src2 = curstack->prev->prev;
3516 src3 = curstack->prev;
3518 POPANY; POPANY; POPANY; POPANY;
3521 /* move non-temporary sources out of the way */
3522 if (!IS_TEMPVAR(src2)) {
3523 MOVE_TO_TEMP(src2); iptr++; len--;
3525 if (!IS_TEMPVAR(src3)) {
3526 MOVE_TO_TEMP(src3); iptr++; len--;
3528 if (!IS_TEMPVAR(src4)) {
3529 MOVE_TO_TEMP(src4); iptr++; len--;
3532 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3533 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3535 MOVE_UP(src1); iptr++; len--;
3536 MOVE_UP(src2); iptr++; len--;
3537 MOVE_UP(src3); iptr++; len--;
3538 MOVE_UP(src4); iptr++; len--;
3540 COPY_DOWN(curstack, dst2); iptr++; len--;
3541 COPY_DOWN(curstack->prev, dst1);
3543 coalescing_boundary = sd.new;
3547 /* pop 2 push 2 swap */
3550 #ifdef ENABLE_VERIFIER
3553 if (IS_2_WORD_TYPE(curstack->type)
3554 || IS_2_WORD_TYPE(curstack->prev->type))
3555 goto throw_stack_category_error;
3559 src1 = curstack->prev;
3564 /* move non-temporary sources out of the way */
3565 if (!IS_TEMPVAR(src1)) {
3566 MOVE_TO_TEMP(src1); iptr++; len--;
3569 MOVE_UP(src2); iptr++; len--;
3572 coalescing_boundary = sd.new;
3579 coalescing_boundary = sd.new;
3580 #if !SUPPORT_DIVISION
3581 bte = iptr->sx.s23.s3.bte;
3584 if (md->memuse > rd->memuse)
3585 rd->memuse = md->memuse;
3586 if (md->argintreguse > rd->argintreguse)
3587 rd->argintreguse = md->argintreguse;
3589 /* make all stack variables saved */
3593 sd.var[copy->varnum].flags |= SAVEDVAR;
3594 copy->flags |= SAVEDVAR;
3599 #endif /* !SUPPORT_DIVISION */
3610 COUNT(count_pcmd_op);
3611 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3616 coalescing_boundary = sd.new;
3617 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3618 bte = iptr->sx.s23.s3.bte;
3621 if (md->memuse > rd->memuse)
3622 rd->memuse = md->memuse;
3623 if (md->argintreguse > rd->argintreguse)
3624 rd->argintreguse = md->argintreguse;
3625 /* XXX non-leaf method? */
3627 /* make all stack variables saved */
3631 sd.var[copy->varnum].flags |= SAVEDVAR;
3632 copy->flags |= SAVEDVAR;
3637 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3642 #if SUPPORT_LONG_LOGICAL
3646 #endif /* SUPPORT_LONG_LOGICAL */
3647 COUNT(count_pcmd_op);
3648 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3654 COUNT(count_pcmd_op);
3655 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3663 COUNT(count_pcmd_op);
3664 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3672 COUNT(count_pcmd_op);
3673 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3677 COUNT(count_pcmd_op);
3678 #if SUPPORT_LONG_CMP_CONST
3679 if ((len == 0) || (iptr[1].sx.val.i != 0))
3682 switch (iptr[1].opc) {
3684 iptr->opc = ICMD_IF_LCMPEQ;
3686 iptr->dst.insindex = iptr[1].dst.insindex;
3687 iptr[1].opc = ICMD_NOP;
3689 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3692 COUNT(count_pcmd_bra);
3695 iptr->opc = ICMD_IF_LCMPNE;
3696 goto icmd_lcmp_if_tail;
3698 iptr->opc = ICMD_IF_LCMPLT;
3699 goto icmd_lcmp_if_tail;
3701 iptr->opc = ICMD_IF_LCMPGT;
3702 goto icmd_lcmp_if_tail;
3704 iptr->opc = ICMD_IF_LCMPLE;
3705 goto icmd_lcmp_if_tail;
3707 iptr->opc = ICMD_IF_LCMPGE;
3708 goto icmd_lcmp_if_tail;
3714 #endif /* SUPPORT_LONG_CMP_CONST */
3715 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3718 /* XXX why is this deactivated? */
3721 COUNT(count_pcmd_op);
3722 if ((len == 0) || (iptr[1].sx.val.i != 0))
3725 switch (iptr[1].opc) {
3727 iptr->opc = ICMD_IF_FCMPEQ;
3729 iptr->dst.insindex = iptr[1].dst.insindex;
3730 iptr[1].opc = ICMD_NOP;
3732 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3735 COUNT(count_pcmd_bra);
3738 iptr->opc = ICMD_IF_FCMPNE;
3739 goto icmd_if_fcmpl_tail;
3741 iptr->opc = ICMD_IF_FCMPL_LT;
3742 goto icmd_if_fcmpl_tail;
3744 iptr->opc = ICMD_IF_FCMPL_GT;
3745 goto icmd_if_fcmpl_tail;
3747 iptr->opc = ICMD_IF_FCMPL_LE;
3748 goto icmd_if_fcmpl_tail;
3750 iptr->opc = ICMD_IF_FCMPL_GE;
3751 goto icmd_if_fcmpl_tail;
3758 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3762 COUNT(count_pcmd_op);
3763 if ((len == 0) || (iptr[1].sx.val.i != 0))
3766 switch (iptr[1].opc) {
3768 iptr->opc = ICMD_IF_FCMPEQ;
3770 iptr->dst.insindex = iptr[1].dst.insindex;
3771 iptr[1].opc = ICMD_NOP;
3773 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3776 COUNT(count_pcmd_bra);
3779 iptr->opc = ICMD_IF_FCMPNE;
3780 goto icmd_if_fcmpg_tail;
3782 iptr->opc = ICMD_IF_FCMPG_LT;
3783 goto icmd_if_fcmpg_tail;
3785 iptr->opc = ICMD_IF_FCMPG_GT;
3786 goto icmd_if_fcmpg_tail;
3788 iptr->opc = ICMD_IF_FCMPG_LE;
3789 goto icmd_if_fcmpg_tail;
3791 iptr->opc = ICMD_IF_FCMPG_GE;
3792 goto icmd_if_fcmpg_tail;
3799 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3803 COUNT(count_pcmd_op);
3804 if ((len == 0) || (iptr[1].sx.val.i != 0))
3807 switch (iptr[1].opc) {
3809 iptr->opc = ICMD_IF_DCMPEQ;
3811 iptr->dst.insindex = iptr[1].dst.insindex;
3812 iptr[1].opc = ICMD_NOP;
3814 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3817 COUNT(count_pcmd_bra);
3820 iptr->opc = ICMD_IF_DCMPNE;
3821 goto icmd_if_dcmpl_tail;
3823 iptr->opc = ICMD_IF_DCMPL_LT;
3824 goto icmd_if_dcmpl_tail;
3826 iptr->opc = ICMD_IF_DCMPL_GT;
3827 goto icmd_if_dcmpl_tail;
3829 iptr->opc = ICMD_IF_DCMPL_LE;
3830 goto icmd_if_dcmpl_tail;
3832 iptr->opc = ICMD_IF_DCMPL_GE;
3833 goto icmd_if_dcmpl_tail;
3840 OPTT2_1(TYPE_DBL, TYPE_INT);
3844 COUNT(count_pcmd_op);
3845 if ((len == 0) || (iptr[1].sx.val.i != 0))
3848 switch (iptr[1].opc) {
3850 iptr->opc = ICMD_IF_DCMPEQ;
3852 iptr->dst.insindex = iptr[1].dst.insindex;
3853 iptr[1].opc = ICMD_NOP;
3855 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
3858 COUNT(count_pcmd_bra);
3861 iptr->opc = ICMD_IF_DCMPNE;
3862 goto icmd_if_dcmpg_tail;
3864 iptr->opc = ICMD_IF_DCMPG_LT;
3865 goto icmd_if_dcmpg_tail;
3867 iptr->opc = ICMD_IF_DCMPG_GT;
3868 goto icmd_if_dcmpg_tail;
3870 iptr->opc = ICMD_IF_DCMPG_LE;
3871 goto icmd_if_dcmpg_tail;
3873 iptr->opc = ICMD_IF_DCMPG_GE;
3874 goto icmd_if_dcmpg_tail;
3881 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3886 COUNT(count_pcmd_op);
3887 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3892 COUNT(count_pcmd_op);
3893 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
3902 case ICMD_INT2SHORT:
3903 COUNT(count_pcmd_op);
3904 OP1_1(TYPE_INT, TYPE_INT);
3907 COUNT(count_pcmd_op);
3908 OP1_1(TYPE_LNG, TYPE_LNG);
3911 COUNT(count_pcmd_op);
3912 OP1_1(TYPE_FLT, TYPE_FLT);
3915 COUNT(count_pcmd_op);
3916 OP1_1(TYPE_DBL, TYPE_DBL);
3920 COUNT(count_pcmd_op);
3921 OP1_1(TYPE_INT, TYPE_LNG);
3924 COUNT(count_pcmd_op);
3925 OP1_1(TYPE_INT, TYPE_FLT);
3928 COUNT(count_pcmd_op);
3929 OP1_1(TYPE_INT, TYPE_DBL);
3932 COUNT(count_pcmd_op);
3933 OP1_1(TYPE_LNG, TYPE_INT);
3936 COUNT(count_pcmd_op);
3937 OP1_1(TYPE_LNG, TYPE_FLT);
3940 COUNT(count_pcmd_op);
3941 OP1_1(TYPE_LNG, TYPE_DBL);
3944 COUNT(count_pcmd_op);
3945 OP1_1(TYPE_FLT, TYPE_INT);
3948 COUNT(count_pcmd_op);
3949 OP1_1(TYPE_FLT, TYPE_LNG);
3952 COUNT(count_pcmd_op);
3953 OP1_1(TYPE_FLT, TYPE_DBL);
3956 COUNT(count_pcmd_op);
3957 OP1_1(TYPE_DBL, TYPE_INT);
3960 COUNT(count_pcmd_op);
3961 OP1_1(TYPE_DBL, TYPE_LNG);
3964 COUNT(count_pcmd_op);
3965 OP1_1(TYPE_DBL, TYPE_FLT);
3968 case ICMD_CHECKCAST:
3969 coalescing_boundary = sd.new;
3970 if (iptr->flags.bits & INS_FLAG_ARRAY) {
3971 /* array type cast-check */
3973 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
3976 if (md->memuse > rd->memuse)
3977 rd->memuse = md->memuse;
3978 if (md->argintreguse > rd->argintreguse)
3979 rd->argintreguse = md->argintreguse;
3981 /* make all stack variables saved */
3985 sd.var[copy->varnum].flags |= SAVEDVAR;
3986 copy->flags |= SAVEDVAR;
3990 OP1_1(TYPE_ADR, TYPE_ADR);
3993 case ICMD_INSTANCEOF:
3994 case ICMD_ARRAYLENGTH:
3995 coalescing_boundary = sd.new;
3996 OP1_1(TYPE_ADR, TYPE_INT);
4000 case ICMD_ANEWARRAY:
4001 coalescing_boundary = sd.new;
4002 OP1_1(TYPE_INT, TYPE_ADR);
4006 coalescing_boundary = sd.new;
4007 COUNT(count_check_null);
4008 COUNT(count_pcmd_mem);
4009 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4010 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4015 case ICMD_GETSTATIC:
4016 coalescing_boundary = sd.new;
4017 COUNT(count_pcmd_mem);
4018 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4019 OP0_1(fmiref->parseddesc.fd->type);
4023 coalescing_boundary = sd.new;
4030 assert(sd.bptr->next); /* XXX exception */
4031 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4033 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4034 tbptr->type = BBTYPE_SBR;
4036 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4040 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4042 /* We need to check for overflow right here because
4043 * the pushed value is poped afterwards */
4046 superblockend = true;
4047 /* XXX should not be marked as interface, as it does not need to be */
4048 /* allocated. Same for the invar of the target. */
4051 /* pop many push any */
4055 bte = iptr->sx.s23.s3.bte;
4059 case ICMD_INVOKESTATIC:
4060 case ICMD_INVOKESPECIAL:
4061 case ICMD_INVOKEVIRTUAL:
4062 case ICMD_INVOKEINTERFACE:
4063 COUNT(count_pcmd_met);
4065 /* Check for functions to replace with builtin
4068 if (builtintable_replace_function(iptr))
4071 INSTRUCTION_GET_METHODDESC(iptr, md);
4072 /* XXX resurrect this COUNT? */
4073 /* if (lm->flags & ACC_STATIC) */
4074 /* {COUNT(count_check_null);} */
4078 coalescing_boundary = sd.new;
4082 if (md->memuse > rd->memuse)
4083 rd->memuse = md->memuse;
4084 if (md->argintreguse > rd->argintreguse)
4085 rd->argintreguse = md->argintreguse;
4086 if (md->argfltreguse > rd->argfltreguse)
4087 rd->argfltreguse = md->argfltreguse;
4091 /* XXX optimize for <= 2 args */
4092 /* XXX not for ICMD_BUILTIN */
4093 iptr->s1.argcount = stackdepth;
4094 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4097 for (i-- ; i >= 0; i--) {
4098 iptr->sx.s23.s2.args[i] = copy->varnum;
4100 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4101 /* -> won't help anyway */
4102 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4104 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4105 /* If we pass float arguments in integer argument registers, we
4106 * are not allowed to precolor them here. Floats have to be moved
4107 * to this regs explicitly in codegen().
4108 * Only arguments that are passed by stack anyway can be precolored
4109 * (michi 2005/07/24) */
4110 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4111 (!IS_FLT_DBL_TYPE(copy->type)
4112 || md->params[i].inmemory)) {
4114 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4119 if (md->params[i].inmemory) {
4120 sd.var[copy->varnum].vv.regoff =
4121 md->params[i].regoff;
4122 sd.var[copy->varnum].flags |=
4126 if (IS_FLT_DBL_TYPE(copy->type)) {
4127 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4128 assert(0); /* XXX is this assert ok? */
4130 sd.var[copy->varnum].vv.regoff =
4131 rd->argfltregs[md->params[i].regoff];
4132 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4135 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4136 if (IS_2_WORD_TYPE(copy->type))
4137 sd.var[copy->varnum].vv.regoff =
4138 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4139 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4142 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4143 sd.var[copy->varnum].vv.regoff =
4144 rd->argintregs[md->params[i].regoff];
4152 /* deal with live-through stack slots "under" the */
4154 /* XXX not for ICMD_BUILTIN */
4160 iptr->sx.s23.s2.args[i++] = copy->varnum;
4161 sd.var[copy->varnum].flags |= SAVEDVAR;
4162 copy->flags |= SAVEDVAR;
4166 /* pop the arguments */
4175 /* push the return value */
4177 if (md->returntype.type != TYPE_VOID) {
4178 GET_NEW_VAR(sd, new_index, md->returntype.type);
4179 DST(md->returntype.type, new_index);
4184 case ICMD_INLINE_START:
4185 case ICMD_INLINE_END:
4190 case ICMD_MULTIANEWARRAY:
4191 coalescing_boundary = sd.new;
4192 if (rd->argintreguse < 3)
4193 rd->argintreguse = 3;
4195 i = iptr->s1.argcount;
4199 iptr->sx.s23.s2.args = DMNEW(s4, i);
4201 #if defined(SPECIALMEMUSE)
4202 # if defined(__DARWIN__)
4203 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4204 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4206 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4207 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4210 # if defined(__I386__)
4211 if (rd->memuse < i + 3)
4212 rd->memuse = i + 3; /* n integer args spilled on stack */
4213 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4214 if (rd->memuse < i + 2)
4215 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4218 rd->memuse = i; /* n integer args spilled on stack */
4219 # endif /* defined(__I386__) */
4223 /* check INT type here? Currently typecheck does this. */
4224 iptr->sx.s23.s2.args[i] = copy->varnum;
4225 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4226 && (!IS_INOUT(copy))
4227 && (!IS_LOCALVAR(copy)) ) {
4228 copy->varkind = ARGVAR;
4229 sd.var[copy->varnum].flags |=
4230 INMEMORY & PREALLOC;
4231 #if defined(SPECIALMEMUSE)
4232 # if defined(__DARWIN__)
4233 sd.var[copy->varnum].vv.regoff = i +
4234 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4236 sd.var[copy->varnum].vv.regoff = i +
4237 LA_SIZE_IN_POINTERS + 3;
4240 # if defined(__I386__)
4241 sd.var[copy->varnum].vv.regoff = i + 3;
4242 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4243 sd.var[copy->varnum].vv.regoff = i + 2;
4245 sd.var[copy->varnum].vv.regoff = i;
4246 # endif /* defined(__I386__) */
4247 #endif /* defined(SPECIALMEMUSE) */
4252 sd.var[copy->varnum].flags |= SAVEDVAR;
4253 copy->flags |= SAVEDVAR;
4257 i = iptr->s1.argcount;
4262 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4263 DST(TYPE_ADR, new_index);
4269 new_internalerror("Unknown ICMD %d", opcode);
4275 } /* while instructions */
4277 /* stack slots at basic block end become interfaces */
4279 sd.bptr->outdepth = stackdepth;
4280 sd.bptr->outvars = DMNEW(s4, stackdepth);
4283 for (copy = curstack; copy; i--, copy = copy->prev) {
4287 /* with the new vars rd->interfaces will be removed */
4288 /* and all in and outvars have to be STACKVARS! */
4289 /* in the moment i.e. SWAP with in and out vars can */
4290 /* create an unresolvable conflict */
4297 v = sd.var + copy->varnum;
4300 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4301 /* no interface var until now for this depth and */
4303 jd->interface_map[i*5 + t].flags = v->flags;
4306 jd->interface_map[i*5 + t].flags |= v->flags;
4309 sd.bptr->outvars[i] = copy->varnum;
4312 /* check if interface slots at basic block begin must be saved */
4314 for (i=0; i<sd.bptr->indepth; ++i) {
4315 varinfo *v = sd.var + sd.bptr->invars[i];
4322 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4323 /* no interface var until now for this depth and */
4325 jd->interface_map[i*5 + t].flags = v->flags;
4328 jd->interface_map[i*5 + t].flags |= v->flags;
4332 /* store the number of this block's variables */
4334 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4336 #if defined(STACK_VERBOSE)
4337 stack_verbose_block_exit(&sd, superblockend);
4340 /* reach the following block, if any */
4343 if (!stack_reach_next_block(&sd))
4348 } while (sd.repeat && !deadcode);
4350 /* XXX reset TYPE_RET to TYPE_ADR */
4352 for (i=0; i<sd.vartop; ++i) {
4353 if (sd.var[i].type == TYPE_RET)
4354 sd.var[i].type = TYPE_ADR;
4357 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4359 ex = cd->exceptiontable;
4360 for (; ex != NULL; ex = ex->down) {
4361 if (ex->start == ex->end) {
4362 assert(ex->end->next);
4363 ex->end = ex->end->next;
4367 /* gather statistics *****************************************************/
4369 #if defined(ENABLE_STATISTICS)
4371 if (jd->basicblockcount > count_max_basic_blocks)
4372 count_max_basic_blocks = jd->basicblockcount;
4373 count_basic_blocks += jd->basicblockcount;
4374 if (jd->instructioncount > count_max_javainstr)
4375 count_max_javainstr = jd->instructioncount;
4376 count_javainstr += jd->instructioncount;
4377 if (jd->stackcount > count_upper_bound_new_stack)
4378 count_upper_bound_new_stack = jd->stackcount;
4379 if ((sd.new - jd->stack) > count_max_new_stack)
4380 count_max_new_stack = (sd.new - jd->stack);
4382 sd.bptr = jd->basicblocks;
4383 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4384 if (sd.bptr->flags > BBREACHED) {
4385 if (sd.bptr->indepth >= 10)
4386 count_block_stack[10]++;
4388 count_block_stack[sd.bptr->indepth]++;
4389 len = sd.bptr->icount;
4391 count_block_size_distribution[len]++;
4393 count_block_size_distribution[10]++;
4395 count_block_size_distribution[11]++;
4397 count_block_size_distribution[12]++;
4399 count_block_size_distribution[13]++;
4401 count_block_size_distribution[14]++;
4403 count_block_size_distribution[15]++;
4405 count_block_size_distribution[16]++;
4407 count_block_size_distribution[17]++;
4411 if (iteration_count == 1)
4412 count_analyse_iterations[0]++;
4413 else if (iteration_count == 2)
4414 count_analyse_iterations[1]++;
4415 else if (iteration_count == 3)
4416 count_analyse_iterations[2]++;
4417 else if (iteration_count == 4)
4418 count_analyse_iterations[3]++;
4420 count_analyse_iterations[4]++;
4422 if (jd->basicblockcount <= 5)
4423 count_method_bb_distribution[0]++;
4424 else if (jd->basicblockcount <= 10)
4425 count_method_bb_distribution[1]++;
4426 else if (jd->basicblockcount <= 15)
4427 count_method_bb_distribution[2]++;
4428 else if (jd->basicblockcount <= 20)
4429 count_method_bb_distribution[3]++;
4430 else if (jd->basicblockcount <= 30)
4431 count_method_bb_distribution[4]++;
4432 else if (jd->basicblockcount <= 40)
4433 count_method_bb_distribution[5]++;
4434 else if (jd->basicblockcount <= 50)
4435 count_method_bb_distribution[6]++;
4436 else if (jd->basicblockcount <= 75)
4437 count_method_bb_distribution[7]++;
4439 count_method_bb_distribution[8]++;
4441 #endif /* defined(ENABLE_STATISTICS) */
4443 /* everything's ok *******************************************************/
4447 /* goto labels for throwing verifier exceptions **************************/
4449 #if defined(ENABLE_VERIFIER)
4451 throw_stack_underflow:
4452 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4455 throw_stack_overflow:
4456 exceptions_throw_verifyerror(m, "Stack size too large");
4459 throw_stack_type_error:
4460 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4463 throw_stack_category_error:
4464 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4471 /* functions for verbose stack analysis output ********************************/
4473 #if defined(STACK_VERBOSE)
4474 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4476 printf("%c", show_jit_type_letters[v->type]);
4477 if (v->type == TYPE_RET)
4478 printf("{L%03d}", v->vv.retaddr->nr);
4482 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4484 assert(index >= 0 && index < sd->vartop);
4485 stack_verbose_show_varinfo(sd, sd->var + index);
4489 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4493 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4495 for (i=0; i<bptr->indepth; ++i) {
4498 stack_verbose_show_variable(sd, bptr->invars[i]);
4503 printf("] inlocals [");
4504 if (bptr->inlocals) {
4505 for (i=0; i<sd->localcount; ++i) {
4508 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4513 printf("] out:%d [", bptr->outdepth);
4514 if (bptr->outvars) {
4515 for (i=0; i<bptr->outdepth; ++i) {
4518 stack_verbose_show_variable(sd, bptr->outvars[i]);
4526 printf(" (clone of L%03d)", bptr->original->nr);
4528 basicblock *b = bptr->copied_to;
4530 printf(" (copied to ");
4531 for (; b; b = b->copied_to)
4532 printf("L%03d ", b->nr);
4539 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4543 printf("======================================== STACK %sANALYSE BLOCK ",
4544 (reanalyse) ? "RE-" : "");
4545 stack_verbose_show_block(sd, sd->bptr);
4548 if (sd->handlers[0]) {
4549 printf("HANDLERS: ");
4550 for (i=0; sd->handlers[i]; ++i) {
4551 printf("L%03d ", sd->handlers[i]->handler->nr);
4559 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4561 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4562 stack_verbose_show_block(sd, sd->bptr);
4569 * These are local overrides for various environment variables in Emacs.
4570 * Please do not remove this and leave it at the end of the file, where
4571 * Emacs will automagically detect them.
4572 * ---------------------------------------------------------------------
4575 * indent-tabs-mode: t
4579 * vim:noexpandtab:sw=4:ts=4: