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
32 $Id: stack.c 6023 2006-11-19 15:22:53Z edwin $
47 #include "mm/memory.h"
49 #include "native/native.h"
51 #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"
61 #include "vm/jit/abi.h"
62 #include "vm/jit/cfg.h"
63 #include "vm/jit/codegen-common.h"
64 #include "vm/jit/parse.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)
101 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
104 /* For returnAddresses we use a field of the typeinfo to store from which */
105 /* subroutine the returnAddress will return, if used. */
106 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
107 /* to need it initialised to NULL. This should be investigated. */
109 #if defined(ENABLE_VERIFIER)
110 #define SBRSTART typeinfo.elementclass.any
114 /* stackdata_t *****************************************************************
116 This struct holds internal data during stack analysis.
118 *******************************************************************************/
120 typedef struct stackdata_t stackdata_t;
123 basicblock *bptr; /* the current basic block being analysed */
124 stackptr new; /* next free stackelement */
125 s4 vartop; /* next free variable index */
126 s4 localcount; /* number of locals (at the start of var) */
127 s4 varcount; /* maximum number of variables expected */
128 s4 varsallocated; /* total number of variables allocated */
129 s4 maxlocals; /* max. number of Java locals */
130 varinfo *var; /* variable array (same as jd->var) */
131 s4 *javalocals; /* map from Java locals to jd->var indices */
132 methodinfo *m; /* the method being analysed */
133 jitdata *jd; /* current jitdata */
134 basicblock *last_real_block; /* the last block before the empty one */
135 bool repeat; /* if true, iterate the analysis again */
136 exception_entry **handlers; /* exception handlers for the current block */
137 exception_entry *extableend; /* points to the last exception entry */
138 stackelement exstack; /* instack for exception handlers */
142 /* macros for allocating/releasing variable indices *****************/
144 #define GET_NEW_INDEX(sd, new_varindex) \
146 assert((sd).vartop < (sd).varcount); \
147 (new_varindex) = ((sd).vartop)++; \
150 /* Not implemented now - could be used to reuse varindices. */
151 /* Pay attention to not release a localvar once implementing it! */
152 #define RELEASE_INDEX(sd, varindex)
154 #define GET_NEW_VAR(sd, newvarindex, newtype) \
156 GET_NEW_INDEX((sd), (newvarindex)); \
157 (sd).var[newvarindex].type = (newtype); \
161 /* macros for querying variable properties **************************/
163 #define IS_INOUT(sp) \
164 (sd.var[(sp)->varnum].flags & INOUT)
166 #define IS_PREALLOC(sp) \
167 (sd.var[(sp)->varnum].flags & PREALLOC)
169 #define IS_TEMPVAR(sp) \
170 ( ((sp)->varnum >= sd.localcount) \
171 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
174 #define IS_LOCALVAR_SD(sd, sp) \
175 ((sp)->varnum < (sd).localcount)
177 #define IS_LOCALVAR(sp) \
178 IS_LOCALVAR_SD(sd, (sp))
181 /* macros for setting variable properties ****************************/
183 #define SET_TEMPVAR(sp) \
185 if (IS_LOCALVAR((sp))) { \
186 stack_change_to_tempvar(&sd, (sp), iptr); \
188 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
191 #define SET_PREALLOC(sp) \
193 assert(!IS_LOCALVAR((sp))); \
194 sd.var[(sp)->varnum].flags |= PREALLOC; \
198 /* macros for source operands ***************************************/
201 (iptr->s1.varindex = -1)
203 #define USE_S1(type1) \
206 CHECK_BASIC_TYPE(type1, curstack->type); \
207 iptr->s1.varindex = curstack->varnum; \
213 iptr->s1.varindex = curstack->varnum; \
216 #define USE_S1_S2(type1, type2) \
219 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
220 CHECK_BASIC_TYPE(type2, curstack->type); \
221 iptr->sx.s23.s2.varindex = curstack->varnum; \
222 iptr->s1.varindex = curstack->prev->varnum; \
225 #define USE_S1_S2_ANY_ANY \
228 iptr->sx.s23.s2.varindex = curstack->varnum; \
229 iptr->s1.varindex = curstack->prev->varnum; \
232 #define USE_S1_S2_S3(type1, type2, type3) \
235 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
236 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
237 CHECK_BASIC_TYPE(type3, curstack->type); \
238 iptr->sx.s23.s3.varindex = curstack->varnum; \
239 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
240 iptr->s1.varindex = curstack->prev->prev->varnum; \
243 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
246 if (curstack->varkind == UNDEFVAR) \
247 curstack->varkind = TEMPVAR; \
248 curstack = curstack->prev; \
251 #define POP_S1(type1) \
254 if (curstack->varkind == UNDEFVAR) \
255 curstack->varkind = TEMPVAR; \
256 curstack = curstack->prev; \
262 if (curstack->varkind == UNDEFVAR) \
263 curstack->varkind = TEMPVAR; \
264 curstack = curstack->prev; \
267 #define POP_S1_S2(type1, type2) \
269 USE_S1_S2(type1, type2); \
270 if (curstack->varkind == UNDEFVAR) \
271 curstack->varkind = TEMPVAR; \
272 if (curstack->prev->varkind == UNDEFVAR) \
273 curstack->prev->varkind = TEMPVAR; \
274 curstack = curstack->prev->prev; \
277 #define POP_S1_S2_ANY_ANY \
280 if (curstack->varkind == UNDEFVAR) \
281 curstack->varkind = TEMPVAR; \
282 if (curstack->prev->varkind == UNDEFVAR) \
283 curstack->prev->varkind = TEMPVAR; \
284 curstack = curstack->prev->prev; \
287 #define POP_S1_S2_S3(type1, type2, type3) \
289 USE_S1_S2_S3(type1, type2, type3); \
290 if (curstack->varkind == UNDEFVAR) \
291 curstack->varkind = TEMPVAR; \
292 if (curstack->prev->varkind == UNDEFVAR) \
293 curstack->prev->varkind = TEMPVAR; \
294 if (curstack->prev->prev->varkind == UNDEFVAR) \
295 curstack->prev->prev->varkind = TEMPVAR; \
296 curstack = curstack->prev->prev->prev; \
303 /* macros for setting the destination operand ***********************/
306 (iptr->dst.varindex = -1)
308 #define DST(typed, index) \
310 NEWSTACKn((typed),(index)); \
311 curstack->creator = iptr; \
312 iptr->dst.varindex = (index); \
315 #define DST_LOCALVAR(typed, index) \
317 NEWSTACK((typed), LOCALVAR, (index)); \
318 curstack->creator = iptr; \
319 iptr->dst.varindex = (index); \
323 /* macro for propagating constant values ****************************/
325 #if defined(ENABLE_VERIFIER)
326 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
328 if (((dv)->type = (sv)->type) == TYPE_RET) { \
329 (dv)->vv = (sv)->vv; \
330 (dv)->SBRSTART = (sv)->SBRSTART; \
334 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
336 (dv)->type = (sv)->type; \
337 if (((dv)->type = (sv)->type) == TYPE_RET) { \
338 (dv)->vv = (sv)->vv; \
343 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
344 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
347 /* stack modelling macros *******************************************/
349 #define OP0_1(typed) \
352 GET_NEW_VAR(sd, new_index, (typed)); \
353 DST((typed), new_index); \
364 #define OP1_BRANCH(type1) \
370 #define OP1_1(type1, typed) \
373 GET_NEW_VAR(sd, new_index, (typed)); \
374 DST(typed, new_index); \
377 #define OP2_1(type1, type2, typed) \
379 POP_S1_S2(type1, type2); \
380 GET_NEW_VAR(sd, new_index, (typed)); \
381 DST(typed, new_index); \
396 #define OP1_0(type1) \
403 #define OP2_0(type1, type2) \
405 POP_S1_S2(type1, type2); \
410 #define OP2_BRANCH(type1, type2) \
412 POP_S1_S2(type1, type2); \
416 #define OP2_0_ANY_ANY \
423 #define OP3_0(type1, type2, type3) \
425 POP_S1_S2_S3(type1, type2, type3); \
430 #define LOAD(type1, index) \
432 DST_LOCALVAR(type1, index); \
436 #define STORE(type1, index) \
443 /* macros for DUP elimination ***************************************/
445 /* XXX replace NEW_VAR with NEW_INDEX */
446 #define DUP_SLOT(sp) \
448 GET_NEW_VAR(sd, new_index, (sp)->type); \
449 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
450 NEWSTACK((sp)->type, TEMPVAR, new_index); \
453 /* does not check input stackdepth */
454 #define MOVE_UP(sp) \
456 iptr->opc = ICMD_MOVE; \
457 iptr->s1.varindex = (sp)->varnum; \
459 curstack->creator = iptr; \
460 iptr->dst.varindex = curstack->varnum; \
464 /* does not check input stackdepth */
465 #define COPY_UP(sp) \
468 iptr->opc = ICMD_COPY; \
469 iptr->s1.varindex = (sp)->varnum; \
471 curstack->creator = iptr; \
472 iptr->dst.varindex = curstack->varnum; \
476 #define COPY_DOWN(s, d) \
479 iptr->opc = ICMD_COPY; \
480 iptr->s1.varindex = (s)->varnum; \
481 iptr->dst.varindex = (d)->varnum; \
482 (d)->creator = iptr; \
485 #define MOVE_TO_TEMP(sp) \
487 GET_NEW_INDEX(sd, new_index); \
488 iptr->opc = ICMD_MOVE; \
489 iptr->s1.varindex = (sp)->varnum; \
490 iptr->dst.varindex = new_index; \
491 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
492 (sp)->varnum = new_index; \
493 (sp)->varkind = TEMPVAR; \
496 /* macros for branching / reaching basic blocks *********************/
498 #define BRANCH_TARGET(bt, tempbptr) \
500 tempbptr = BLOCK_OF((bt).insindex); \
501 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
503 if (tempbptr == NULL) \
505 (bt).block = tempbptr; \
508 #define BRANCH(tempbptr) \
509 BRANCH_TARGET(iptr->dst, tempbptr)
512 /* forward declarations *******************************************************/
514 static void stack_create_invars(stackdata_t *sd, basicblock *b,
515 stackptr curstack, int stackdepth);
516 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
518 #if defined(STACK_VERBOSE)
519 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
520 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
521 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
522 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
523 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
524 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr,
529 /* stack_init ******************************************************************
531 Initialized the stack analysis subsystem (called by jit_init).
533 *******************************************************************************/
535 bool stack_init(void)
541 /* stack_grow_variable_array ***************************************************
543 Grow the variable array so the given number of additional variables fits in.
544 The number is added to `varcount`, which is the maximum number of variables
545 we expect to need at this point. The actual number of variables
546 (`varsallocated`) may be larger than that, in order to avoid too many
550 sd...........stack analysis data
551 num..........number of additional variables
553 *******************************************************************************/
555 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
561 if (sd->varcount + num > sd->varsallocated) {
562 newsize = 2*sd->varsallocated + num;
564 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
565 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
566 sd->varsallocated = newsize;
567 sd->jd->var = sd->var;
571 sd->jd->varcount += num;
573 assert(sd->varcount <= sd->varsallocated);
577 /* stack_append_block **********************************************************
579 Append the given block after the last real block of the method (before
580 the pseudo-block at the end).
583 sd...........stack analysis data
584 b............the block to append
586 *******************************************************************************/
588 static void stack_append_block(stackdata_t *sd, basicblock *b)
590 #if defined(STACK_VERBOSE)
591 printf("APPENDING BLOCK L%0d\n", b->nr);
594 b->next = sd->last_real_block->next;
595 sd->last_real_block->next = b;
596 sd->last_real_block = b;
597 b->nr = sd->jd->basicblockcount++;
598 b->next->nr = b->nr + 1;
602 /* stack_clone_block ***********************************************************
604 Create a copy of the given block and insert it at the end of the method.
606 CAUTION: This function does not copy the any variables or the instruction
607 list. It _does_, however, reserve space for the block's invars in the
611 sd...........stack analysis data
612 b............the block to clone
615 a pointer to the copy
617 *******************************************************************************/
619 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
623 clone = DNEW(basicblock);
626 clone->iinstr = NULL;
627 clone->inlocals = NULL;
628 clone->javalocals = NULL;
629 clone->invars = NULL;
631 clone->original = (b->original) ? b->original : b;
632 clone->copied_to = clone->original->copied_to;
633 clone->original->copied_to = clone;
635 clone->flags = BBREACHED;
637 stack_append_block(sd, clone);
639 /* reserve space for the invars of the clone */
641 stack_grow_variable_array(sd, b->indepth);
643 #if defined(STACK_VERBOSE)
644 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
651 /* stack_create_locals *********************************************************
653 Create the local variables for the start of the given basic block.
656 sd...........stack analysis data
657 b............block to create the locals for
659 *******************************************************************************/
661 static void stack_create_locals(stackdata_t *sd, basicblock *b)
667 /* copy the current state of the local variables */
668 /* (one extra local is needed by the verifier) */
670 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
672 for (i=0; i<sd->localcount; ++i)
675 /* the current map from java locals to cacao variables */
677 jl = DMNEW(s4, sd->maxlocals);
679 MCOPY(jl, sd->javalocals, s4, sd->maxlocals);
683 /* stack_merge_locals **********************************************************
685 Merge local variables at the beginning of the given basic block.
688 sd...........stack analysis data
689 b............the block that is reached
691 *******************************************************************************/
693 static void stack_merge_locals(stackdata_t *sd, basicblock *b)
699 /* If a javalocal is mapped to different cacao locals along the */
700 /* incoming control-flow edges, it becomes undefined. */
702 for (i=0; i<sd->maxlocals; ++i) {
703 if (b->javalocals[i] != UNUSED && b->javalocals[i] != sd->javalocals[i]) {
704 b->javalocals[i] = UNUSED;
705 if (b->flags >= BBFINISHED)
706 b->flags = BBTYPECHECK_REACHED;
707 if (b->nr <= sd->bptr->nr)
712 #if defined(ENABLE_VERIFIER)
714 for (i=0; i<sd->localcount; ++i) {
715 dv = b->inlocals + i;
717 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
718 && (sv->SBRSTART != dv->SBRSTART))
720 dv->type = TYPE_VOID;
721 if (b->flags >= BBFINISHED)
722 b->flags = BBTYPECHECK_REACHED;
723 sd->repeat = true; /* This is very rare, so just repeat */
727 #endif /* defined(ENABLE_VERIFIER) */
731 /* stack_create_invars *********************************************************
733 Create the invars for the given basic block. Also make a copy of the locals.
736 sd...........stack analysis data
737 b............block to create the invars for
738 curstack.....current stack top
739 stackdepth...current stack depth
741 This function creates STACKDEPTH invars and sets their types to the
742 types to the types of the corresponding slot in the current stack.
744 *******************************************************************************/
746 static void stack_create_invars(stackdata_t *sd, basicblock *b,
747 stackptr curstack, int stackdepth)
755 assert(sd->vartop + stackdepth <= sd->varcount);
757 b->indepth = stackdepth;
758 b->invars = DMNEW(s4, stackdepth);
760 /* allocate the variable indices */
761 index = (sd->vartop += stackdepth);
764 for (sp = curstack; i--; sp = sp->prev) {
765 b->invars[i] = --index;
766 dv = sd->var + index;
767 sv = sd->var + sp->varnum;
769 COPY_VAL_AND_TYPE_VAR(sv, dv);
772 stack_create_locals(sd, b);
776 /* stack_create_invars_from_outvars ********************************************
778 Create the invars for the given basic block. Also make a copy of the locals.
779 Types are propagated from the outvars of the current block.
782 sd...........stack analysis data
783 b............block to create the invars for
785 *******************************************************************************/
787 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
793 n = sd->bptr->outdepth;
794 assert(sd->vartop + n <= sd->varcount);
797 b->invars = DMNEW(s4, n);
800 dv = sd->var + sd->vartop;
802 /* allocate the invars */
804 for (i=0; i<n; ++i, ++dv) {
805 sv = sd->var + sd->bptr->outvars[i];
806 b->invars[i] = sd->vartop++;
808 COPY_VAL_AND_TYPE_VAR(sv, dv);
812 stack_create_locals(sd, b);
816 /* stack_check_invars **********************************************************
818 Check the current stack against the invars of the given basic block.
819 Depth and types must match.
822 sd...........stack analysis data
823 b............block which invars to check against
824 curstack.....current stack top
825 stackdepth...current stack depth
829 NULL.........a VerifyError has been thrown
831 *******************************************************************************/
833 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
834 stackptr curstack, int stackdepth)
843 #if defined(STACK_VERBOSE)
844 printf("stack_check_invars(L%03d)\n", b->nr);
847 /* find original of b */
852 #if defined(STACK_VERBOSE)
853 printf("original is L%03d\n", orig->nr);
858 #if defined(ENABLE_VERIFIER)
859 if (i != stackdepth) {
860 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
868 #if defined(STACK_VERBOSE)
869 printf("checking against ");
870 stack_verbose_show_block(sd, b); printf("\n");
874 for (i = orig->indepth; i--; sp = sp->prev) {
875 dv = sd->var + b->invars[i];
876 sv = sd->var + sp->varnum;
878 #if defined(ENABLE_VERIFIER)
879 if (dv->type != sp->type) {
880 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
885 if (sp->type == TYPE_RET) {
886 #if defined(ENABLE_VERIFIER)
887 if (dv->SBRSTART != sv->SBRSTART) {
888 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
892 if (dv->vv.retaddr != sv->vv.retaddr) {
894 /* don't break! have to check the remaining stackslots */
900 for (i=0; i<sd->localcount; ++i) {
901 dv = b->inlocals + i;
903 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
905 #if defined(ENABLE_VERIFIER)
906 (sv->SBRSTART == dv->SBRSTART) &&
908 (sv->vv.retaddr != dv->vv.retaddr))
918 /* XXX cascading collapse? */
920 stack_merge_locals(sd, b);
922 #if defined(STACK_VERBOSE)
923 printf("------> using L%03d\n", b->nr);
927 } while ((b = b->copied_to) != NULL);
929 b = stack_clone_block(sd, orig);
933 stack_create_invars(sd, b, curstack, stackdepth);
938 /* stack_check_invars_from_outvars *********************************************
940 Check the outvars of the current block against the invars of the given block.
941 Depth and types must match.
944 sd...........stack analysis data
945 b............block which invars to check against
949 NULL.........a VerifyError has been thrown
951 *******************************************************************************/
953 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
961 #if defined(STACK_VERBOSE)
962 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
965 /* find original of b */
970 #if defined(STACK_VERBOSE)
971 printf("original is L%03d\n", orig->nr);
975 n = sd->bptr->outdepth;
977 #if defined(ENABLE_VERIFIER)
979 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
987 #if defined(STACK_VERBOSE)
988 printf("checking against ");
989 stack_verbose_show_block(sd, b); printf("\n");
993 dv = sd->var + b->invars[0];
995 for (i=0; i<n; ++i, ++dv) {
996 sv = sd->var + sd->bptr->outvars[i];
998 #if defined(ENABLE_VERIFIER)
999 if (sv->type != dv->type) {
1000 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
1005 if (dv->type == TYPE_RET) {
1006 #if defined(ENABLE_VERIFIER)
1007 if (sv->SBRSTART != dv->SBRSTART) {
1008 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
1012 if (sv->vv.retaddr != dv->vv.retaddr) {
1014 /* don't break! have to check the remaining stackslots */
1021 for (i=0; i<sd->localcount; ++i) {
1022 dv = b->inlocals + i;
1025 #if defined(ENABLE_VERIFIER)
1026 (sv->SBRSTART == dv->SBRSTART) &&
1028 (sv->type == TYPE_RET && dv->type == TYPE_RET))
1030 if (sv->vv.retaddr != dv->vv.retaddr) {
1039 /* XXX cascading collapse? */
1041 stack_merge_locals(sd, b);
1043 #if defined(STACK_VERBOSE)
1044 printf("------> using L%03d\n", b->nr);
1048 } while ((b = b->copied_to) != NULL);
1050 b = stack_clone_block(sd, orig);
1054 stack_create_invars_from_outvars(sd, b);
1059 /* stack_create_instack ********************************************************
1061 Create the instack of the current basic block.
1064 sd...........stack analysis data
1067 the current stack top at the start of the basic block.
1069 *******************************************************************************/
1071 static stackptr stack_create_instack(stackdata_t *sd)
1077 if ((depth = sd->bptr->indepth) == 0)
1080 sp = (sd->new += depth);
1084 index = sd->bptr->invars[depth];
1086 sp->type = sd->var[index].type;
1090 sp->varkind = STACKVAR;
1094 /* return the top of the created stack */
1099 /* stack_mark_reached **********************************************************
1101 Mark the given block reached and propagate the current stack and locals to
1102 it. This function specializes the target block, if necessary, and returns
1103 a pointer to the specialized target.
1106 sd...........stack analysis data
1107 b............the block to reach
1108 curstack.....the current stack top
1109 stackdepth...the current stack depth
1112 a pointer to (a specialized version of) the target
1113 NULL.........a VerifyError has been thrown
1115 *******************************************************************************/
1117 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1119 #if defined(STACK_VERBOSE)
1120 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1122 /* mark targets of backward branches */
1123 if (b->nr <= sd->bptr->nr)
1124 b->bitflags |= BBFLAG_REPLACEMENT;
1126 if (b->flags < BBREACHED) {
1127 /* b is reached for the first time. Create its invars. */
1129 #if defined(STACK_VERBOSE)
1130 printf("reached L%03d for the first time\n", b->nr);
1133 stack_create_invars(sd, b, curstack, stackdepth);
1135 b->flags = BBREACHED;
1140 /* b has been reached before. Check that its invars match. */
1142 return stack_check_invars(sd, b, curstack, stackdepth);
1147 /* stack_mark_reached_from_outvars *********************************************
1149 Mark the given block reached and propagate the outvars of the current block
1150 and the current locals to it. This function specializes the target block,
1151 if necessary, and returns a pointer to the specialized target.
1154 sd...........stack analysis data
1155 b............the block to reach
1158 a pointer to (a specialized version of) the target
1159 NULL.........a VerifyError has been thrown
1161 *******************************************************************************/
1163 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1165 #if defined(STACK_VERBOSE)
1166 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1168 /* mark targets of backward branches */
1169 if (b->nr <= sd->bptr->nr)
1170 b->bitflags |= BBFLAG_REPLACEMENT;
1172 if (b->flags < BBREACHED) {
1173 /* b is reached for the first time. Create its invars. */
1175 #if defined(STACK_VERBOSE)
1176 printf("reached L%03d for the first time\n", b->nr);
1179 stack_create_invars_from_outvars(sd, b);
1181 b->flags = BBREACHED;
1186 /* b has been reached before. Check that its invars match. */
1188 return stack_check_invars_from_outvars(sd, b);
1193 /* stack_reach_next_block ******************************************************
1195 Mark the following block reached and propagate the outvars of the current block
1196 and the current locals to it. This function specializes the target block,
1197 if necessary, and returns a pointer to the specialized target.
1200 sd...........stack analysis data
1203 a pointer to (a specialized version of) the following block
1204 NULL.........a VerifyError has been thrown
1206 *******************************************************************************/
1208 static bool stack_reach_next_block(stackdata_t *sd)
1213 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1214 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1218 if (tbptr != sd->bptr->next) {
1219 #if defined(STACK_VERBOSE)
1220 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1222 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1223 assert(iptr->opc == ICMD_NOP);
1224 iptr->opc = ICMD_GOTO;
1225 iptr->dst.block = tbptr;
1227 if (tbptr->flags < BBFINISHED)
1228 sd->repeat = true; /* XXX check if we really need to repeat */
1235 /* stack_reach_handlers ********************************************************
1237 Reach the exception handlers for the current block.
1240 sd...........stack analysis data
1243 true.........everything ok
1244 false........a VerifyError has been thrown
1246 *******************************************************************************/
1248 static bool stack_reach_handlers(stackdata_t *sd)
1253 #if defined(STACK_VERBOSE)
1254 printf("reaching exception handlers...\n");
1257 for (i=0; sd->handlers[i]; ++i) {
1258 tbptr = sd->handlers[i]->handler;
1260 tbptr->type = BBTYPE_EXH;
1261 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1263 /* reach (and specialize) the handler block */
1265 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1270 sd->handlers[i]->handler = tbptr;
1277 /* stack_reanalyse_block ******************************************************
1279 Re-analyse the current block. This is called if either the block itself
1280 has already been analysed before, or the current block is a clone of an
1281 already analysed block, and this clone is reached for the first time.
1282 In the latter case, this function does all that is necessary for fully
1283 cloning the block (cloning the instruction list and variables, etc.).
1286 sd...........stack analysis data
1289 true.........everything ok
1290 false........a VerifyError has been thrown
1292 *******************************************************************************/
1294 #define RELOCATE(index) \
1296 if ((index) >= blockvarstart) \
1297 (index) += blockvarshift; \
1298 else if ((index) >= invarstart) \
1299 (index) += invarshift; \
1302 bool stack_reanalyse_block(stackdata_t *sd)
1314 branch_target_t *table;
1315 lookup_target_t *lookup;
1317 bool cloneinstructions;
1318 exception_entry *ex;
1320 #if defined(STACK_VERBOSE)
1321 stack_verbose_block_enter(sd, true);
1328 assert(orig != NULL);
1330 /* clone the instruction list */
1332 cloneinstructions = true;
1334 assert(orig->iinstr);
1336 iptr = DMNEW(instruction, len + 1);
1338 MCOPY(iptr, orig->iinstr, instruction, len);
1339 iptr[len].opc = ICMD_NOP;
1343 /* reserve space for the clone's block variables */
1345 stack_grow_variable_array(sd, orig->varcount);
1347 /* we already have the invars set */
1349 assert(b->indepth == orig->indepth);
1351 /* calculate relocation shifts for invars and block variables */
1353 if (orig->indepth) {
1354 invarstart = orig->invars[0];
1355 invarshift = b->invars[0] - invarstart;
1358 invarstart = INT_MAX;
1361 blockvarstart = orig->varstart;
1362 blockvarshift = sd->vartop - blockvarstart;
1364 /* copy block variables */
1366 b->varstart = sd->vartop;
1367 b->varcount = orig->varcount;
1368 sd->vartop += b->varcount;
1369 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1373 b->outdepth = orig->outdepth;
1374 b->outvars = DMNEW(s4, orig->outdepth);
1375 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1377 /* clone exception handlers */
1379 for (i=0; sd->handlers[i]; ++i) {
1380 ex = DNEW(exception_entry);
1381 ex->handler = sd->handlers[i]->handler;
1383 ex->end = b; /* XXX hack, see end of stack_analyse */
1384 ex->catchtype = sd->handlers[i]->catchtype;
1387 assert(sd->extableend->down == NULL);
1388 sd->extableend->down = ex;
1389 sd->extableend = ex;
1390 sd->jd->exceptiontablelength++;
1392 sd->handlers[i] = ex;
1396 cloneinstructions = false;
1399 invarstart = sd->vartop;
1400 blockvarstart = sd->vartop;
1405 /* find exception handlers for the cloned block */
1407 ex = sd->jd->exceptiontable;
1408 for (; ex != NULL; ex = ex->down) {
1409 /* XXX the cloned exception handlers have identical */
1410 /* start end end blocks. */
1411 if ((ex->start == b) && (ex->end == b)) {
1412 sd->handlers[len++] = ex;
1415 sd->handlers[len] = NULL;
1418 #if defined(STACK_VERBOSE)
1419 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1420 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1423 /* mark block as finished */
1425 b->flags = BBFINISHED;
1427 /* initialize locals at the start of this block */
1430 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1432 MCOPY(sd->javalocals, b->javalocals, s4, sd->maxlocals);
1434 /* reach exception handlers for this block */
1436 if (!stack_reach_handlers(sd))
1439 superblockend = false;
1441 for (len = b->icount; len--; iptr++) {
1442 #if defined(STACK_VERBOSE)
1443 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1447 switch (iptr->opc) {
1449 j = iptr->s1.varindex;
1451 #if defined(ENABLE_VERIFIER)
1452 if (sd->var[j].type != TYPE_RET) {
1453 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1458 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1459 superblockend = true;
1463 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1464 RELOCATE(iptr->dst.varindex);
1465 superblockend = true;
1469 superblockend = true;
1472 case ICMD_CHECKNULL:
1473 case ICMD_PUTSTATICCONST:
1478 case ICMD_INLINE_START:
1479 case ICMD_INLINE_END:
1480 case ICMD_INLINE_GOTO:
1484 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1485 superblockend = true;
1488 /* pop 0 push 1 const */
1496 /* pop 0 push 1 load */
1503 RELOCATE(iptr->dst.varindex);
1516 RELOCATE(iptr->sx.s23.s2.varindex);
1517 RELOCATE(iptr->s1.varindex);
1518 RELOCATE(iptr->dst.varindex);
1531 RELOCATE(iptr->sx.s23.s3.varindex);
1532 RELOCATE(iptr->sx.s23.s2.varindex);
1533 RELOCATE(iptr->s1.varindex);
1536 /* pop 1 push 0 store */
1543 RELOCATE(iptr->s1.varindex);
1545 j = iptr->dst.varindex;
1546 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1547 i = iptr->sx.s23.s3.javaindex;
1548 if (iptr->flags.bits & INS_FLAG_RETADDR) {
1549 iptr->sx.s23.s2.retaddrnr =
1550 UNUSED - (1 + sd->var[j].vv.retaddr->nr);
1551 sd->javalocals[i] = iptr->sx.s23.s2.retaddrnr;
1554 sd->javalocals[i] = j;
1555 if (iptr->flags.bits & INS_FLAG_KILL_PREV)
1556 sd->javalocals[i-1] = UNUSED;
1557 if (iptr->flags.bits & INS_FLAG_KILL_NEXT)
1558 sd->javalocals[i+1] = UNUSED;
1569 RELOCATE(iptr->s1.varindex);
1570 superblockend = true;
1573 case ICMD_PUTSTATIC:
1574 case ICMD_PUTFIELDCONST:
1576 RELOCATE(iptr->s1.varindex);
1579 /* pop 1 push 0 branch */
1582 case ICMD_IFNONNULL:
1597 RELOCATE(iptr->s1.varindex);
1598 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1601 /* pop 1 push 0 table branch */
1603 case ICMD_TABLESWITCH:
1604 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1606 if (cloneinstructions) {
1607 table = DMNEW(branch_target_t, i);
1608 MCOPY(table, iptr->dst.table, branch_target_t, i);
1609 iptr->dst.table = table;
1612 table = iptr->dst.table;
1615 RELOCATE(iptr->s1.varindex);
1617 table->block = stack_mark_reached_from_outvars(sd, table->block);
1620 superblockend = true;
1623 case ICMD_LOOKUPSWITCH:
1624 i = iptr->sx.s23.s2.lookupcount;
1625 if (cloneinstructions) {
1626 lookup = DMNEW(lookup_target_t, i);
1627 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1628 iptr->dst.lookup = lookup;
1631 lookup = iptr->dst.lookup;
1633 RELOCATE(iptr->s1.varindex);
1635 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1638 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1639 superblockend = true;
1642 case ICMD_MONITORENTER:
1643 case ICMD_MONITOREXIT:
1644 RELOCATE(iptr->s1.varindex);
1647 /* pop 2 push 0 branch */
1649 case ICMD_IF_ICMPEQ:
1650 case ICMD_IF_ICMPNE:
1651 case ICMD_IF_ICMPLT:
1652 case ICMD_IF_ICMPGE:
1653 case ICMD_IF_ICMPGT:
1654 case ICMD_IF_ICMPLE:
1656 case ICMD_IF_LCMPEQ:
1657 case ICMD_IF_LCMPNE:
1658 case ICMD_IF_LCMPLT:
1659 case ICMD_IF_LCMPGE:
1660 case ICMD_IF_LCMPGT:
1661 case ICMD_IF_LCMPLE:
1663 case ICMD_IF_FCMPEQ:
1664 case ICMD_IF_FCMPNE:
1666 case ICMD_IF_FCMPL_LT:
1667 case ICMD_IF_FCMPL_GE:
1668 case ICMD_IF_FCMPL_GT:
1669 case ICMD_IF_FCMPL_LE:
1671 case ICMD_IF_FCMPG_LT:
1672 case ICMD_IF_FCMPG_GE:
1673 case ICMD_IF_FCMPG_GT:
1674 case ICMD_IF_FCMPG_LE:
1676 case ICMD_IF_DCMPEQ:
1677 case ICMD_IF_DCMPNE:
1679 case ICMD_IF_DCMPL_LT:
1680 case ICMD_IF_DCMPL_GE:
1681 case ICMD_IF_DCMPL_GT:
1682 case ICMD_IF_DCMPL_LE:
1684 case ICMD_IF_DCMPG_LT:
1685 case ICMD_IF_DCMPG_GE:
1686 case ICMD_IF_DCMPG_GT:
1687 case ICMD_IF_DCMPG_LE:
1689 case ICMD_IF_ACMPEQ:
1690 case ICMD_IF_ACMPNE:
1691 RELOCATE(iptr->sx.s23.s2.varindex);
1692 RELOCATE(iptr->s1.varindex);
1693 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1699 case ICMD_IASTORECONST:
1700 case ICMD_LASTORECONST:
1701 case ICMD_AASTORECONST:
1702 case ICMD_BASTORECONST:
1703 case ICMD_CASTORECONST:
1704 case ICMD_SASTORECONST:
1706 RELOCATE(iptr->sx.s23.s2.varindex);
1707 RELOCATE(iptr->s1.varindex);
1710 /* pop 0 push 1 copy */
1714 RELOCATE(iptr->dst.varindex);
1715 RELOCATE(iptr->s1.varindex);
1716 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1758 RELOCATE(iptr->sx.s23.s2.varindex);
1759 RELOCATE(iptr->s1.varindex);
1760 RELOCATE(iptr->dst.varindex);
1765 case ICMD_CHECKCAST:
1766 case ICMD_ARRAYLENGTH:
1767 case ICMD_INSTANCEOF:
1769 case ICMD_ANEWARRAY:
1771 case ICMD_IADDCONST:
1772 case ICMD_ISUBCONST:
1773 case ICMD_IMULCONST:
1777 case ICMD_IANDCONST:
1779 case ICMD_IXORCONST:
1780 case ICMD_ISHLCONST:
1781 case ICMD_ISHRCONST:
1782 case ICMD_IUSHRCONST:
1783 case ICMD_LADDCONST:
1784 case ICMD_LSUBCONST:
1785 case ICMD_LMULCONST:
1789 case ICMD_LANDCONST:
1791 case ICMD_LXORCONST:
1792 case ICMD_LSHLCONST:
1793 case ICMD_LSHRCONST:
1794 case ICMD_LUSHRCONST:
1798 case ICMD_INT2SHORT:
1814 RELOCATE(iptr->s1.varindex);
1815 RELOCATE(iptr->dst.varindex);
1820 case ICMD_GETSTATIC:
1822 RELOCATE(iptr->dst.varindex);
1825 /* pop many push any */
1827 case ICMD_INVOKESTATIC:
1828 case ICMD_INVOKESPECIAL:
1829 case ICMD_INVOKEVIRTUAL:
1830 case ICMD_INVOKEINTERFACE:
1832 case ICMD_MULTIANEWARRAY:
1833 i = iptr->s1.argcount;
1834 if (cloneinstructions) {
1835 argp = DMNEW(s4, i);
1836 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1837 iptr->sx.s23.s2.args = argp;
1840 argp = iptr->sx.s23.s2.args;
1847 RELOCATE(iptr->dst.varindex);
1852 new_internalerror("Unknown ICMD %d during stack re-analysis",
1857 #if defined(STACK_VERBOSE)
1858 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1863 /* relocate outvars */
1865 for (i=0; i<b->outdepth; ++i) {
1866 RELOCATE(b->outvars[i]);
1869 #if defined(STACK_VERBOSE)
1870 stack_verbose_block_exit(sd, superblockend);
1873 /* propagate to the next block */
1876 if (!stack_reach_next_block(sd))
1883 /* stack_change_to_tempvar *****************************************************
1885 Change the given stackslot to a TEMPVAR. This includes creating a new
1886 temporary variable and changing the dst.varindex of the creator of the
1887 stacklot to the new variable index. If this stackslot has been passed
1888 through ICMDs between the point of its creation and the current point,
1889 then the variable index is also changed in these ICMDs.
1892 sd...........stack analysis data
1893 sp...........stackslot to change
1894 ilimit.......instruction up to which to look for ICMDs passing-through
1895 the stackslot (exclusive). This may point exactly after the
1896 last instruction, in which case the search is done to the
1899 *******************************************************************************/
1901 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1902 instruction *ilimit)
1910 oldindex = sp->varnum;
1912 /* create a new temporary variable */
1914 GET_NEW_VAR(*sd, newindex, sp->type);
1916 sd->var[newindex].flags = sp->flags;
1918 /* change the stackslot */
1920 sp->varnum = newindex;
1921 sp->varkind = TEMPVAR;
1923 /* change the dst.varindex of the stackslot's creator */
1926 sp->creator->dst.varindex = newindex;
1928 /* handle ICMDs this stackslot passed through, if any */
1930 if (sp->flags & PASSTHROUGH) {
1931 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1933 /* assert that the limit points to an ICMD, or after the last one */
1935 assert(ilimit >= sd->bptr->iinstr);
1936 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1938 /* find the stackdepth under sp plus one */
1939 /* Note: This number is usually known when this function is called, */
1940 /* but calculating it here is less error-prone and should not be */
1941 /* a performance problem. */
1943 for (depth = 0; sp != NULL; sp = sp->prev)
1946 /* iterate over all instructions in the range and replace */
1948 for (; iptr < ilimit; ++iptr) {
1949 switch (iptr->opc) {
1950 case ICMD_INVOKESTATIC:
1951 case ICMD_INVOKESPECIAL:
1952 case ICMD_INVOKEVIRTUAL:
1953 case ICMD_INVOKEINTERFACE:
1955 i = iptr->s1.argcount - depth;
1956 if (iptr->sx.s23.s2.args[i] == oldindex) {
1957 iptr->sx.s23.s2.args[i] = newindex;
1960 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1961 /* stackslot, it must be added in this switch! */
1968 /* stack_init_javalocals *******************************************************
1970 Initialize the mapping from Java locals to cacao variables at method entry.
1973 sd...........stack analysis data
1975 *******************************************************************************/
1977 static void stack_init_javalocals(stackdata_t *sd)
1986 jl = DMNEW(s4, sd->maxlocals);
1987 jd->basicblocks[0].javalocals = jl;
1989 for (i=0; i<sd->maxlocals; ++i)
1992 md = jd->m->parseddesc;
1994 for (i=0; i<md->paramcount; ++i) {
1995 t = md->paramtypes[i].type;
1996 jl[j] = jd->local_map[5*j + t];
1998 if (IS_2_WORD_TYPE(t))
2004 /* stack_analyse ***************************************************************
2006 Analyse_stack uses the intermediate code created by parse.c to
2007 build a model of the JVM operand stack for the current method.
2009 The following checks are performed:
2010 - check for operand stack underflow (before each instruction)
2011 - check for operand stack overflow (after[1] each instruction)
2012 - check for matching stack depth at merging points
2013 - check for matching basic types[2] at merging points
2014 - check basic types for instruction input (except for BUILTIN*
2015 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
2017 [1]) Checking this after the instruction should be ok. parse.c
2018 counts the number of required stack slots in such a way that it is
2019 only vital that we don't exceed `maxstack` at basic block
2022 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
2023 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
2024 types are not discerned.
2026 *******************************************************************************/
2028 bool stack_analyse(jitdata *jd)
2030 methodinfo *m; /* method being analyzed */
2033 #if defined(ENABLE_SSA)
2037 stackptr curstack; /* current stack top */
2039 int opcode; /* opcode of current instruction */
2042 int len; /* # of instructions after the current one */
2043 bool superblockend; /* if true, no fallthrough to next block */
2044 bool deadcode; /* true if no live code has been reached */
2045 instruction *iptr; /* the current instruction */
2047 basicblock *original;
2048 exception_entry *ex;
2050 stackptr *last_store_boundary;
2051 stackptr coalescing_boundary;
2053 stackptr src1, src2, src3, src4, dst1, dst2;
2055 branch_target_t *table;
2056 lookup_target_t *lookup;
2057 #if defined(ENABLE_VERIFIER)
2058 int expectedtype; /* used by CHECK_BASIC_TYPE */
2060 builtintable_entry *bte;
2062 constant_FMIref *fmiref;
2063 #if defined(ENABLE_STATISTICS)
2064 int iteration_count; /* number of iterations of analysis */
2066 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
2068 #if defined(STACK_VERBOSE)
2069 show_method(jd, SHOW_PARSE);
2072 /* get required compiler data - initialization */
2076 #if defined(ENABLE_SSA)
2080 /* initialize the stackdata_t struct */
2084 sd.varcount = jd->varcount;
2085 sd.vartop = jd->vartop;
2086 sd.localcount = jd->localcount;
2088 sd.varsallocated = sd.varcount;
2089 sd.maxlocals = m->maxlocals;
2090 sd.javalocals = DMNEW(s4, sd.maxlocals);
2091 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2093 /* prepare the variable for exception handler stacks */
2094 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2096 sd.exstack.type = TYPE_ADR;
2097 sd.exstack.prev = NULL;
2098 sd.exstack.varnum = sd.localcount;
2099 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2101 #if defined(ENABLE_LSRA)
2102 m->maxlifetimes = 0;
2105 #if defined(ENABLE_STATISTICS)
2106 iteration_count = 0;
2109 /* find the last real basic block */
2111 sd.last_real_block = NULL;
2112 tbptr = jd->basicblocks;
2113 while (tbptr->next) {
2114 sd.last_real_block = tbptr;
2115 tbptr = tbptr->next;
2117 assert(sd.last_real_block);
2119 /* find the last exception handler */
2121 if (jd->exceptiontablelength)
2122 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2124 sd.extableend = NULL;
2126 /* init jd->interface_map */
2128 jd->maxinterfaces = m->maxstack;
2129 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2130 for (i = 0; i < m->maxstack * 5; i++)
2131 jd->interface_map[i].flags = UNUSED;
2133 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2135 /* initialize flags and invars (none) of first block */
2137 jd->basicblocks[0].flags = BBREACHED;
2138 jd->basicblocks[0].invars = NULL;
2139 jd->basicblocks[0].indepth = 0;
2140 jd->basicblocks[0].inlocals =
2141 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2142 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2143 jd->localcount + VERIFIER_EXTRA_LOCALS);
2145 /* initialize java local mapping of first block */
2147 stack_init_javalocals(&sd);
2149 /* stack analysis loop (until fixpoint reached) **************************/
2152 #if defined(ENABLE_STATISTICS)
2156 /* initialize loop over basic blocks */
2158 sd.bptr = jd->basicblocks;
2159 superblockend = true;
2161 curstack = NULL; stackdepth = 0;
2164 /* iterate over basic blocks *****************************************/
2166 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2168 if (sd.bptr->flags == BBDELETED) {
2169 /* This block has been deleted - do nothing. */
2174 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2175 /* re-analyse a block because its input changed */
2177 if (!stack_reanalyse_block(&sd))
2179 superblockend = true; /* XXX */
2183 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2184 /* This block has not been reached so far, and we */
2185 /* don't fall into it, so we'll have to iterate again. */
2191 if (sd.bptr->flags > BBREACHED) {
2192 /* This block is already finished. */
2194 superblockend = true;
2198 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2199 /* This block is a clone and the original has not been */
2200 /* analysed, yet. Analyse it on the next iteration. */
2203 /* XXX superblockend? */
2207 /* This block has to be analysed now. */
2211 /* XXX The rest of this block is still indented one level too */
2212 /* much in order to avoid a giant diff by changing that. */
2214 /* We know that sd.bptr->flags == BBREACHED. */
2215 /* This block has been reached before. */
2217 assert(sd.bptr->flags == BBREACHED);
2218 stackdepth = sd.bptr->indepth;
2220 /* find exception handlers for this block */
2222 /* determine the active exception handlers for this block */
2223 /* XXX could use a faster algorithm with sorted lists or */
2226 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2229 ex = jd->exceptiontable;
2230 for (; ex != NULL; ex = ex->down) {
2231 if ((ex->start <= original) && (ex->end > original)) {
2232 sd.handlers[len++] = ex;
2235 sd.handlers[len] = NULL;
2238 /* reanalyse cloned block */
2240 if (sd.bptr->original) {
2241 if (!stack_reanalyse_block(&sd))
2246 /* reset the new pointer for allocating stackslots */
2250 /* create the instack of this block */
2252 curstack = stack_create_instack(&sd);
2254 /* initialize locals at the start of this block */
2256 if (sd.bptr->inlocals)
2257 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2259 MCOPY(sd.javalocals, sd.bptr->javalocals, s4, sd.maxlocals);
2261 /* set up local variables for analyzing this block */
2263 superblockend = false;
2264 len = sd.bptr->icount;
2265 iptr = sd.bptr->iinstr;
2267 /* mark the block as analysed */
2269 sd.bptr->flags = BBFINISHED;
2271 /* reset variables for dependency checking */
2273 coalescing_boundary = sd.new;
2274 for( i = 0; i < m->maxlocals; i++)
2275 last_store_boundary[i] = sd.new;
2277 /* remember the start of this block's variables */
2279 sd.bptr->varstart = sd.vartop;
2281 #if defined(STACK_VERBOSE)
2282 stack_verbose_block_enter(&sd, false);
2285 /* reach exception handlers for this block */
2287 if (!stack_reach_handlers(&sd))
2290 /* iterate over ICMDs ****************************************/
2292 while (--len >= 0) {
2294 #if defined(STACK_VERBOSE)
2295 stack_verbose_show_state(&sd, iptr, curstack);
2298 /* fetch the current opcode */
2302 /* automatically replace some ICMDs with builtins */
2304 #if defined(USEBUILTINTABLE)
2305 bte = builtintable_get_automatic(opcode);
2307 if (bte && bte->opcode == opcode) {
2308 iptr->opc = ICMD_BUILTIN;
2309 iptr->flags.bits &= INS_FLAG_ID_MASK;
2310 iptr->sx.s23.s3.bte = bte;
2311 /* iptr->line is already set */
2312 jd->isleafmethod = false;
2315 #endif /* defined(USEBUILTINTABLE) */
2317 /* main opcode switch *************************************/
2329 case ICMD_CHECKNULL:
2330 coalescing_boundary = sd.new;
2331 COUNT(count_check_null);
2334 iptr->dst.varindex = iptr->s1.varindex;
2338 j = iptr->s1.varindex =
2339 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2341 #if defined(ENABLE_VERIFIER)
2342 if (sd.var[j].type != TYPE_RET) {
2343 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2350 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2351 superblockend = true;
2355 COUNT(count_pcmd_return);
2358 superblockend = true;
2359 sd.jd->returncount++;
2360 sd.jd->returnblock = sd.bptr;
2364 /* pop 0 push 1 const */
2366 /************************** ICONST OPTIMIZATIONS **************************/
2369 COUNT(count_pcmd_load);
2373 switch (iptr[1].opc) {
2375 iptr->opc = ICMD_IADDCONST;
2379 iptr[1].opc = ICMD_NOP;
2380 OP1_1(TYPE_INT, TYPE_INT);
2381 COUNT(count_pcmd_op);
2385 iptr->opc = ICMD_ISUBCONST;
2386 goto icmd_iconst_tail;
2387 #if SUPPORT_CONST_MUL
2389 iptr->opc = ICMD_IMULCONST;
2390 goto icmd_iconst_tail;
2391 #else /* SUPPORT_CONST_MUL */
2393 if (iptr->sx.val.i == 0x00000002)
2395 else if (iptr->sx.val.i == 0x00000004)
2397 else if (iptr->sx.val.i == 0x00000008)
2399 else if (iptr->sx.val.i == 0x00000010)
2401 else if (iptr->sx.val.i == 0x00000020)
2403 else if (iptr->sx.val.i == 0x00000040)
2405 else if (iptr->sx.val.i == 0x00000080)
2407 else if (iptr->sx.val.i == 0x00000100)
2409 else if (iptr->sx.val.i == 0x00000200)
2411 else if (iptr->sx.val.i == 0x00000400)
2412 iptr->sx.val.i = 10;
2413 else if (iptr->sx.val.i == 0x00000800)
2414 iptr->sx.val.i = 11;
2415 else if (iptr->sx.val.i == 0x00001000)
2416 iptr->sx.val.i = 12;
2417 else if (iptr->sx.val.i == 0x00002000)
2418 iptr->sx.val.i = 13;
2419 else if (iptr->sx.val.i == 0x00004000)
2420 iptr->sx.val.i = 14;
2421 else if (iptr->sx.val.i == 0x00008000)
2422 iptr->sx.val.i = 15;
2423 else if (iptr->sx.val.i == 0x00010000)
2424 iptr->sx.val.i = 16;
2425 else if (iptr->sx.val.i == 0x00020000)
2426 iptr->sx.val.i = 17;
2427 else if (iptr->sx.val.i == 0x00040000)
2428 iptr->sx.val.i = 18;
2429 else if (iptr->sx.val.i == 0x00080000)
2430 iptr->sx.val.i = 19;
2431 else if (iptr->sx.val.i == 0x00100000)
2432 iptr->sx.val.i = 20;
2433 else if (iptr->sx.val.i == 0x00200000)
2434 iptr->sx.val.i = 21;
2435 else if (iptr->sx.val.i == 0x00400000)
2436 iptr->sx.val.i = 22;
2437 else if (iptr->sx.val.i == 0x00800000)
2438 iptr->sx.val.i = 23;
2439 else if (iptr->sx.val.i == 0x01000000)
2440 iptr->sx.val.i = 24;
2441 else if (iptr->sx.val.i == 0x02000000)
2442 iptr->sx.val.i = 25;
2443 else if (iptr->sx.val.i == 0x04000000)
2444 iptr->sx.val.i = 26;
2445 else if (iptr->sx.val.i == 0x08000000)
2446 iptr->sx.val.i = 27;
2447 else if (iptr->sx.val.i == 0x10000000)
2448 iptr->sx.val.i = 28;
2449 else if (iptr->sx.val.i == 0x20000000)
2450 iptr->sx.val.i = 29;
2451 else if (iptr->sx.val.i == 0x40000000)
2452 iptr->sx.val.i = 30;
2453 else if (iptr->sx.val.i == 0x80000000)
2454 iptr->sx.val.i = 31;
2458 iptr->opc = ICMD_IMULPOW2;
2459 goto icmd_iconst_tail;
2460 #endif /* SUPPORT_CONST_MUL */
2462 if (iptr->sx.val.i == 0x00000002)
2464 else if (iptr->sx.val.i == 0x00000004)
2466 else if (iptr->sx.val.i == 0x00000008)
2468 else if (iptr->sx.val.i == 0x00000010)
2470 else if (iptr->sx.val.i == 0x00000020)
2472 else if (iptr->sx.val.i == 0x00000040)
2474 else if (iptr->sx.val.i == 0x00000080)
2476 else if (iptr->sx.val.i == 0x00000100)
2478 else if (iptr->sx.val.i == 0x00000200)
2480 else if (iptr->sx.val.i == 0x00000400)
2481 iptr->sx.val.i = 10;
2482 else if (iptr->sx.val.i == 0x00000800)
2483 iptr->sx.val.i = 11;
2484 else if (iptr->sx.val.i == 0x00001000)
2485 iptr->sx.val.i = 12;
2486 else if (iptr->sx.val.i == 0x00002000)
2487 iptr->sx.val.i = 13;
2488 else if (iptr->sx.val.i == 0x00004000)
2489 iptr->sx.val.i = 14;
2490 else if (iptr->sx.val.i == 0x00008000)
2491 iptr->sx.val.i = 15;
2492 else if (iptr->sx.val.i == 0x00010000)
2493 iptr->sx.val.i = 16;
2494 else if (iptr->sx.val.i == 0x00020000)
2495 iptr->sx.val.i = 17;
2496 else if (iptr->sx.val.i == 0x00040000)
2497 iptr->sx.val.i = 18;
2498 else if (iptr->sx.val.i == 0x00080000)
2499 iptr->sx.val.i = 19;
2500 else if (iptr->sx.val.i == 0x00100000)
2501 iptr->sx.val.i = 20;
2502 else if (iptr->sx.val.i == 0x00200000)
2503 iptr->sx.val.i = 21;
2504 else if (iptr->sx.val.i == 0x00400000)
2505 iptr->sx.val.i = 22;
2506 else if (iptr->sx.val.i == 0x00800000)
2507 iptr->sx.val.i = 23;
2508 else if (iptr->sx.val.i == 0x01000000)
2509 iptr->sx.val.i = 24;
2510 else if (iptr->sx.val.i == 0x02000000)
2511 iptr->sx.val.i = 25;
2512 else if (iptr->sx.val.i == 0x04000000)
2513 iptr->sx.val.i = 26;
2514 else if (iptr->sx.val.i == 0x08000000)
2515 iptr->sx.val.i = 27;
2516 else if (iptr->sx.val.i == 0x10000000)
2517 iptr->sx.val.i = 28;
2518 else if (iptr->sx.val.i == 0x20000000)
2519 iptr->sx.val.i = 29;
2520 else if (iptr->sx.val.i == 0x40000000)
2521 iptr->sx.val.i = 30;
2522 else if (iptr->sx.val.i == 0x80000000)
2523 iptr->sx.val.i = 31;
2527 iptr->opc = ICMD_IDIVPOW2;
2528 goto icmd_iconst_tail;
2531 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2532 if ((iptr->sx.val.i == 0x00000002) ||
2533 (iptr->sx.val.i == 0x00000004) ||
2534 (iptr->sx.val.i == 0x00000008) ||
2535 (iptr->sx.val.i == 0x00000010) ||
2536 (iptr->sx.val.i == 0x00000020) ||
2537 (iptr->sx.val.i == 0x00000040) ||
2538 (iptr->sx.val.i == 0x00000080) ||
2539 (iptr->sx.val.i == 0x00000100) ||
2540 (iptr->sx.val.i == 0x00000200) ||
2541 (iptr->sx.val.i == 0x00000400) ||
2542 (iptr->sx.val.i == 0x00000800) ||
2543 (iptr->sx.val.i == 0x00001000) ||
2544 (iptr->sx.val.i == 0x00002000) ||
2545 (iptr->sx.val.i == 0x00004000) ||
2546 (iptr->sx.val.i == 0x00008000) ||
2547 (iptr->sx.val.i == 0x00010000) ||
2548 (iptr->sx.val.i == 0x00020000) ||
2549 (iptr->sx.val.i == 0x00040000) ||
2550 (iptr->sx.val.i == 0x00080000) ||
2551 (iptr->sx.val.i == 0x00100000) ||
2552 (iptr->sx.val.i == 0x00200000) ||
2553 (iptr->sx.val.i == 0x00400000) ||
2554 (iptr->sx.val.i == 0x00800000) ||
2555 (iptr->sx.val.i == 0x01000000) ||
2556 (iptr->sx.val.i == 0x02000000) ||
2557 (iptr->sx.val.i == 0x04000000) ||
2558 (iptr->sx.val.i == 0x08000000) ||
2559 (iptr->sx.val.i == 0x10000000) ||
2560 (iptr->sx.val.i == 0x20000000) ||
2561 (iptr->sx.val.i == 0x40000000) ||
2562 (iptr->sx.val.i == 0x80000000))
2564 iptr->opc = ICMD_IREMPOW2;
2565 iptr->sx.val.i -= 1;
2566 goto icmd_iconst_tail;
2569 #if SUPPORT_CONST_LOGICAL
2571 iptr->opc = ICMD_IANDCONST;
2572 goto icmd_iconst_tail;
2575 iptr->opc = ICMD_IORCONST;
2576 goto icmd_iconst_tail;
2579 iptr->opc = ICMD_IXORCONST;
2580 goto icmd_iconst_tail;
2582 #endif /* SUPPORT_CONST_LOGICAL */
2584 iptr->opc = ICMD_ISHLCONST;
2585 goto icmd_iconst_tail;
2588 iptr->opc = ICMD_ISHRCONST;
2589 goto icmd_iconst_tail;
2592 iptr->opc = ICMD_IUSHRCONST;
2593 goto icmd_iconst_tail;
2594 #if SUPPORT_LONG_SHIFT
2596 iptr->opc = ICMD_LSHLCONST;
2597 goto icmd_lconst_tail;
2600 iptr->opc = ICMD_LSHRCONST;
2601 goto icmd_lconst_tail;
2604 iptr->opc = ICMD_LUSHRCONST;
2605 goto icmd_lconst_tail;
2606 #endif /* SUPPORT_LONG_SHIFT */
2607 case ICMD_IF_ICMPEQ:
2608 iptr[1].opc = ICMD_IFEQ;
2612 /* set the constant for the following icmd */
2613 iptr[1].sx.val.i = iptr->sx.val.i;
2615 /* this instruction becomes a nop */
2616 iptr->opc = ICMD_NOP;
2619 case ICMD_IF_ICMPLT:
2620 iptr[1].opc = ICMD_IFLT;
2621 goto icmd_if_icmp_tail;
2623 case ICMD_IF_ICMPLE:
2624 iptr[1].opc = ICMD_IFLE;
2625 goto icmd_if_icmp_tail;
2627 case ICMD_IF_ICMPNE:
2628 iptr[1].opc = ICMD_IFNE;
2629 goto icmd_if_icmp_tail;
2631 case ICMD_IF_ICMPGT:
2632 iptr[1].opc = ICMD_IFGT;
2633 goto icmd_if_icmp_tail;
2635 case ICMD_IF_ICMPGE:
2636 iptr[1].opc = ICMD_IFGE;
2637 goto icmd_if_icmp_tail;
2639 #if SUPPORT_CONST_STORE
2644 # if SUPPORT_CONST_STORE_ZERO_ONLY
2645 if (iptr->sx.val.i != 0)
2648 switch (iptr[1].opc) {
2650 iptr->opc = ICMD_IASTORECONST;
2651 iptr->flags.bits |= INS_FLAG_CHECK;
2654 iptr->opc = ICMD_BASTORECONST;
2655 iptr->flags.bits |= INS_FLAG_CHECK;
2658 iptr->opc = ICMD_CASTORECONST;
2659 iptr->flags.bits |= INS_FLAG_CHECK;
2662 iptr->opc = ICMD_SASTORECONST;
2663 iptr->flags.bits |= INS_FLAG_CHECK;
2667 iptr[1].opc = ICMD_NOP;
2669 /* copy the constant to s3 */
2670 /* XXX constval -> astoreconstval? */
2671 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2672 OP2_0(TYPE_ADR, TYPE_INT);
2673 COUNT(count_pcmd_op);
2676 case ICMD_PUTSTATIC:
2678 # if SUPPORT_CONST_STORE_ZERO_ONLY
2679 if (iptr->sx.val.i != 0)
2682 /* XXX check field type? */
2684 /* copy the constant to s2 */
2685 /* XXX constval -> fieldconstval? */
2686 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2689 /* set the field reference (s3) */
2690 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2691 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2692 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2693 fmiref = iptr->sx.s23.s3.uf->fieldref;
2696 fmiref = iptr[1].sx.s23.s3.fmiref;
2697 iptr->sx.s23.s3.fmiref = fmiref;
2700 #if defined(ENABLE_VERIFIER)
2701 expectedtype = fmiref->parseddesc.fd->type;
2702 switch (iptr[0].opc) {
2704 if (expectedtype != TYPE_INT)
2705 goto throw_stack_type_error;
2708 if (expectedtype != TYPE_LNG)
2709 goto throw_stack_type_error;
2712 if (expectedtype != TYPE_ADR)
2713 goto throw_stack_type_error;
2718 #endif /* defined(ENABLE_VERIFIER) */
2720 switch (iptr[1].opc) {
2721 case ICMD_PUTSTATIC:
2722 iptr->opc = ICMD_PUTSTATICCONST;
2726 iptr->opc = ICMD_PUTFIELDCONST;
2731 iptr[1].opc = ICMD_NOP;
2732 COUNT(count_pcmd_op);
2734 #endif /* SUPPORT_CONST_STORE */
2740 /* if we get here, the ICONST has been optimized */
2744 /* normal case of an unoptimized ICONST */
2748 /************************** LCONST OPTIMIZATIONS **************************/
2751 COUNT(count_pcmd_load);
2755 /* switch depending on the following instruction */
2757 switch (iptr[1].opc) {
2758 #if SUPPORT_LONG_ADD
2760 iptr->opc = ICMD_LADDCONST;
2764 /* instruction of type LONG -> LONG */
2765 iptr[1].opc = ICMD_NOP;
2766 OP1_1(TYPE_LNG, TYPE_LNG);
2767 COUNT(count_pcmd_op);
2771 iptr->opc = ICMD_LSUBCONST;
2772 goto icmd_lconst_tail;
2774 #endif /* SUPPORT_LONG_ADD */
2775 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2777 iptr->opc = ICMD_LMULCONST;
2778 goto icmd_lconst_tail;
2779 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2780 # if SUPPORT_LONG_SHIFT
2782 if (iptr->sx.val.l == 0x00000002)
2784 else if (iptr->sx.val.l == 0x00000004)
2786 else if (iptr->sx.val.l == 0x00000008)
2788 else if (iptr->sx.val.l == 0x00000010)
2790 else if (iptr->sx.val.l == 0x00000020)
2792 else if (iptr->sx.val.l == 0x00000040)
2794 else if (iptr->sx.val.l == 0x00000080)
2796 else if (iptr->sx.val.l == 0x00000100)
2798 else if (iptr->sx.val.l == 0x00000200)
2800 else if (iptr->sx.val.l == 0x00000400)
2801 iptr->sx.val.i = 10;
2802 else if (iptr->sx.val.l == 0x00000800)
2803 iptr->sx.val.i = 11;
2804 else if (iptr->sx.val.l == 0x00001000)
2805 iptr->sx.val.i = 12;
2806 else if (iptr->sx.val.l == 0x00002000)
2807 iptr->sx.val.i = 13;
2808 else if (iptr->sx.val.l == 0x00004000)
2809 iptr->sx.val.i = 14;
2810 else if (iptr->sx.val.l == 0x00008000)
2811 iptr->sx.val.i = 15;
2812 else if (iptr->sx.val.l == 0x00010000)
2813 iptr->sx.val.i = 16;
2814 else if (iptr->sx.val.l == 0x00020000)
2815 iptr->sx.val.i = 17;
2816 else if (iptr->sx.val.l == 0x00040000)
2817 iptr->sx.val.i = 18;
2818 else if (iptr->sx.val.l == 0x00080000)
2819 iptr->sx.val.i = 19;
2820 else if (iptr->sx.val.l == 0x00100000)
2821 iptr->sx.val.i = 20;
2822 else if (iptr->sx.val.l == 0x00200000)
2823 iptr->sx.val.i = 21;
2824 else if (iptr->sx.val.l == 0x00400000)
2825 iptr->sx.val.i = 22;
2826 else if (iptr->sx.val.l == 0x00800000)
2827 iptr->sx.val.i = 23;
2828 else if (iptr->sx.val.l == 0x01000000)
2829 iptr->sx.val.i = 24;
2830 else if (iptr->sx.val.l == 0x02000000)
2831 iptr->sx.val.i = 25;
2832 else if (iptr->sx.val.l == 0x04000000)
2833 iptr->sx.val.i = 26;
2834 else if (iptr->sx.val.l == 0x08000000)
2835 iptr->sx.val.i = 27;
2836 else if (iptr->sx.val.l == 0x10000000)
2837 iptr->sx.val.i = 28;
2838 else if (iptr->sx.val.l == 0x20000000)
2839 iptr->sx.val.i = 29;
2840 else if (iptr->sx.val.l == 0x40000000)
2841 iptr->sx.val.i = 30;
2842 else if (iptr->sx.val.l == 0x80000000)
2843 iptr->sx.val.i = 31;
2847 iptr->opc = ICMD_LMULPOW2;
2848 goto icmd_lconst_tail;
2849 # endif /* SUPPORT_LONG_SHIFT */
2850 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2851 #if SUPPORT_LONG_DIV_POW2
2853 if (iptr->sx.val.l == 0x00000002)
2855 else if (iptr->sx.val.l == 0x00000004)
2857 else if (iptr->sx.val.l == 0x00000008)
2859 else if (iptr->sx.val.l == 0x00000010)
2861 else if (iptr->sx.val.l == 0x00000020)
2863 else if (iptr->sx.val.l == 0x00000040)
2865 else if (iptr->sx.val.l == 0x00000080)
2867 else if (iptr->sx.val.l == 0x00000100)
2869 else if (iptr->sx.val.l == 0x00000200)
2871 else if (iptr->sx.val.l == 0x00000400)
2872 iptr->sx.val.i = 10;
2873 else if (iptr->sx.val.l == 0x00000800)
2874 iptr->sx.val.i = 11;
2875 else if (iptr->sx.val.l == 0x00001000)
2876 iptr->sx.val.i = 12;
2877 else if (iptr->sx.val.l == 0x00002000)
2878 iptr->sx.val.i = 13;
2879 else if (iptr->sx.val.l == 0x00004000)
2880 iptr->sx.val.i = 14;
2881 else if (iptr->sx.val.l == 0x00008000)
2882 iptr->sx.val.i = 15;
2883 else if (iptr->sx.val.l == 0x00010000)
2884 iptr->sx.val.i = 16;
2885 else if (iptr->sx.val.l == 0x00020000)
2886 iptr->sx.val.i = 17;
2887 else if (iptr->sx.val.l == 0x00040000)
2888 iptr->sx.val.i = 18;
2889 else if (iptr->sx.val.l == 0x00080000)
2890 iptr->sx.val.i = 19;
2891 else if (iptr->sx.val.l == 0x00100000)
2892 iptr->sx.val.i = 20;
2893 else if (iptr->sx.val.l == 0x00200000)
2894 iptr->sx.val.i = 21;
2895 else if (iptr->sx.val.l == 0x00400000)
2896 iptr->sx.val.i = 22;
2897 else if (iptr->sx.val.l == 0x00800000)
2898 iptr->sx.val.i = 23;
2899 else if (iptr->sx.val.l == 0x01000000)
2900 iptr->sx.val.i = 24;
2901 else if (iptr->sx.val.l == 0x02000000)
2902 iptr->sx.val.i = 25;
2903 else if (iptr->sx.val.l == 0x04000000)
2904 iptr->sx.val.i = 26;
2905 else if (iptr->sx.val.l == 0x08000000)
2906 iptr->sx.val.i = 27;
2907 else if (iptr->sx.val.l == 0x10000000)
2908 iptr->sx.val.i = 28;
2909 else if (iptr->sx.val.l == 0x20000000)
2910 iptr->sx.val.i = 29;
2911 else if (iptr->sx.val.l == 0x40000000)
2912 iptr->sx.val.i = 30;
2913 else if (iptr->sx.val.l == 0x80000000)
2914 iptr->sx.val.i = 31;
2918 iptr->opc = ICMD_LDIVPOW2;
2919 goto icmd_lconst_tail;
2920 #endif /* SUPPORT_LONG_DIV_POW2 */
2922 #if SUPPORT_LONG_REM_POW2
2924 if ((iptr->sx.val.l == 0x00000002) ||
2925 (iptr->sx.val.l == 0x00000004) ||
2926 (iptr->sx.val.l == 0x00000008) ||
2927 (iptr->sx.val.l == 0x00000010) ||
2928 (iptr->sx.val.l == 0x00000020) ||
2929 (iptr->sx.val.l == 0x00000040) ||
2930 (iptr->sx.val.l == 0x00000080) ||
2931 (iptr->sx.val.l == 0x00000100) ||
2932 (iptr->sx.val.l == 0x00000200) ||
2933 (iptr->sx.val.l == 0x00000400) ||
2934 (iptr->sx.val.l == 0x00000800) ||
2935 (iptr->sx.val.l == 0x00001000) ||
2936 (iptr->sx.val.l == 0x00002000) ||
2937 (iptr->sx.val.l == 0x00004000) ||
2938 (iptr->sx.val.l == 0x00008000) ||
2939 (iptr->sx.val.l == 0x00010000) ||
2940 (iptr->sx.val.l == 0x00020000) ||
2941 (iptr->sx.val.l == 0x00040000) ||
2942 (iptr->sx.val.l == 0x00080000) ||
2943 (iptr->sx.val.l == 0x00100000) ||
2944 (iptr->sx.val.l == 0x00200000) ||
2945 (iptr->sx.val.l == 0x00400000) ||
2946 (iptr->sx.val.l == 0x00800000) ||
2947 (iptr->sx.val.l == 0x01000000) ||
2948 (iptr->sx.val.l == 0x02000000) ||
2949 (iptr->sx.val.l == 0x04000000) ||
2950 (iptr->sx.val.l == 0x08000000) ||
2951 (iptr->sx.val.l == 0x10000000) ||
2952 (iptr->sx.val.l == 0x20000000) ||
2953 (iptr->sx.val.l == 0x40000000) ||
2954 (iptr->sx.val.l == 0x80000000))
2956 iptr->opc = ICMD_LREMPOW2;
2957 iptr->sx.val.l -= 1;
2958 goto icmd_lconst_tail;
2961 #endif /* SUPPORT_LONG_REM_POW2 */
2963 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2966 iptr->opc = ICMD_LANDCONST;
2967 goto icmd_lconst_tail;
2970 iptr->opc = ICMD_LORCONST;
2971 goto icmd_lconst_tail;
2974 iptr->opc = ICMD_LXORCONST;
2975 goto icmd_lconst_tail;
2976 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2978 #if SUPPORT_LONG_CMP_CONST
2980 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2983 /* switch on the instruction after LCONST - LCMP */
2985 switch (iptr[2].opc) {
2987 iptr->opc = ICMD_IF_LEQ;
2990 icmd_lconst_lcmp_tail:
2991 /* convert LCONST, LCMP, IFXX to IF_LXX */
2992 iptr->dst.insindex = iptr[2].dst.insindex;
2993 iptr[1].opc = ICMD_NOP;
2994 iptr[2].opc = ICMD_NOP;
2996 OP1_BRANCH(TYPE_LNG);
2998 COUNT(count_pcmd_bra);
2999 COUNT(count_pcmd_op);
3003 iptr->opc = ICMD_IF_LNE;
3004 goto icmd_lconst_lcmp_tail;
3007 iptr->opc = ICMD_IF_LLT;
3008 goto icmd_lconst_lcmp_tail;
3011 iptr->opc = ICMD_IF_LGT;
3012 goto icmd_lconst_lcmp_tail;
3015 iptr->opc = ICMD_IF_LLE;
3016 goto icmd_lconst_lcmp_tail;
3019 iptr->opc = ICMD_IF_LGE;
3020 goto icmd_lconst_lcmp_tail;
3024 } /* end switch on opcode after LCONST - LCMP */
3026 #endif /* SUPPORT_LONG_CMP_CONST */
3028 #if SUPPORT_CONST_STORE
3030 # if SUPPORT_CONST_STORE_ZERO_ONLY
3031 if (iptr->sx.val.l != 0)
3034 #if SIZEOF_VOID_P == 4
3035 /* the constant must fit into a ptrint */
3036 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3039 /* move the constant to s3 */
3040 iptr->sx.s23.s3.constval = iptr->sx.val.l;
3042 iptr->opc = ICMD_LASTORECONST;
3043 iptr->flags.bits |= INS_FLAG_CHECK;
3044 OP2_0(TYPE_ADR, TYPE_INT);
3046 iptr[1].opc = ICMD_NOP;
3047 COUNT(count_pcmd_op);
3050 case ICMD_PUTSTATIC:
3052 # if SUPPORT_CONST_STORE_ZERO_ONLY
3053 if (iptr->sx.val.l != 0)
3056 #if SIZEOF_VOID_P == 4
3057 /* the constant must fit into a ptrint */
3058 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
3061 /* XXX check field type? */
3063 /* copy the constant to s2 */
3064 /* XXX constval -> fieldconstval? */
3065 iptr->sx.s23.s2.constval = iptr->sx.val.l;
3069 #endif /* SUPPORT_CONST_STORE */
3073 } /* end switch opcode after LCONST */
3075 /* if we get here, the LCONST has been optimized */
3079 /* the normal case of an unoptimized LCONST */
3083 /************************ END OF LCONST OPTIMIZATIONS *********************/
3086 COUNT(count_pcmd_load);
3091 COUNT(count_pcmd_load);
3095 /************************** ACONST OPTIMIZATIONS **************************/
3098 coalescing_boundary = sd.new;
3099 COUNT(count_pcmd_load);
3100 #if SUPPORT_CONST_STORE
3101 /* We can only optimize if the ACONST is resolved
3102 * and there is an instruction after it. */
3104 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3107 switch (iptr[1].opc) {
3109 /* We can only optimize for NULL values
3110 * here because otherwise a checkcast is
3112 if (iptr->sx.val.anyptr != NULL)
3115 /* copy the constant (NULL) to s3 */
3116 iptr->sx.s23.s3.constval = 0;
3117 iptr->opc = ICMD_AASTORECONST;
3118 iptr->flags.bits |= INS_FLAG_CHECK;
3119 OP2_0(TYPE_ADR, TYPE_INT);
3121 iptr[1].opc = ICMD_NOP;
3122 COUNT(count_pcmd_op);
3125 case ICMD_PUTSTATIC:
3127 # if SUPPORT_CONST_STORE_ZERO_ONLY
3128 if (iptr->sx.val.anyptr != NULL)
3131 /* XXX check field type? */
3132 /* copy the constant to s2 */
3133 /* XXX constval -> fieldconstval? */
3134 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3142 /* if we get here the ACONST has been optimized */
3146 #endif /* SUPPORT_CONST_STORE */
3151 /* pop 0 push 1 load */
3158 COUNT(count_load_instruction);
3159 i = opcode - ICMD_ILOAD; /* type */
3161 j = iptr->s1.varindex =
3162 jd->local_map[iptr->s1.varindex * 5 + i];
3164 #if defined(ENABLE_VERIFIER)
3165 if (sd.var[j].type == TYPE_RET) {
3166 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3171 #if defined(ENABLE_SSA)
3173 GET_NEW_VAR(sd, new_index, i);
3190 coalescing_boundary = sd.new;
3191 iptr->flags.bits |= INS_FLAG_CHECK;
3192 COUNT(count_check_null);
3193 COUNT(count_check_bound);
3194 COUNT(count_pcmd_mem);
3195 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3202 coalescing_boundary = sd.new;
3203 iptr->flags.bits |= INS_FLAG_CHECK;
3204 COUNT(count_check_null);
3205 COUNT(count_check_bound);
3206 COUNT(count_pcmd_mem);
3207 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3210 /* pop 0 push 0 iinc */
3213 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3214 #if defined(ENABLE_SSA)
3217 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3221 last_store_boundary[iptr->s1.varindex] = sd.new;
3224 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3229 if ((copy->varkind == LOCALVAR) &&
3230 (copy->varnum == iptr->s1.varindex))
3232 assert(IS_LOCALVAR(copy));
3238 #if defined(ENABLE_SSA)
3242 iptr->dst.varindex = iptr->s1.varindex;
3245 /* pop 1 push 0 store */
3254 i = opcode - ICMD_ISTORE; /* type */
3255 javaindex = iptr->dst.varindex;
3256 j = iptr->dst.varindex =
3257 jd->local_map[javaindex * 5 + i];
3259 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3261 iptr->sx.s23.s3.javaindex = javaindex;
3263 if (curstack->type == TYPE_RET) {
3264 iptr->flags.bits |= INS_FLAG_RETADDR;
3265 iptr->sx.s23.s2.retaddrnr =
3266 UNUSED - (1 + sd.var[j].vv.retaddr->nr);
3267 sd.javalocals[javaindex] = iptr->sx.s23.s2.retaddrnr;
3270 sd.javalocals[javaindex] = j;
3272 /* invalidate the following javalocal for 2-word types */
3274 if (IS_2_WORD_TYPE(i)) {
3275 sd.javalocals[javaindex+1] = UNUSED;
3276 iptr->flags.bits |= INS_FLAG_KILL_NEXT;
3279 /* invalidate 2-word types if second half was overwritten */
3281 if (javaindex > 0 && (i = sd.javalocals[javaindex-1]) != UNUSED) {
3282 if (IS_2_WORD_TYPE(sd.var[i].type)) {
3283 sd.javalocals[javaindex-1] = UNUSED;
3284 iptr->flags.bits |= INS_FLAG_KILL_PREV;
3288 #if defined(ENABLE_STATISTICS)
3291 i = sd.new - curstack;
3293 count_store_length[20]++;
3295 count_store_length[i]++;
3298 count_store_depth[10]++;
3300 count_store_depth[i]++;
3304 #if defined(ENABLE_SSA)
3307 /* check for conflicts as described in Figure 5.2 */
3309 copy = curstack->prev;
3312 if ((copy->varkind == LOCALVAR) &&
3313 (copy->varnum == j))
3315 copy->varkind = TEMPVAR;
3316 assert(IS_LOCALVAR(copy));
3323 /* if the variable is already coalesced, don't bother */
3325 /* We do not need to check against INOUT, as invars */
3326 /* are always before the coalescing boundary. */
3328 if (curstack->varkind == LOCALVAR)
3331 /* there is no STORE Lj while curstack is live */
3333 if (curstack < last_store_boundary[javaindex])
3334 goto assume_conflict;
3336 /* curstack must be after the coalescing boundary */
3338 if (curstack < coalescing_boundary)
3339 goto assume_conflict;
3341 /* there is no DEF LOCALVAR(j) while curstack is live */
3343 copy = sd.new; /* most recent stackslot created + 1 */
3344 while (--copy > curstack) {
3345 if (copy->varkind == LOCALVAR && copy->varnum == j)
3346 goto assume_conflict;
3349 /* coalesce the temporary variable with Lj */
3350 assert((curstack->varkind == TEMPVAR)
3351 || (curstack->varkind == UNDEFVAR));
3352 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3353 assert(!IS_INOUT(curstack));
3354 assert(!IS_PREALLOC(curstack));
3356 assert(curstack->creator);
3357 assert(curstack->creator->dst.varindex == curstack->varnum);
3358 assert(!(curstack->flags & PASSTHROUGH));
3359 RELEASE_INDEX(sd, curstack);
3360 curstack->varkind = LOCALVAR;
3361 curstack->varnum = j;
3362 curstack->creator->dst.varindex = j;
3365 /* revert the coalescing, if it has been done earlier */
3367 if ((curstack->varkind == LOCALVAR)
3368 && (curstack->varnum == j))
3370 assert(IS_LOCALVAR(curstack));
3371 SET_TEMPVAR(curstack);
3374 /* remember the stack boundary at this store */
3376 last_store_boundary[javaindex] = sd.new;
3377 #if defined(ENABLE_SSA)
3378 } /* if (ls != NULL) */
3381 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3384 STORE(opcode - ICMD_ISTORE, j);
3390 coalescing_boundary = sd.new;
3391 iptr->flags.bits |= INS_FLAG_CHECK;
3392 COUNT(count_check_null);
3393 COUNT(count_check_bound);
3394 COUNT(count_pcmd_mem);
3396 bte = builtintable_get_internal(BUILTIN_canstore);
3399 if (md->memuse > rd->memuse)
3400 rd->memuse = md->memuse;
3401 if (md->argintreguse > rd->argintreguse)
3402 rd->argintreguse = md->argintreguse;
3403 /* XXX non-leaf method? */
3405 /* make all stack variables saved */
3409 sd.var[copy->varnum].flags |= SAVEDVAR;
3410 /* in case copy->varnum is/will be a LOCALVAR */
3411 /* once and set back to a non LOCALVAR */
3412 /* the correct SAVEDVAR flag has to be */
3413 /* remembered in copy->flags, too */
3414 copy->flags |= SAVEDVAR;
3418 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3425 coalescing_boundary = sd.new;
3426 iptr->flags.bits |= INS_FLAG_CHECK;
3427 COUNT(count_check_null);
3428 COUNT(count_check_bound);
3429 COUNT(count_pcmd_mem);
3430 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3437 coalescing_boundary = sd.new;
3438 iptr->flags.bits |= INS_FLAG_CHECK;
3439 COUNT(count_check_null);
3440 COUNT(count_check_bound);
3441 COUNT(count_pcmd_mem);
3442 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3448 #ifdef ENABLE_VERIFIER
3451 if (IS_2_WORD_TYPE(curstack->type))
3452 goto throw_stack_category_error;
3463 coalescing_boundary = sd.new;
3464 /* Assert here that no LOCAL or INOUTS get */
3465 /* preallocated, since tha macros are not */
3466 /* available in md-abi.c! */
3467 if (IS_TEMPVAR(curstack))
3468 md_return_alloc(jd, curstack);
3469 COUNT(count_pcmd_return);
3470 OP1_0(opcode - ICMD_IRETURN);
3471 superblockend = true;
3472 sd.jd->returncount++;
3473 sd.jd->returnblock = sd.bptr;
3477 coalescing_boundary = sd.new;
3478 COUNT(count_check_null);
3480 curstack = NULL; stackdepth = 0;
3481 superblockend = true;
3484 case ICMD_PUTSTATIC:
3485 coalescing_boundary = sd.new;
3486 COUNT(count_pcmd_mem);
3487 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3488 OP1_0(fmiref->parseddesc.fd->type);
3491 /* pop 1 push 0 branch */
3494 case ICMD_IFNONNULL:
3495 COUNT(count_pcmd_bra);
3496 OP1_BRANCH(TYPE_ADR);
3506 COUNT(count_pcmd_bra);
3507 /* iptr->sx.val.i is set implicitly in parse by
3508 clearing the memory or from IF_ICMPxx
3511 OP1_BRANCH(TYPE_INT);
3512 /* iptr->sx.val.i = 0; */
3516 /* pop 0 push 0 branch */
3519 COUNT(count_pcmd_bra);
3522 superblockend = true;
3525 /* pop 1 push 0 table branch */
3527 case ICMD_TABLESWITCH:
3528 COUNT(count_pcmd_table);
3529 OP1_BRANCH(TYPE_INT);
3531 table = iptr->dst.table;
3532 BRANCH_TARGET(*table, tbptr);
3535 i = iptr->sx.s23.s3.tablehigh
3536 - iptr->sx.s23.s2.tablelow + 1;
3539 BRANCH_TARGET(*table, tbptr);
3542 superblockend = true;
3545 /* pop 1 push 0 table branch */
3547 case ICMD_LOOKUPSWITCH:
3548 COUNT(count_pcmd_table);
3549 OP1_BRANCH(TYPE_INT);
3551 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3553 lookup = iptr->dst.lookup;
3555 i = iptr->sx.s23.s2.lookupcount;
3558 BRANCH_TARGET(lookup->target, tbptr);
3561 superblockend = true;
3564 case ICMD_MONITORENTER:
3565 case ICMD_MONITOREXIT:
3566 coalescing_boundary = sd.new;
3567 COUNT(count_check_null);
3571 /* pop 2 push 0 branch */
3573 case ICMD_IF_ICMPEQ:
3574 case ICMD_IF_ICMPNE:
3575 case ICMD_IF_ICMPLT:
3576 case ICMD_IF_ICMPGE:
3577 case ICMD_IF_ICMPGT:
3578 case ICMD_IF_ICMPLE:
3579 COUNT(count_pcmd_bra);
3580 OP2_BRANCH(TYPE_INT, TYPE_INT);
3584 case ICMD_IF_ACMPEQ:
3585 case ICMD_IF_ACMPNE:
3586 COUNT(count_pcmd_bra);
3587 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3594 coalescing_boundary = sd.new;
3595 COUNT(count_check_null);
3596 COUNT(count_pcmd_mem);
3597 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3598 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3603 if (!IS_2_WORD_TYPE(curstack->type)) {
3605 #ifdef ENABLE_VERIFIER
3608 if (IS_2_WORD_TYPE(curstack->prev->type))
3609 goto throw_stack_category_error;
3612 OP2_0_ANY_ANY; /* pop two slots */
3615 iptr->opc = ICMD_POP;
3616 OP1_0_ANY; /* pop one (two-word) slot */
3620 /* pop 0 push 1 dup */
3623 #ifdef ENABLE_VERIFIER
3626 if (IS_2_WORD_TYPE(curstack->type))
3627 goto throw_stack_category_error;
3630 COUNT(count_dup_instruction);
3636 coalescing_boundary = sd.new - 1;
3641 if (IS_2_WORD_TYPE(curstack->type)) {
3643 iptr->opc = ICMD_DUP;
3648 /* ..., ????, cat1 */
3649 #ifdef ENABLE_VERIFIER
3651 if (IS_2_WORD_TYPE(curstack->prev->type))
3652 goto throw_stack_category_error;
3655 src1 = curstack->prev;
3658 COPY_UP(src1); iptr++; len--;
3661 coalescing_boundary = sd.new;
3665 /* pop 2 push 3 dup */
3668 #ifdef ENABLE_VERIFIER
3671 if (IS_2_WORD_TYPE(curstack->type) ||
3672 IS_2_WORD_TYPE(curstack->prev->type))
3673 goto throw_stack_category_error;
3678 src1 = curstack->prev;
3683 /* move non-temporary sources out of the way */
3684 if (!IS_TEMPVAR(src2)) {
3685 MOVE_TO_TEMP(src2); iptr++; len--;
3688 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3690 MOVE_UP(src1); iptr++; len--;
3691 MOVE_UP(src2); iptr++; len--;
3693 COPY_DOWN(curstack, dst1);
3695 coalescing_boundary = sd.new;
3700 if (IS_2_WORD_TYPE(curstack->type)) {
3701 /* ..., ????, cat2 */
3702 #ifdef ENABLE_VERIFIER
3704 if (IS_2_WORD_TYPE(curstack->prev->type))
3705 goto throw_stack_category_error;
3708 iptr->opc = ICMD_DUP_X1;
3712 /* ..., ????, cat1 */
3713 #ifdef ENABLE_VERIFIER
3716 if (IS_2_WORD_TYPE(curstack->prev->type)
3717 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3718 goto throw_stack_category_error;
3723 src1 = curstack->prev->prev;
3724 src2 = curstack->prev;
3726 POPANY; POPANY; POPANY;
3729 /* move non-temporary sources out of the way */
3730 if (!IS_TEMPVAR(src2)) {
3731 MOVE_TO_TEMP(src2); iptr++; len--;
3733 if (!IS_TEMPVAR(src3)) {
3734 MOVE_TO_TEMP(src3); iptr++; len--;
3737 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3738 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3740 MOVE_UP(src1); iptr++; len--;
3741 MOVE_UP(src2); iptr++; len--;
3742 MOVE_UP(src3); iptr++; len--;
3744 COPY_DOWN(curstack, dst2); iptr++; len--;
3745 COPY_DOWN(curstack->prev, dst1);
3747 coalescing_boundary = sd.new;
3751 /* pop 3 push 4 dup */
3755 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3756 /* ..., cat2, ???? */
3757 #ifdef ENABLE_VERIFIER
3759 if (IS_2_WORD_TYPE(curstack->type))
3760 goto throw_stack_category_error;
3763 iptr->opc = ICMD_DUP_X1;
3767 /* ..., cat1, ???? */
3768 #ifdef ENABLE_VERIFIER
3771 if (IS_2_WORD_TYPE(curstack->type)
3772 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3773 goto throw_stack_category_error;
3777 src1 = curstack->prev->prev;
3778 src2 = curstack->prev;
3780 POPANY; POPANY; POPANY;
3783 /* move non-temporary sources out of the way */
3784 if (!IS_TEMPVAR(src2)) {
3785 MOVE_TO_TEMP(src2); iptr++; len--;
3787 if (!IS_TEMPVAR(src3)) {
3788 MOVE_TO_TEMP(src3); iptr++; len--;
3791 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3793 MOVE_UP(src1); iptr++; len--;
3794 MOVE_UP(src2); iptr++; len--;
3795 MOVE_UP(src3); iptr++; len--;
3797 COPY_DOWN(curstack, dst1);
3799 coalescing_boundary = sd.new;
3805 if (IS_2_WORD_TYPE(curstack->type)) {
3806 /* ..., ????, cat2 */
3807 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3808 /* ..., cat2, cat2 */
3809 iptr->opc = ICMD_DUP_X1;
3813 /* ..., cat1, cat2 */
3814 #ifdef ENABLE_VERIFIER
3817 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3818 goto throw_stack_category_error;
3821 iptr->opc = ICMD_DUP_X2;
3827 /* ..., ????, ????, cat1 */
3829 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3830 /* ..., cat2, ????, cat1 */
3831 #ifdef ENABLE_VERIFIER
3833 if (IS_2_WORD_TYPE(curstack->prev->type))
3834 goto throw_stack_category_error;
3837 iptr->opc = ICMD_DUP2_X1;
3841 /* ..., cat1, ????, cat1 */
3842 #ifdef ENABLE_VERIFIER
3845 if (IS_2_WORD_TYPE(curstack->prev->type)
3846 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3847 goto throw_stack_category_error;
3851 src1 = curstack->prev->prev->prev;
3852 src2 = curstack->prev->prev;
3853 src3 = curstack->prev;
3855 POPANY; POPANY; POPANY; POPANY;
3858 /* move non-temporary sources out of the way */
3859 if (!IS_TEMPVAR(src2)) {
3860 MOVE_TO_TEMP(src2); iptr++; len--;
3862 if (!IS_TEMPVAR(src3)) {
3863 MOVE_TO_TEMP(src3); iptr++; len--;
3865 if (!IS_TEMPVAR(src4)) {
3866 MOVE_TO_TEMP(src4); iptr++; len--;
3869 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3870 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3872 MOVE_UP(src1); iptr++; len--;
3873 MOVE_UP(src2); iptr++; len--;
3874 MOVE_UP(src3); iptr++; len--;
3875 MOVE_UP(src4); iptr++; len--;
3877 COPY_DOWN(curstack, dst2); iptr++; len--;
3878 COPY_DOWN(curstack->prev, dst1);
3880 coalescing_boundary = sd.new;
3884 /* pop 2 push 2 swap */
3887 #ifdef ENABLE_VERIFIER
3890 if (IS_2_WORD_TYPE(curstack->type)
3891 || IS_2_WORD_TYPE(curstack->prev->type))
3892 goto throw_stack_category_error;
3896 src1 = curstack->prev;
3901 /* move non-temporary sources out of the way */
3902 if (!IS_TEMPVAR(src1)) {
3903 MOVE_TO_TEMP(src1); iptr++; len--;
3906 MOVE_UP(src2); iptr++; len--;
3909 coalescing_boundary = sd.new;
3916 coalescing_boundary = sd.new;
3917 #if !SUPPORT_DIVISION
3918 bte = iptr->sx.s23.s3.bte;
3921 if (md->memuse > rd->memuse)
3922 rd->memuse = md->memuse;
3923 if (md->argintreguse > rd->argintreguse)
3924 rd->argintreguse = md->argintreguse;
3926 /* make all stack variables saved */
3930 sd.var[copy->varnum].flags |= SAVEDVAR;
3931 copy->flags |= SAVEDVAR;
3936 #endif /* !SUPPORT_DIVISION */
3947 COUNT(count_pcmd_op);
3948 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3953 coalescing_boundary = sd.new;
3954 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3955 bte = iptr->sx.s23.s3.bte;
3958 if (md->memuse > rd->memuse)
3959 rd->memuse = md->memuse;
3960 if (md->argintreguse > rd->argintreguse)
3961 rd->argintreguse = md->argintreguse;
3962 /* XXX non-leaf method? */
3964 /* make all stack variables saved */
3968 sd.var[copy->varnum].flags |= SAVEDVAR;
3969 copy->flags |= SAVEDVAR;
3974 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3979 #if SUPPORT_LONG_LOGICAL
3983 #endif /* SUPPORT_LONG_LOGICAL */
3984 COUNT(count_pcmd_op);
3985 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3991 COUNT(count_pcmd_op);
3992 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
4000 COUNT(count_pcmd_op);
4001 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
4009 COUNT(count_pcmd_op);
4010 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
4014 COUNT(count_pcmd_op);
4015 #if SUPPORT_LONG_CMP_CONST
4016 if ((len == 0) || (iptr[1].sx.val.i != 0))
4019 switch (iptr[1].opc) {
4021 iptr->opc = ICMD_IF_LCMPEQ;
4023 iptr->dst.insindex = iptr[1].dst.insindex;
4024 iptr[1].opc = ICMD_NOP;
4026 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
4029 COUNT(count_pcmd_bra);
4032 iptr->opc = ICMD_IF_LCMPNE;
4033 goto icmd_lcmp_if_tail;
4035 iptr->opc = ICMD_IF_LCMPLT;
4036 goto icmd_lcmp_if_tail;
4038 iptr->opc = ICMD_IF_LCMPGT;
4039 goto icmd_lcmp_if_tail;
4041 iptr->opc = ICMD_IF_LCMPLE;
4042 goto icmd_lcmp_if_tail;
4044 iptr->opc = ICMD_IF_LCMPGE;
4045 goto icmd_lcmp_if_tail;
4051 #endif /* SUPPORT_LONG_CMP_CONST */
4052 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
4055 /* XXX why is this deactivated? */
4058 COUNT(count_pcmd_op);
4059 if ((len == 0) || (iptr[1].sx.val.i != 0))
4062 switch (iptr[1].opc) {
4064 iptr->opc = ICMD_IF_FCMPEQ;
4066 iptr->dst.insindex = iptr[1].dst.insindex;
4067 iptr[1].opc = ICMD_NOP;
4069 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
4072 COUNT(count_pcmd_bra);
4075 iptr->opc = ICMD_IF_FCMPNE;
4076 goto icmd_if_fcmpl_tail;
4078 iptr->opc = ICMD_IF_FCMPL_LT;
4079 goto icmd_if_fcmpl_tail;
4081 iptr->opc = ICMD_IF_FCMPL_GT;
4082 goto icmd_if_fcmpl_tail;
4084 iptr->opc = ICMD_IF_FCMPL_LE;
4085 goto icmd_if_fcmpl_tail;
4087 iptr->opc = ICMD_IF_FCMPL_GE;
4088 goto icmd_if_fcmpl_tail;
4095 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4099 COUNT(count_pcmd_op);
4100 if ((len == 0) || (iptr[1].sx.val.i != 0))
4103 switch (iptr[1].opc) {
4105 iptr->opc = ICMD_IF_FCMPEQ;
4107 iptr->dst.insindex = iptr[1].dst.insindex;
4108 iptr[1].opc = ICMD_NOP;
4110 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
4113 COUNT(count_pcmd_bra);
4116 iptr->opc = ICMD_IF_FCMPNE;
4117 goto icmd_if_fcmpg_tail;
4119 iptr->opc = ICMD_IF_FCMPG_LT;
4120 goto icmd_if_fcmpg_tail;
4122 iptr->opc = ICMD_IF_FCMPG_GT;
4123 goto icmd_if_fcmpg_tail;
4125 iptr->opc = ICMD_IF_FCMPG_LE;
4126 goto icmd_if_fcmpg_tail;
4128 iptr->opc = ICMD_IF_FCMPG_GE;
4129 goto icmd_if_fcmpg_tail;
4136 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4140 COUNT(count_pcmd_op);
4141 if ((len == 0) || (iptr[1].sx.val.i != 0))
4144 switch (iptr[1].opc) {
4146 iptr->opc = ICMD_IF_DCMPEQ;
4148 iptr->dst.insindex = iptr[1].dst.insindex;
4149 iptr[1].opc = ICMD_NOP;
4151 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4154 COUNT(count_pcmd_bra);
4157 iptr->opc = ICMD_IF_DCMPNE;
4158 goto icmd_if_dcmpl_tail;
4160 iptr->opc = ICMD_IF_DCMPL_LT;
4161 goto icmd_if_dcmpl_tail;
4163 iptr->opc = ICMD_IF_DCMPL_GT;
4164 goto icmd_if_dcmpl_tail;
4166 iptr->opc = ICMD_IF_DCMPL_LE;
4167 goto icmd_if_dcmpl_tail;
4169 iptr->opc = ICMD_IF_DCMPL_GE;
4170 goto icmd_if_dcmpl_tail;
4177 OPTT2_1(TYPE_DBL, TYPE_INT);
4181 COUNT(count_pcmd_op);
4182 if ((len == 0) || (iptr[1].sx.val.i != 0))
4185 switch (iptr[1].opc) {
4187 iptr->opc = ICMD_IF_DCMPEQ;
4189 iptr->dst.insindex = iptr[1].dst.insindex;
4190 iptr[1].opc = ICMD_NOP;
4192 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4195 COUNT(count_pcmd_bra);
4198 iptr->opc = ICMD_IF_DCMPNE;
4199 goto icmd_if_dcmpg_tail;
4201 iptr->opc = ICMD_IF_DCMPG_LT;
4202 goto icmd_if_dcmpg_tail;
4204 iptr->opc = ICMD_IF_DCMPG_GT;
4205 goto icmd_if_dcmpg_tail;
4207 iptr->opc = ICMD_IF_DCMPG_LE;
4208 goto icmd_if_dcmpg_tail;
4210 iptr->opc = ICMD_IF_DCMPG_GE;
4211 goto icmd_if_dcmpg_tail;
4218 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4223 COUNT(count_pcmd_op);
4224 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4229 COUNT(count_pcmd_op);
4230 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4239 case ICMD_INT2SHORT:
4240 COUNT(count_pcmd_op);
4241 OP1_1(TYPE_INT, TYPE_INT);
4244 COUNT(count_pcmd_op);
4245 OP1_1(TYPE_LNG, TYPE_LNG);
4248 COUNT(count_pcmd_op);
4249 OP1_1(TYPE_FLT, TYPE_FLT);
4252 COUNT(count_pcmd_op);
4253 OP1_1(TYPE_DBL, TYPE_DBL);
4257 COUNT(count_pcmd_op);
4258 OP1_1(TYPE_INT, TYPE_LNG);
4261 COUNT(count_pcmd_op);
4262 OP1_1(TYPE_INT, TYPE_FLT);
4265 COUNT(count_pcmd_op);
4266 OP1_1(TYPE_INT, TYPE_DBL);
4269 COUNT(count_pcmd_op);
4270 OP1_1(TYPE_LNG, TYPE_INT);
4273 COUNT(count_pcmd_op);
4274 OP1_1(TYPE_LNG, TYPE_FLT);
4277 COUNT(count_pcmd_op);
4278 OP1_1(TYPE_LNG, TYPE_DBL);
4281 COUNT(count_pcmd_op);
4282 OP1_1(TYPE_FLT, TYPE_INT);
4285 COUNT(count_pcmd_op);
4286 OP1_1(TYPE_FLT, TYPE_LNG);
4289 COUNT(count_pcmd_op);
4290 OP1_1(TYPE_FLT, TYPE_DBL);
4293 COUNT(count_pcmd_op);
4294 OP1_1(TYPE_DBL, TYPE_INT);
4297 COUNT(count_pcmd_op);
4298 OP1_1(TYPE_DBL, TYPE_LNG);
4301 COUNT(count_pcmd_op);
4302 OP1_1(TYPE_DBL, TYPE_FLT);
4305 case ICMD_CHECKCAST:
4306 coalescing_boundary = sd.new;
4307 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4308 /* array type cast-check */
4310 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4313 if (md->memuse > rd->memuse)
4314 rd->memuse = md->memuse;
4315 if (md->argintreguse > rd->argintreguse)
4316 rd->argintreguse = md->argintreguse;
4318 /* make all stack variables saved */
4322 sd.var[copy->varnum].flags |= SAVEDVAR;
4323 copy->flags |= SAVEDVAR;
4327 OP1_1(TYPE_ADR, TYPE_ADR);
4330 case ICMD_INSTANCEOF:
4331 case ICMD_ARRAYLENGTH:
4332 coalescing_boundary = sd.new;
4333 OP1_1(TYPE_ADR, TYPE_INT);
4337 case ICMD_ANEWARRAY:
4338 coalescing_boundary = sd.new;
4339 OP1_1(TYPE_INT, TYPE_ADR);
4343 coalescing_boundary = sd.new;
4344 COUNT(count_check_null);
4345 COUNT(count_pcmd_mem);
4346 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4347 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4352 case ICMD_GETSTATIC:
4353 coalescing_boundary = sd.new;
4354 COUNT(count_pcmd_mem);
4355 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4356 OP0_1(fmiref->parseddesc.fd->type);
4360 coalescing_boundary = sd.new;
4367 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4368 tbptr->type = BBTYPE_SBR;
4370 assert(sd.bptr->next); /* XXX exception */
4371 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4372 #if defined(ENABLE_VERIFIER)
4373 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4376 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4380 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4382 /* We need to check for overflow right here because
4383 * the pushed value is poped afterwards */
4386 superblockend = true;
4387 /* XXX should not be marked as interface, as it does not need to be */
4388 /* allocated. Same for the invar of the target. */
4391 /* pop many push any */
4395 bte = iptr->sx.s23.s3.bte;
4399 case ICMD_INVOKESTATIC:
4400 case ICMD_INVOKESPECIAL:
4401 case ICMD_INVOKEVIRTUAL:
4402 case ICMD_INVOKEINTERFACE:
4403 COUNT(count_pcmd_met);
4405 /* Check for functions to replace with builtin
4408 if (builtintable_replace_function(iptr))
4411 INSTRUCTION_GET_METHODDESC(iptr, md);
4412 /* XXX resurrect this COUNT? */
4413 /* if (lm->flags & ACC_STATIC) */
4414 /* {COUNT(count_check_null);} */
4418 coalescing_boundary = sd.new;
4422 if (md->memuse > rd->memuse)
4423 rd->memuse = md->memuse;
4424 if (md->argintreguse > rd->argintreguse)
4425 rd->argintreguse = md->argintreguse;
4426 if (md->argfltreguse > rd->argfltreguse)
4427 rd->argfltreguse = md->argfltreguse;
4431 iptr->s1.argcount = stackdepth;
4432 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4435 for (i-- ; i >= 0; i--) {
4436 iptr->sx.s23.s2.args[i] = copy->varnum;
4438 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4439 /* -> won't help anyway */
4440 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4442 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4443 /* If we pass float arguments in integer argument registers, we
4444 * are not allowed to precolor them here. Floats have to be moved
4445 * to this regs explicitly in codegen().
4446 * Only arguments that are passed by stack anyway can be precolored
4447 * (michi 2005/07/24) */
4448 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4449 (!IS_FLT_DBL_TYPE(copy->type)
4450 || md->params[i].inmemory)) {
4452 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4457 if (md->params[i].inmemory) {
4458 sd.var[copy->varnum].vv.regoff =
4459 md->params[i].regoff;
4460 sd.var[copy->varnum].flags |=
4464 if (IS_FLT_DBL_TYPE(copy->type)) {
4465 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4466 assert(0); /* XXX is this assert ok? */
4468 sd.var[copy->varnum].vv.regoff =
4469 rd->argfltregs[md->params[i].regoff];
4470 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4473 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4474 if (IS_2_WORD_TYPE(copy->type))
4475 sd.var[copy->varnum].vv.regoff =
4476 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4477 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4480 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4481 sd.var[copy->varnum].vv.regoff =
4482 rd->argintregs[md->params[i].regoff];
4490 /* deal with live-through stack slots "under" the */
4496 iptr->sx.s23.s2.args[i++] = copy->varnum;
4497 sd.var[copy->varnum].flags |= SAVEDVAR;
4498 copy->flags |= SAVEDVAR | PASSTHROUGH;
4502 /* pop the arguments */
4511 /* push the return value */
4513 if (md->returntype.type != TYPE_VOID) {
4514 GET_NEW_VAR(sd, new_index, md->returntype.type);
4515 DST(md->returntype.type, new_index);
4520 case ICMD_INLINE_START:
4521 case ICMD_INLINE_END:
4526 case ICMD_MULTIANEWARRAY:
4527 coalescing_boundary = sd.new;
4528 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4529 rd->argintreguse = MIN(3, INT_ARG_CNT);
4531 i = iptr->s1.argcount;
4535 iptr->sx.s23.s2.args = DMNEW(s4, i);
4537 #if defined(SPECIALMEMUSE)
4538 # if defined(__DARWIN__)
4539 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4540 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4542 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4543 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4546 # if defined(__I386__)
4547 if (rd->memuse < i + 3)
4548 rd->memuse = i + 3; /* n integer args spilled on stack */
4549 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4550 if (rd->memuse < i + 2)
4551 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4554 rd->memuse = i; /* n integer args spilled on stack */
4555 # endif /* defined(__I386__) */
4559 /* check INT type here? Currently typecheck does this. */
4560 iptr->sx.s23.s2.args[i] = copy->varnum;
4561 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4562 && (!IS_INOUT(copy))
4563 && (!IS_LOCALVAR(copy)) ) {
4564 copy->varkind = ARGVAR;
4565 sd.var[copy->varnum].flags |=
4566 INMEMORY & PREALLOC;
4567 #if defined(SPECIALMEMUSE)
4568 # if defined(__DARWIN__)
4569 sd.var[copy->varnum].vv.regoff = i +
4570 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4572 sd.var[copy->varnum].vv.regoff = i +
4573 LA_SIZE_IN_POINTERS + 3;
4576 # if defined(__I386__)
4577 sd.var[copy->varnum].vv.regoff = i + 3;
4578 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4579 sd.var[copy->varnum].vv.regoff = i + 2;
4581 sd.var[copy->varnum].vv.regoff = i;
4582 # endif /* defined(__I386__) */
4583 #endif /* defined(SPECIALMEMUSE) */
4588 sd.var[copy->varnum].flags |= SAVEDVAR;
4589 copy->flags |= SAVEDVAR;
4593 i = iptr->s1.argcount;
4598 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4599 DST(TYPE_ADR, new_index);
4605 new_internalerror("Unknown ICMD %d", opcode);
4611 } /* while instructions */
4613 /* show state after last instruction */
4615 #if defined(STACK_VERBOSE)
4616 stack_verbose_show_state(&sd, NULL, curstack);
4619 /* stack slots at basic block end become interfaces */
4621 sd.bptr->outdepth = stackdepth;
4622 sd.bptr->outvars = DMNEW(s4, stackdepth);
4625 for (copy = curstack; copy; i--, copy = copy->prev) {
4629 /* with the new vars rd->interfaces will be removed */
4630 /* and all in and outvars have to be STACKVARS! */
4631 /* in the moment i.e. SWAP with in and out vars can */
4632 /* create an unresolvable conflict */
4637 v = sd.var + copy->varnum;
4640 /* do not allocate variables for returnAddresses */
4642 if (t != TYPE_RET) {
4643 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4644 /* no interface var until now for this depth and */
4646 jd->interface_map[i*5 + t].flags = v->flags;
4649 jd->interface_map[i*5 + t].flags |= v->flags;
4653 sd.bptr->outvars[i] = copy->varnum;
4656 /* check if interface slots at basic block begin must be saved */
4658 for (i=0; i<sd.bptr->indepth; ++i) {
4659 varinfo *v = sd.var + sd.bptr->invars[i];
4664 if (t != TYPE_RET) {
4665 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4666 /* no interface var until now for this depth and */
4668 jd->interface_map[i*5 + t].flags = v->flags;
4671 jd->interface_map[i*5 + t].flags |= v->flags;
4676 /* store the number of this block's variables */
4678 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4680 #if defined(STACK_VERBOSE)
4681 stack_verbose_block_exit(&sd, superblockend);
4684 /* reach the following block, if any */
4687 if (!stack_reach_next_block(&sd))
4692 } while (sd.repeat && !deadcode);
4694 /* reset locals of TYPE_RET to TYPE_ADR */
4696 for (i=0; i<sd.localcount; ++i) {
4697 if (sd.var[i].type == TYPE_RET)
4698 sd.var[i].type = TYPE_ADR;
4701 /* mark temporaries of TYPE_RET as PREALLOC to avoid allocation */
4703 for (i=sd.localcount; i<sd.vartop; ++i) {
4704 if (sd.var[i].type == TYPE_RET)
4705 sd.var[i].flags |= PREALLOC;
4708 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4710 ex = jd->exceptiontable;
4711 for (; ex != NULL; ex = ex->down) {
4712 if (ex->start == ex->end) {
4713 assert(ex->end->next);
4714 ex->end = ex->end->next;
4718 /* store number of created variables */
4720 jd->vartop = sd.vartop;
4722 /* gather statistics *****************************************************/
4724 #if defined(ENABLE_STATISTICS)
4726 if (jd->basicblockcount > count_max_basic_blocks)
4727 count_max_basic_blocks = jd->basicblockcount;
4728 count_basic_blocks += jd->basicblockcount;
4729 if (jd->instructioncount > count_max_javainstr)
4730 count_max_javainstr = jd->instructioncount;
4731 count_javainstr += jd->instructioncount;
4732 if (jd->stackcount > count_upper_bound_new_stack)
4733 count_upper_bound_new_stack = jd->stackcount;
4734 if ((sd.new - jd->stack) > count_max_new_stack)
4735 count_max_new_stack = (sd.new - jd->stack);
4737 sd.bptr = jd->basicblocks;
4738 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4739 if (sd.bptr->flags > BBREACHED) {
4740 if (sd.bptr->indepth >= 10)
4741 count_block_stack[10]++;
4743 count_block_stack[sd.bptr->indepth]++;
4744 len = sd.bptr->icount;
4746 count_block_size_distribution[len]++;
4748 count_block_size_distribution[10]++;
4750 count_block_size_distribution[11]++;
4752 count_block_size_distribution[12]++;
4754 count_block_size_distribution[13]++;
4756 count_block_size_distribution[14]++;
4758 count_block_size_distribution[15]++;
4760 count_block_size_distribution[16]++;
4762 count_block_size_distribution[17]++;
4766 if (iteration_count == 1)
4767 count_analyse_iterations[0]++;
4768 else if (iteration_count == 2)
4769 count_analyse_iterations[1]++;
4770 else if (iteration_count == 3)
4771 count_analyse_iterations[2]++;
4772 else if (iteration_count == 4)
4773 count_analyse_iterations[3]++;
4775 count_analyse_iterations[4]++;
4777 if (jd->basicblockcount <= 5)
4778 count_method_bb_distribution[0]++;
4779 else if (jd->basicblockcount <= 10)
4780 count_method_bb_distribution[1]++;
4781 else if (jd->basicblockcount <= 15)
4782 count_method_bb_distribution[2]++;
4783 else if (jd->basicblockcount <= 20)
4784 count_method_bb_distribution[3]++;
4785 else if (jd->basicblockcount <= 30)
4786 count_method_bb_distribution[4]++;
4787 else if (jd->basicblockcount <= 40)
4788 count_method_bb_distribution[5]++;
4789 else if (jd->basicblockcount <= 50)
4790 count_method_bb_distribution[6]++;
4791 else if (jd->basicblockcount <= 75)
4792 count_method_bb_distribution[7]++;
4794 count_method_bb_distribution[8]++;
4796 #endif /* defined(ENABLE_STATISTICS) */
4798 /* everything's ok *******************************************************/
4802 /* goto labels for throwing verifier exceptions **************************/
4804 #if defined(ENABLE_VERIFIER)
4806 throw_stack_underflow:
4807 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4810 throw_stack_overflow:
4811 exceptions_throw_verifyerror(m, "Stack size too large");
4814 throw_stack_type_error:
4815 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4818 throw_stack_category_error:
4819 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4826 /* functions for verbose stack analysis output ********************************/
4828 #if defined(STACK_VERBOSE)
4829 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4831 printf("%c", show_jit_type_letters[v->type]);
4832 if (v->type == TYPE_RET)
4833 printf("{L%03d}", v->vv.retaddr->nr);
4837 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4839 assert(index >= 0 && index < sd->vartop);
4840 stack_verbose_show_varinfo(sd, sd->var + index);
4844 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4848 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4850 for (i=0; i<bptr->indepth; ++i) {
4853 stack_verbose_show_variable(sd, bptr->invars[i]);
4858 printf("] javalocals ");
4859 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4860 printf(" inlocals [");
4861 if (bptr->inlocals) {
4862 for (i=0; i<sd->localcount; ++i) {
4865 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4870 printf("] out:%d [", bptr->outdepth);
4871 if (bptr->outvars) {
4872 for (i=0; i<bptr->outdepth; ++i) {
4875 stack_verbose_show_variable(sd, bptr->outvars[i]);
4883 printf(" (clone of L%03d)", bptr->original->nr);
4885 basicblock *b = bptr->copied_to;
4887 printf(" (copied to ");
4888 for (; b; b = b->copied_to)
4889 printf("L%03d ", b->nr);
4896 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4900 printf("======================================== STACK %sANALYSE BLOCK ",
4901 (reanalyse) ? ((sd->bptr->iinstr == NULL) ? "CLONE-" : "RE-") : "");
4902 stack_verbose_show_block(sd, sd->bptr);
4905 if (sd->handlers[0]) {
4906 printf("HANDLERS: ");
4907 for (i=0; sd->handlers[i]; ++i) {
4908 printf("L%03d ", sd->handlers[i]->handler->nr);
4916 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4918 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4919 stack_verbose_show_block(sd, sd->bptr);
4923 static void stack_verbose_show_state(stackdata_t *sd, instruction *iptr, stackptr curstack)
4931 printf(" javalocals ");
4932 show_javalocals_array(sd->jd, sd->javalocals, sd->maxlocals, SHOW_STACK);
4935 for(i = 0, sp = curstack; sp; sp = sp->prev)
4939 stack = MNEW(stackptr, depth);
4940 for(sp = curstack; sp; sp = sp->prev)
4943 for(i=0; i<depth; ++i) {
4947 v = &(sd->var[sp->varnum]);
4949 if (v->flags & INOUT)
4951 if (v->flags & PREALLOC)
4953 printf("%d:%c", sp->varnum, show_jit_type_letters[sp->type]);
4954 if (v->type == TYPE_RET) {
4955 printf("(L%03d)", v->vv.retaddr->nr);
4960 show_icmd(sd->jd, iptr, false, SHOW_PARSE);
4967 * These are local overrides for various environment variables in Emacs.
4968 * Please do not remove this and leave it at the end of the file, where
4969 * Emacs will automagically detect them.
4970 * ---------------------------------------------------------------------
4973 * indent-tabs-mode: t
4977 * vim:noexpandtab:sw=4:ts=4: