1 /* src/vm/jit/stack.c - stack analysis
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
29 Changes: Edwin Steiner
33 $Id: stack.c 5860 2006-10-29 23:37:20Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/show.h"
68 #if defined(ENABLE_DISASSEMBLER)
69 # include "vm/jit/disass.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/stack.h"
75 #if defined(ENABLE_SSA)
76 # include "vm/jit/optimizing/lsra.h"
77 # include "vm/jit/optimizing/ssa.h"
78 #elif defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
82 /*#define STACK_VERBOSE*/
85 /* macro for saving #ifdefs ***************************************************/
87 #if defined(ENABLE_STATISTICS)
88 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
91 if (stackdepth >= 10) \
92 count_store_depth[10]++; \
94 count_store_depth[stackdepth]++; \
97 #else /* !defined(ENABLE_STATISTICS) */
98 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
102 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
105 /* For returnAddresses we use a field of the typeinfo to store from which */
106 /* subroutine the returnAddress will return, if used. */
107 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
108 /* to need it initialised to NULL. This should be investigated. */
110 #if defined(ENABLE_VERIFIER)
111 #define SBRSTART typeinfo.elementclass.any
115 /* stackdata_t *****************************************************************
117 This struct holds internal data during stack analysis.
119 *******************************************************************************/
121 typedef struct stackdata_t stackdata_t;
124 basicblock *bptr; /* the current basic block being analysed */
125 stackptr new; /* next free stackelement */
126 s4 vartop; /* next free variable index */
127 s4 localcount; /* number of locals (at the start of var) */
128 s4 varcount; /* maximum number of variables expected */
129 s4 varsallocated; /* total number of variables allocated */
130 varinfo *var; /* variable array (same as jd->var) */
131 methodinfo *m; /* the method being analysed */
132 jitdata *jd; /* current jitdata */
133 basicblock *last_real_block; /* the last block before the empty one */
134 bool repeat; /* if true, iterate the analysis again */
135 exception_entry **handlers; /* exception handlers for the current block */
136 exception_entry *extableend; /* points to the last exception entry */
137 stackelement exstack; /* instack for exception handlers */
141 /* macros for allocating/releasing variable indices *****************/
143 #define GET_NEW_INDEX(sd, new_varindex) \
145 assert((sd).vartop < (sd).varcount); \
146 (new_varindex) = ((sd).vartop)++; \
149 /* Not implemented now - could be used to reuse varindices. */
150 /* Pay attention to not release a localvar once implementing it! */
151 #define RELEASE_INDEX(sd, varindex)
153 #define GET_NEW_VAR(sd, newvarindex, newtype) \
155 GET_NEW_INDEX((sd), (newvarindex)); \
156 (sd).var[newvarindex].type = (newtype); \
160 /* macros for querying variable properties **************************/
162 #define IS_INOUT(sp) \
163 (sd.var[(sp)->varnum].flags & INOUT)
165 #define IS_PREALLOC(sp) \
166 (sd.var[(sp)->varnum].flags & PREALLOC)
168 #define IS_TEMPVAR(sp) \
169 ( ((sp)->varnum >= sd.localcount) \
170 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
173 #define IS_LOCALVAR_SD(sd, sp) \
174 ((sp)->varnum < (sd).localcount)
176 #define IS_LOCALVAR(sp) \
177 IS_LOCALVAR_SD(sd, (sp))
180 /* macros for setting variable properties ****************************/
182 #define SET_TEMPVAR(sp) \
184 if (IS_LOCALVAR((sp))) { \
185 stack_change_to_tempvar(&sd, (sp), iptr); \
187 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
190 #define SET_PREALLOC(sp) \
192 assert(!IS_LOCALVAR((sp))); \
193 sd.var[(sp)->varnum].flags |= PREALLOC; \
197 /* macros for source operands ***************************************/
200 (iptr->s1.varindex = -1)
202 #define USE_S1(type1) \
205 CHECK_BASIC_TYPE(type1, curstack->type); \
206 iptr->s1.varindex = curstack->varnum; \
212 iptr->s1.varindex = curstack->varnum; \
215 #define USE_S1_S2(type1, type2) \
218 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
219 CHECK_BASIC_TYPE(type2, curstack->type); \
220 iptr->sx.s23.s2.varindex = curstack->varnum; \
221 iptr->s1.varindex = curstack->prev->varnum; \
224 #define USE_S1_S2_ANY_ANY \
227 iptr->sx.s23.s2.varindex = curstack->varnum; \
228 iptr->s1.varindex = curstack->prev->varnum; \
231 #define USE_S1_S2_S3(type1, type2, type3) \
234 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
235 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
236 CHECK_BASIC_TYPE(type3, curstack->type); \
237 iptr->sx.s23.s3.varindex = curstack->varnum; \
238 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
239 iptr->s1.varindex = curstack->prev->prev->varnum; \
242 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
245 if (curstack->varkind == UNDEFVAR) \
246 curstack->varkind = TEMPVAR; \
247 curstack = curstack->prev; \
250 #define POP_S1(type1) \
253 if (curstack->varkind == UNDEFVAR) \
254 curstack->varkind = TEMPVAR; \
255 curstack = curstack->prev; \
261 if (curstack->varkind == UNDEFVAR) \
262 curstack->varkind = TEMPVAR; \
263 curstack = curstack->prev; \
266 #define POP_S1_S2(type1, type2) \
268 USE_S1_S2(type1, type2); \
269 if (curstack->varkind == UNDEFVAR) \
270 curstack->varkind = TEMPVAR; \
271 if (curstack->prev->varkind == UNDEFVAR) \
272 curstack->prev->varkind = TEMPVAR; \
273 curstack = curstack->prev->prev; \
276 #define POP_S1_S2_ANY_ANY \
279 if (curstack->varkind == UNDEFVAR) \
280 curstack->varkind = TEMPVAR; \
281 if (curstack->prev->varkind == UNDEFVAR) \
282 curstack->prev->varkind = TEMPVAR; \
283 curstack = curstack->prev->prev; \
286 #define POP_S1_S2_S3(type1, type2, type3) \
288 USE_S1_S2_S3(type1, type2, type3); \
289 if (curstack->varkind == UNDEFVAR) \
290 curstack->varkind = TEMPVAR; \
291 if (curstack->prev->varkind == UNDEFVAR) \
292 curstack->prev->varkind = TEMPVAR; \
293 if (curstack->prev->prev->varkind == UNDEFVAR) \
294 curstack->prev->prev->varkind = TEMPVAR; \
295 curstack = curstack->prev->prev->prev; \
302 /* macros for setting the destination operand ***********************/
305 (iptr->dst.varindex = -1)
307 #define DST(typed, index) \
309 NEWSTACKn((typed),(index)); \
310 curstack->creator = iptr; \
311 iptr->dst.varindex = (index); \
314 #define DST_LOCALVAR(typed, index) \
316 NEWSTACK((typed), LOCALVAR, (index)); \
317 curstack->creator = iptr; \
318 iptr->dst.varindex = (index); \
322 /* macro for propagating constant values ****************************/
324 #if defined(ENABLE_VERIFIER)
325 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
327 (dv)->type = (sv)->type; \
328 (dv)->vv = (sv)->vv; \
329 (dv)->SBRSTART = (sv)->SBRSTART; \
332 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
334 (dv)->type = (sv)->type; \
335 (dv)->vv = (sv)->vv; \
339 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
340 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
343 /* stack modelling macros *******************************************/
345 #define OP0_1(typed) \
348 GET_NEW_VAR(sd, new_index, (typed)); \
349 DST((typed), new_index); \
360 #define OP1_BRANCH(type1) \
366 #define OP1_1(type1, typed) \
369 GET_NEW_VAR(sd, new_index, (typed)); \
370 DST(typed, new_index); \
373 #define OP2_1(type1, type2, typed) \
375 POP_S1_S2(type1, type2); \
376 GET_NEW_VAR(sd, new_index, (typed)); \
377 DST(typed, new_index); \
392 #define OP1_0(type1) \
399 #define OP2_0(type1, type2) \
401 POP_S1_S2(type1, type2); \
406 #define OP2_BRANCH(type1, type2) \
408 POP_S1_S2(type1, type2); \
412 #define OP2_0_ANY_ANY \
419 #define OP3_0(type1, type2, type3) \
421 POP_S1_S2_S3(type1, type2, type3); \
426 #define LOAD(type1, index) \
428 DST_LOCALVAR(type1, index); \
432 #define STORE(type1, index) \
439 /* macros for DUP elimination ***************************************/
441 /* XXX replace NEW_VAR with NEW_INDEX */
442 #define DUP_SLOT(sp) \
444 GET_NEW_VAR(sd, new_index, (sp)->type); \
445 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
446 NEWSTACK((sp)->type, TEMPVAR, new_index); \
449 /* does not check input stackdepth */
450 #define MOVE_UP(sp) \
452 iptr->opc = ICMD_MOVE; \
453 iptr->s1.varindex = (sp)->varnum; \
455 curstack->creator = iptr; \
456 iptr->dst.varindex = curstack->varnum; \
460 /* does not check input stackdepth */
461 #define COPY_UP(sp) \
464 iptr->opc = ICMD_COPY; \
465 iptr->s1.varindex = (sp)->varnum; \
467 curstack->creator = iptr; \
468 iptr->dst.varindex = curstack->varnum; \
472 #define COPY_DOWN(s, d) \
475 iptr->opc = ICMD_COPY; \
476 iptr->s1.varindex = (s)->varnum; \
477 iptr->dst.varindex = (d)->varnum; \
478 (d)->creator = iptr; \
481 #define MOVE_TO_TEMP(sp) \
483 GET_NEW_INDEX(sd, new_index); \
484 iptr->opc = ICMD_MOVE; \
485 iptr->s1.varindex = (sp)->varnum; \
486 iptr->dst.varindex = new_index; \
487 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
488 (sp)->varnum = new_index; \
489 (sp)->varkind = TEMPVAR; \
492 /* macros for branching / reaching basic blocks *********************/
494 #define BRANCH_TARGET(bt, tempbptr) \
496 tempbptr = BLOCK_OF((bt).insindex); \
497 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
499 if (tempbptr == NULL) \
501 (bt).block = tempbptr; \
504 #define BRANCH(tempbptr) \
505 BRANCH_TARGET(iptr->dst, tempbptr)
508 /* forward declarations *******************************************************/
510 static void stack_create_invars(stackdata_t *sd, basicblock *b,
511 stackptr curstack, int stackdepth);
512 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
514 #if defined(STACK_VERBOSE)
515 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
516 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
517 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
518 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
519 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
523 /* stack_init ******************************************************************
525 Initialized the stack analysis subsystem (called by jit_init).
527 *******************************************************************************/
529 bool stack_init(void)
535 /* stack_grow_variable_array ***************************************************
537 Grow the variable array so the given number of additional variables fits in.
538 The number is added to `varcount`, which is the maximum number of variables
539 we expect to need at this point. The actual number of variables
540 (`varsallocated`) may be larger than that, in order to avoid too many
544 sd...........stack analysis data
545 num..........number of additional variables
547 *******************************************************************************/
549 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
555 if (sd->varcount + num > sd->varsallocated) {
556 newsize = 2*sd->varsallocated + num;
558 sd->var = DMREALLOC(sd->var, varinfo, sd->varsallocated, newsize);
559 MZERO(sd->var + sd->varsallocated, varinfo, (newsize - sd->varsallocated));
560 sd->varsallocated = newsize;
561 sd->jd->var = sd->var;
565 sd->jd->varcount += num;
567 assert(sd->varcount <= sd->varsallocated);
571 /* stack_append_block **********************************************************
573 Append the given block after the last real block of the method (before
574 the pseudo-block at the end).
577 sd...........stack analysis data
578 b............the block to append
580 *******************************************************************************/
582 static void stack_append_block(stackdata_t *sd, basicblock *b)
584 #if defined(STACK_VERBOSE)
585 printf("APPENDING BLOCK L%0d\n", b->nr);
588 b->next = sd->last_real_block->next;
589 sd->last_real_block->next = b;
590 sd->last_real_block = b;
591 b->nr = sd->jd->basicblockcount++;
592 b->next->nr = b->nr + 1;
596 /* stack_clone_block ***********************************************************
598 Create a copy of the given block and insert it at the end of the method.
600 CAUTION: This function does not copy the any variables or the instruction
601 list. It _does_, however, reserve space for the block's invars in the
605 sd...........stack analysis data
606 b............the block to clone
609 a pointer to the copy
611 *******************************************************************************/
613 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
617 clone = DNEW(basicblock);
620 clone->iinstr = NULL;
621 clone->inlocals = NULL;
622 clone->invars = NULL;
624 clone->original = (b->original) ? b->original : b;
625 clone->copied_to = clone->original->copied_to;
626 clone->original->copied_to = clone;
628 clone->flags = BBREACHED;
630 stack_append_block(sd, clone);
632 /* reserve space for the invars of the clone */
634 stack_grow_variable_array(sd, b->indepth);
636 #if defined(STACK_VERBOSE)
637 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
644 /* stack_create_invars *********************************************************
646 Create the invars for the given basic block. Also make a copy of the locals.
649 sd...........stack analysis data
650 b............block to create the invars for
651 curstack.....current stack top
652 stackdepth...current stack depth
654 This function creates STACKDEPTH invars and sets their types to the
655 types to the types of the corresponding slot in the current stack.
657 *******************************************************************************/
659 static void stack_create_invars(stackdata_t *sd, basicblock *b,
660 stackptr curstack, int stackdepth)
668 assert(sd->vartop + stackdepth <= sd->varcount);
670 b->indepth = stackdepth;
671 b->invars = DMNEW(s4, stackdepth);
673 /* allocate the variable indices */
674 index = (sd->vartop += stackdepth);
677 for (sp = curstack; i--; sp = sp->prev) {
678 b->invars[i] = --index;
679 dv = sd->var + index;
680 sv = sd->var + sp->varnum;
682 COPY_VAL_AND_TYPE_VAR(sv, dv);
685 /* copy the current state of the local variables */
686 /* (one extra local is needed by the verifier) */
688 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
690 for (i=0; i<sd->localcount; ++i)
695 /* stack_create_invars_from_outvars ********************************************
697 Create the invars for the given basic block. Also make a copy of the locals.
698 Types are propagated from the outvars of the current block.
701 sd...........stack analysis data
702 b............block to create the invars for
704 *******************************************************************************/
706 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
712 n = sd->bptr->outdepth;
713 assert(sd->vartop + n <= sd->varcount);
716 b->invars = DMNEW(s4, n);
719 dv = sd->var + sd->vartop;
721 /* allocate the invars */
723 for (i=0; i<n; ++i, ++dv) {
724 sv = sd->var + sd->bptr->outvars[i];
725 b->invars[i] = sd->vartop++;
727 COPY_VAL_AND_TYPE_VAR(sv, dv);
731 /* copy the current state of the local variables */
732 /* (one extra local is needed by the verifier) */
734 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
736 for (i=0; i<sd->localcount; ++i)
741 /* stack_check_invars **********************************************************
743 Check the current stack against the invars of the given basic block.
744 Depth and types must match.
747 sd...........stack analysis data
748 b............block which invars to check against
749 curstack.....current stack top
750 stackdepth...current stack depth
754 NULL.........a VerifyError has been thrown
756 *******************************************************************************/
758 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
759 stackptr curstack, int stackdepth)
768 #if defined(STACK_VERBOSE)
769 printf("stack_check_invars(L%03d)\n", b->nr);
772 /* find original of b */
777 #if defined(STACK_VERBOSE)
778 printf("original is L%03d\n", orig->nr);
783 #if defined(ENABLE_VERIFIER)
784 if (i != stackdepth) {
785 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
793 #if defined(STACK_VERBOSE)
794 printf("checking against ");
795 stack_verbose_show_block(sd, b); printf("\n");
799 for (i = orig->indepth; i--; sp = sp->prev) {
800 dv = sd->var + b->invars[i];
801 sv = sd->var + sp->varnum;
803 #if defined(ENABLE_VERIFIER)
804 if (dv->type != sp->type) {
805 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
810 if (sp->type == TYPE_RET) {
811 #if defined(ENABLE_VERIFIER)
812 if (dv->SBRSTART != sv->SBRSTART) {
813 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
817 if (dv->vv.retaddr != sv->vv.retaddr) {
819 /* don't break! have to check the remaining stackslots */
825 for (i=0; i<sd->localcount; ++i) {
826 dv = b->inlocals + i;
828 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
830 #if defined(ENABLE_VERIFIER)
831 (sv->SBRSTART == dv->SBRSTART) &&
833 (sv->vv.retaddr != dv->vv.retaddr))
843 /* XXX mark mixed type variables void */
844 /* XXX cascading collapse? */
845 #if defined(ENABLE_VERIFIER)
847 for (i=0; i<sd->localcount; ++i) {
848 dv = b->inlocals + i;
850 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
851 && (sv->SBRSTART != dv->SBRSTART))
853 dv->type = TYPE_VOID;
854 if (b->flags >= BBFINISHED)
855 b->flags = BBTYPECHECK_REACHED;
856 sd->repeat = true; /* This is very rare, so just repeat */
862 #if defined(STACK_VERBOSE)
863 printf("------> using L%03d\n", b->nr);
867 } while ((b = b->copied_to) != NULL);
869 b = stack_clone_block(sd, orig);
873 stack_create_invars(sd, b, curstack, stackdepth);
878 /* stack_check_invars_from_outvars *********************************************
880 Check the outvars of the current block against the invars of the given block.
881 Depth and types must match.
884 sd...........stack analysis data
885 b............block which invars to check against
889 NULL.........a VerifyError has been thrown
891 *******************************************************************************/
893 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
901 #if defined(STACK_VERBOSE)
902 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
905 /* find original of b */
910 #if defined(STACK_VERBOSE)
911 printf("original is L%03d\n", orig->nr);
915 n = sd->bptr->outdepth;
917 #if defined(ENABLE_VERIFIER)
919 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
927 #if defined(STACK_VERBOSE)
928 printf("checking against ");
929 stack_verbose_show_block(sd, b); printf("\n");
933 dv = sd->var + b->invars[0];
935 for (i=0; i<n; ++i, ++dv) {
936 sv = sd->var + sd->bptr->outvars[i];
938 #if defined(ENABLE_VERIFIER)
939 if (sv->type != dv->type) {
940 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
945 if (dv->type == TYPE_RET) {
946 #if defined(ENABLE_VERIFIER)
947 if (sv->SBRSTART != dv->SBRSTART) {
948 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
952 if (sv->vv.retaddr != dv->vv.retaddr) {
954 /* don't break! have to check the remaining stackslots */
961 for (i=0; i<sd->localcount; ++i) {
962 dv = b->inlocals + i;
965 #if defined(ENABLE_VERIFIER)
966 (sv->SBRSTART == dv->SBRSTART) &&
968 (sv->type == TYPE_RET && dv->type == TYPE_RET))
970 if (sv->vv.retaddr != dv->vv.retaddr) {
979 /* XXX mark mixed type variables void */
980 /* XXX cascading collapse? */
981 #if defined(ENABLE_VERIFIER)
983 for (i=0; i<sd->localcount; ++i) {
984 dv = b->inlocals + i;
986 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
987 && (sv->SBRSTART != dv->SBRSTART))
989 dv->type = TYPE_VOID;
990 if (b->flags >= BBFINISHED)
991 b->flags = BBTYPECHECK_REACHED;
992 sd->repeat = true; /* This is very rare, so just repeat */
998 #if defined(STACK_VERBOSE)
999 printf("------> using L%03d\n", b->nr);
1003 } while ((b = b->copied_to) != NULL);
1005 b = stack_clone_block(sd, orig);
1009 stack_create_invars_from_outvars(sd, b);
1014 /* stack_create_instack ********************************************************
1016 Create the instack of the current basic block.
1019 sd...........stack analysis data
1022 the current stack top at the start of the basic block.
1024 *******************************************************************************/
1026 static stackptr stack_create_instack(stackdata_t *sd)
1032 if ((depth = sd->bptr->indepth) == 0)
1035 sp = (sd->new += depth);
1039 index = sd->bptr->invars[depth];
1041 sp->type = sd->var[index].type;
1045 sp->varkind = STACKVAR;
1049 /* return the top of the created stack */
1054 /* stack_mark_reached **********************************************************
1056 Mark the given block reached and propagate the current stack and locals to
1057 it. This function specializes the target block, if necessary, and returns
1058 a pointer to the specialized target.
1061 sd...........stack analysis data
1062 b............the block to reach
1063 curstack.....the current stack top
1064 stackdepth...the current stack depth
1067 a pointer to (a specialized version of) the target
1068 NULL.........a VerifyError has been thrown
1070 *******************************************************************************/
1072 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1074 #if defined(STACK_VERBOSE)
1075 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1077 /* mark targets of backward branches */
1079 b->bitflags |= BBFLAG_REPLACEMENT;
1081 if (b->flags < BBREACHED) {
1082 /* b is reached for the first time. Create its invars. */
1084 #if defined(STACK_VERBOSE)
1085 printf("reached L%03d for the first time\n", b->nr);
1088 stack_create_invars(sd, b, curstack, stackdepth);
1090 b->flags = BBREACHED;
1095 /* b has been reached before. Check that its invars match. */
1097 return stack_check_invars(sd, b, curstack, stackdepth);
1102 /* stack_mark_reached_from_outvars *********************************************
1104 Mark the given block reached and propagate the outvars of the current block
1105 and the current locals to it. This function specializes the target block,
1106 if necessary, and returns a pointer to the specialized target.
1109 sd...........stack analysis data
1110 b............the block to reach
1113 a pointer to (a specialized version of) the target
1114 NULL.........a VerifyError has been thrown
1116 *******************************************************************************/
1118 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1120 #if defined(STACK_VERBOSE)
1121 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1123 /* mark targets of backward branches */
1125 b->bitflags |= BBFLAG_REPLACEMENT;
1127 if (b->flags < BBREACHED) {
1128 /* b is reached for the first time. Create its invars. */
1130 #if defined(STACK_VERBOSE)
1131 printf("reached L%03d for the first time\n", b->nr);
1134 stack_create_invars_from_outvars(sd, b);
1136 b->flags = BBREACHED;
1141 /* b has been reached before. Check that its invars match. */
1143 return stack_check_invars_from_outvars(sd, b);
1148 /* stack_reach_next_block ******************************************************
1150 Mark the following block reached and propagate the outvars of the current block
1151 and the current locals to it. This function specializes the target block,
1152 if necessary, and returns a pointer to the specialized target.
1155 sd...........stack analysis data
1158 a pointer to (a specialized version of) the following block
1159 NULL.........a VerifyError has been thrown
1161 *******************************************************************************/
1163 static bool stack_reach_next_block(stackdata_t *sd)
1168 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1169 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1173 if (tbptr != sd->bptr->next) {
1174 #if defined(STACK_VERBOSE)
1175 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1177 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1178 assert(iptr->opc == ICMD_NOP);
1179 iptr->opc = ICMD_GOTO;
1180 iptr->dst.block = tbptr;
1182 if (tbptr->flags < BBFINISHED)
1183 sd->repeat = true; /* XXX check if we really need to repeat */
1190 /* stack_reach_handlers ********************************************************
1192 Reach the exception handlers for the current block.
1195 sd...........stack analysis data
1198 true.........everything ok
1199 false........a VerifyError has been thrown
1201 *******************************************************************************/
1203 static bool stack_reach_handlers(stackdata_t *sd)
1208 #if defined(STACK_VERBOSE)
1209 printf("reaching exception handlers...\n");
1212 for (i=0; sd->handlers[i]; ++i) {
1213 tbptr = sd->handlers[i]->handler;
1215 tbptr->type = BBTYPE_EXH;
1216 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1218 /* reach (and specialize) the handler block */
1220 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1225 sd->handlers[i]->handler = tbptr;
1232 /* stack_reanalyse_block ******************************************************
1234 Re-analyse the current block. This is called if either the block itself
1235 has already been analysed before, or the current block is a clone of an
1236 already analysed block, and this clone is reached for the first time.
1237 In the latter case, this function does all that is necessary for fully
1238 cloning the block (cloning the instruction list and variables, etc.).
1241 sd...........stack analysis data
1244 true.........everything ok
1245 false........a VerifyError has been thrown
1247 *******************************************************************************/
1249 #define RELOCATE(index) \
1251 if ((index) >= blockvarstart) \
1252 (index) += blockvarshift; \
1253 else if ((index) >= invarstart) \
1254 (index) += invarshift; \
1257 bool stack_reanalyse_block(stackdata_t *sd)
1269 branch_target_t *table;
1270 lookup_target_t *lookup;
1273 bool cloneinstructions;
1274 exception_entry *ex;
1276 #if defined(STACK_VERBOSE)
1277 stack_verbose_block_enter(sd, true);
1284 assert(orig != NULL);
1286 /* clone the instruction list */
1288 cloneinstructions = true;
1290 assert(orig->iinstr);
1292 iptr = DMNEW(instruction, len + 1);
1294 MCOPY(iptr, orig->iinstr, instruction, len);
1295 iptr[len].opc = ICMD_NOP;
1299 /* reserve space for the clone's block variables */
1301 stack_grow_variable_array(sd, orig->varcount);
1303 /* we already have the invars set */
1305 assert(b->indepth == orig->indepth);
1307 /* calculate relocation shifts for invars and block variables */
1309 if (orig->indepth) {
1310 invarstart = orig->invars[0];
1311 invarshift = b->invars[0] - invarstart;
1314 invarstart = INT_MAX;
1317 blockvarstart = orig->varstart;
1318 blockvarshift = sd->vartop - blockvarstart;
1320 /* copy block variables */
1322 b->varstart = sd->vartop;
1323 b->varcount = orig->varcount;
1324 sd->vartop += b->varcount;
1325 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1329 b->outdepth = orig->outdepth;
1330 b->outvars = DMNEW(s4, orig->outdepth);
1331 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1333 /* clone exception handlers */
1335 for (i=0; sd->handlers[i]; ++i) {
1336 ex = DNEW(exception_entry);
1337 ex->handler = sd->handlers[i]->handler;
1339 ex->end = b; /* XXX hack, see end of stack_analyse */
1340 ex->catchtype = sd->handlers[i]->catchtype;
1343 assert(sd->extableend->down == NULL);
1344 sd->extableend->down = ex;
1345 sd->extableend = ex;
1346 sd->jd->exceptiontablelength++;
1348 sd->handlers[i] = ex;
1352 cloneinstructions = false;
1355 invarstart = sd->vartop;
1356 blockvarstart = sd->vartop;
1361 /* find exception handlers for the cloned block */
1363 ex = sd->jd->exceptiontable;
1364 for (; ex != NULL; ex = ex->down) {
1365 /* XXX the cloned exception handlers have identical */
1366 /* start end end blocks. */
1367 if ((ex->start == b) && (ex->end == b)) {
1368 sd->handlers[len++] = ex;
1371 sd->handlers[len] = NULL;
1374 #if defined(STACK_VERBOSE)
1375 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1376 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1379 /* mark block as finished */
1381 b->flags = BBFINISHED;
1383 /* initialize locals at the start of this block */
1386 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1388 /* reach exception handlers for this block */
1390 if (!stack_reach_handlers(sd))
1393 superblockend = false;
1395 for (len = b->icount; len--; iptr++) {
1396 #if defined(STACK_VERBOSE)
1397 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1403 switch (iptr->opc) {
1405 j = iptr->s1.varindex;
1407 #if defined(ENABLE_VERIFIER)
1408 if (sd->var[j].type != TYPE_RET) {
1409 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1414 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1415 superblockend = true;
1419 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1420 superblockend = true;
1424 superblockend = true;
1427 case ICMD_CHECKNULL:
1428 case ICMD_PUTSTATICCONST:
1434 case ICMD_INLINE_START:
1435 case ICMD_INLINE_END:
1436 case ICMD_INLINE_GOTO:
1440 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1441 superblockend = true;
1444 /* pop 0 push 1 const */
1453 /* pop 0 push 1 load */
1460 RELOCATE(iptr->dst.varindex);
1473 RELOCATE(iptr->sx.s23.s2.varindex);
1474 RELOCATE(iptr->s1.varindex);
1475 RELOCATE(iptr->dst.varindex);
1489 RELOCATE(iptr->sx.s23.s3.varindex);
1490 RELOCATE(iptr->sx.s23.s2.varindex);
1491 RELOCATE(iptr->s1.varindex);
1495 /* pop 1 push 0 store */
1502 RELOCATE(iptr->s1.varindex);
1504 j = iptr->dst.varindex;
1505 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1517 RELOCATE(iptr->s1.varindex);
1518 superblockend = true;
1521 case ICMD_PUTSTATIC:
1522 case ICMD_PUTFIELDCONST:
1525 RELOCATE(iptr->s1.varindex);
1528 /* pop 1 push 0 branch */
1531 case ICMD_IFNONNULL:
1546 RELOCATE(iptr->s1.varindex);
1547 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1550 /* pop 1 push 0 table branch */
1552 case ICMD_TABLESWITCH:
1553 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1555 if (cloneinstructions) {
1556 table = DMNEW(branch_target_t, i);
1557 MCOPY(table, iptr->dst.table, branch_target_t, i);
1558 iptr->dst.table = table;
1561 table = iptr->dst.table;
1564 RELOCATE(iptr->s1.varindex);
1566 table->block = stack_mark_reached_from_outvars(sd, table->block);
1569 superblockend = true;
1572 case ICMD_LOOKUPSWITCH:
1573 i = iptr->sx.s23.s2.lookupcount;
1574 if (cloneinstructions) {
1575 lookup = DMNEW(lookup_target_t, i);
1576 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1577 iptr->dst.lookup = lookup;
1580 lookup = iptr->dst.lookup;
1582 RELOCATE(iptr->s1.varindex);
1584 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1587 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1588 superblockend = true;
1591 case ICMD_MONITORENTER:
1592 case ICMD_MONITOREXIT:
1593 RELOCATE(iptr->s1.varindex);
1597 /* pop 2 push 0 branch */
1599 case ICMD_IF_ICMPEQ:
1600 case ICMD_IF_ICMPNE:
1601 case ICMD_IF_ICMPLT:
1602 case ICMD_IF_ICMPGE:
1603 case ICMD_IF_ICMPGT:
1604 case ICMD_IF_ICMPLE:
1606 case ICMD_IF_LCMPEQ:
1607 case ICMD_IF_LCMPNE:
1608 case ICMD_IF_LCMPLT:
1609 case ICMD_IF_LCMPGE:
1610 case ICMD_IF_LCMPGT:
1611 case ICMD_IF_LCMPLE:
1613 case ICMD_IF_FCMPEQ:
1614 case ICMD_IF_FCMPNE:
1616 case ICMD_IF_FCMPL_LT:
1617 case ICMD_IF_FCMPL_GE:
1618 case ICMD_IF_FCMPL_GT:
1619 case ICMD_IF_FCMPL_LE:
1621 case ICMD_IF_FCMPG_LT:
1622 case ICMD_IF_FCMPG_GE:
1623 case ICMD_IF_FCMPG_GT:
1624 case ICMD_IF_FCMPG_LE:
1626 case ICMD_IF_DCMPEQ:
1627 case ICMD_IF_DCMPNE:
1629 case ICMD_IF_DCMPL_LT:
1630 case ICMD_IF_DCMPL_GE:
1631 case ICMD_IF_DCMPL_GT:
1632 case ICMD_IF_DCMPL_LE:
1634 case ICMD_IF_DCMPG_LT:
1635 case ICMD_IF_DCMPG_GE:
1636 case ICMD_IF_DCMPG_GT:
1637 case ICMD_IF_DCMPG_LE:
1639 case ICMD_IF_ACMPEQ:
1640 case ICMD_IF_ACMPNE:
1641 RELOCATE(iptr->sx.s23.s2.varindex);
1642 RELOCATE(iptr->s1.varindex);
1643 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1649 case ICMD_IASTORECONST:
1650 case ICMD_LASTORECONST:
1651 case ICMD_AASTORECONST:
1652 case ICMD_BASTORECONST:
1653 case ICMD_CASTORECONST:
1654 case ICMD_SASTORECONST:
1657 RELOCATE(iptr->sx.s23.s2.varindex);
1658 RELOCATE(iptr->s1.varindex);
1661 /* pop 0 push 1 copy */
1665 RELOCATE(iptr->dst.varindex);
1666 RELOCATE(iptr->s1.varindex);
1667 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1710 RELOCATE(iptr->sx.s23.s2.varindex);
1711 RELOCATE(iptr->s1.varindex);
1712 RELOCATE(iptr->dst.varindex);
1717 case ICMD_CHECKCAST:
1718 case ICMD_ARRAYLENGTH:
1719 case ICMD_INSTANCEOF:
1721 case ICMD_ANEWARRAY:
1724 case ICMD_IADDCONST:
1725 case ICMD_ISUBCONST:
1726 case ICMD_IMULCONST:
1730 case ICMD_IANDCONST:
1732 case ICMD_IXORCONST:
1733 case ICMD_ISHLCONST:
1734 case ICMD_ISHRCONST:
1735 case ICMD_IUSHRCONST:
1736 case ICMD_LADDCONST:
1737 case ICMD_LSUBCONST:
1738 case ICMD_LMULCONST:
1742 case ICMD_LANDCONST:
1744 case ICMD_LXORCONST:
1745 case ICMD_LSHLCONST:
1746 case ICMD_LSHRCONST:
1747 case ICMD_LUSHRCONST:
1751 case ICMD_INT2SHORT:
1767 RELOCATE(iptr->s1.varindex);
1768 RELOCATE(iptr->dst.varindex);
1773 case ICMD_GETSTATIC:
1776 RELOCATE(iptr->dst.varindex);
1779 /* pop many push any */
1781 case ICMD_INVOKESTATIC:
1782 case ICMD_INVOKESPECIAL:
1783 case ICMD_INVOKEVIRTUAL:
1784 case ICMD_INVOKEINTERFACE:
1786 case ICMD_MULTIANEWARRAY:
1787 i = iptr->s1.argcount;
1788 if (cloneinstructions) {
1789 argp = DMNEW(s4, i);
1790 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1791 iptr->sx.s23.s2.args = argp;
1794 argp = iptr->sx.s23.s2.args;
1802 RELOCATE(iptr->dst.varindex);
1807 new_internalerror("Unknown ICMD %d during stack re-analysis",
1812 #if defined(STACK_VERBOSE)
1813 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1818 /* relocate outvars */
1820 for (i=0; i<b->outdepth; ++i) {
1821 RELOCATE(b->outvars[i]);
1824 #if defined(STACK_VERBOSE)
1825 stack_verbose_block_exit(sd, superblockend);
1828 /* propagate to the next block */
1831 if (!stack_reach_next_block(sd))
1838 /* stack_change_to_tempvar *****************************************************
1840 Change the given stackslot to a TEMPVAR. This includes creating a new
1841 temporary variable and changing the dst.varindex of the creator of the
1842 stacklot to the new variable index. If this stackslot has been passed
1843 through ICMDs between the point of its creation and the current point,
1844 then the variable index is also changed in these ICMDs.
1847 sd...........stack analysis data
1848 sp...........stackslot to change
1849 ilimit.......instruction up to which to look for ICMDs passing-through
1850 the stackslot (exclusive). This may point exactly after the
1851 last instruction, in which case the search is done to the
1854 *******************************************************************************/
1856 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1857 instruction *ilimit)
1864 oldindex = sp->varnum;
1866 /* create a new temporary variable */
1868 GET_NEW_VAR(*sd, newindex, sp->type);
1870 sd->var[newindex].flags = sp->flags;
1872 /* change the stackslot */
1874 sp->varnum = newindex;
1875 sp->varkind = TEMPVAR;
1877 /* change the dst.varindex of the stackslot's creator */
1880 sp->creator->dst.varindex = newindex;
1882 /* handle ICMDs this stackslot passed through, if any */
1884 if (sp->flags & PASSTHROUGH) {
1885 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1887 /* asser that the limit point to an ICMD, or after the last one */
1888 assert(ilimit >= sd->bptr->iinstr);
1889 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1891 for (; iptr < ilimit; ++iptr) {
1892 switch (iptr->opc) {
1893 case ICMD_INVOKESTATIC:
1894 case ICMD_INVOKESPECIAL:
1895 case ICMD_INVOKEVIRTUAL:
1896 case ICMD_INVOKEINTERFACE:
1899 for (i=0; i<iptr->s1.argcount; ++i)
1900 if (iptr->sx.s23.s2.args[i] == oldindex) {
1901 iptr->sx.s23.s2.args[i] = newindex;
1904 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1905 /* stackslot, it must be added in this switch! */
1912 /* stack_analyse ***************************************************************
1914 Analyse_stack uses the intermediate code created by parse.c to
1915 build a model of the JVM operand stack for the current method.
1917 The following checks are performed:
1918 - check for operand stack underflow (before each instruction)
1919 - check for operand stack overflow (after[1] each instruction)
1920 - check for matching stack depth at merging points
1921 - check for matching basic types[2] at merging points
1922 - check basic types for instruction input (except for BUILTIN*
1923 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1925 [1]) Checking this after the instruction should be ok. parse.c
1926 counts the number of required stack slots in such a way that it is
1927 only vital that we don't exceed `maxstack` at basic block
1930 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1931 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1932 types are not discerned.
1934 *******************************************************************************/
1936 bool stack_analyse(jitdata *jd)
1938 methodinfo *m; /* method being analyzed */
1942 #if defined(ENABLE_SSA)
1945 int b_index; /* basic block index */
1947 stackptr curstack; /* current stack top */
1949 int opcode; /* opcode of current instruction */
1952 int len; /* # of instructions after the current one */
1953 bool superblockend; /* if true, no fallthrough to next block */
1954 bool deadcode; /* true if no live code has been reached */
1955 instruction *iptr; /* the current instruction */
1957 basicblock *original;
1958 exception_entry *ex;
1960 stackptr *last_store_boundary;
1961 stackptr coalescing_boundary;
1963 stackptr src1, src2, src3, src4, dst1, dst2;
1965 branch_target_t *table;
1966 lookup_target_t *lookup;
1967 #if defined(ENABLE_VERIFIER)
1968 int expectedtype; /* used by CHECK_BASIC_TYPE */
1970 builtintable_entry *bte;
1972 constant_FMIref *fmiref;
1973 #if defined(ENABLE_STATISTICS)
1974 int iteration_count; /* number of iterations of analysis */
1976 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1978 #if defined(STACK_VERBOSE)
1979 show_method(jd, SHOW_PARSE);
1982 /* get required compiler data - initialization */
1987 #if defined(ENABLE_SSA)
1991 /* initialize the stackdata_t struct */
1995 sd.varcount = jd->varcount;
1996 sd.vartop = jd->vartop;
1997 sd.localcount = jd->localcount;
1999 sd.varsallocated = sd.varcount;
2000 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
2002 /* prepare the variable for exception handler stacks */
2003 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
2005 sd.exstack.type = TYPE_ADR;
2006 sd.exstack.prev = NULL;
2007 sd.exstack.varnum = sd.localcount;
2008 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2010 #if defined(ENABLE_LSRA)
2011 m->maxlifetimes = 0;
2014 #if defined(ENABLE_STATISTICS)
2015 iteration_count = 0;
2018 /* find the last real basic block */
2020 sd.last_real_block = NULL;
2021 tbptr = jd->basicblocks;
2022 while (tbptr->next) {
2023 sd.last_real_block = tbptr;
2024 tbptr = tbptr->next;
2026 assert(sd.last_real_block);
2028 /* find the last exception handler */
2030 if (jd->exceptiontablelength)
2031 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2033 sd.extableend = NULL;
2035 /* init jd->interface_map */
2037 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2038 for (i = 0; i < m->maxstack * 5; i++)
2039 jd->interface_map[i].flags = UNUSED;
2041 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2043 /* initialize flags and invars (none) of first block */
2045 jd->basicblocks[0].flags = BBREACHED;
2046 jd->basicblocks[0].invars = NULL;
2047 jd->basicblocks[0].indepth = 0;
2048 jd->basicblocks[0].inlocals =
2049 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2050 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2051 jd->localcount + VERIFIER_EXTRA_LOCALS);
2053 /* stack analysis loop (until fixpoint reached) **************************/
2056 #if defined(ENABLE_STATISTICS)
2060 /* initialize loop over basic blocks */
2062 sd.bptr = jd->basicblocks;
2063 superblockend = true;
2065 curstack = NULL; stackdepth = 0;
2068 /* iterate over basic blocks *****************************************/
2070 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2072 if (sd.bptr->flags == BBDELETED) {
2073 /* This block has been deleted - do nothing. */
2078 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2079 /* re-analyse a block because its input changed */
2080 if (!stack_reanalyse_block(&sd))
2082 superblockend = true; /* XXX */
2086 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2087 /* This block has not been reached so far, and we */
2088 /* don't fall into it, so we'll have to iterate again. */
2094 if (sd.bptr->flags > BBREACHED) {
2095 /* This block is already finished. */
2097 superblockend = true;
2101 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2102 /* This block is a clone and the original has not been */
2103 /* analysed, yet. Analyse it on the next iteration. */
2106 /* XXX superblockend? */
2110 /* This block has to be analysed now. */
2112 /* XXX The rest of this block is still indented one level too */
2113 /* much in order to avoid a giant diff by changing that. */
2115 /* We know that sd.bptr->flags == BBREACHED. */
2116 /* This block has been reached before. */
2118 assert(sd.bptr->flags == BBREACHED);
2119 stackdepth = sd.bptr->indepth;
2121 /* find exception handlers for this block */
2123 /* determine the active exception handlers for this block */
2124 /* XXX could use a faster algorithm with sorted lists or */
2127 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2130 ex = jd->exceptiontable;
2131 for (; ex != NULL; ex = ex->down) {
2132 if ((ex->start <= original) && (ex->end > original)) {
2133 sd.handlers[len++] = ex;
2136 sd.handlers[len] = NULL;
2139 /* reanalyse cloned block */
2141 if (sd.bptr->original) {
2142 if (!stack_reanalyse_block(&sd))
2147 /* reset the new pointer for allocating stackslots */
2151 /* create the instack of this block */
2153 curstack = stack_create_instack(&sd);
2155 /* initialize locals at the start of this block */
2157 if (sd.bptr->inlocals)
2158 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2160 /* set up local variables for analyzing this block */
2163 superblockend = false;
2164 len = sd.bptr->icount;
2165 iptr = sd.bptr->iinstr;
2166 b_index = sd.bptr - jd->basicblocks;
2168 /* mark the block as analysed */
2170 sd.bptr->flags = BBFINISHED;
2172 /* reset variables for dependency checking */
2174 coalescing_boundary = sd.new;
2175 for( i = 0; i < m->maxlocals; i++)
2176 last_store_boundary[i] = sd.new;
2178 /* remember the start of this block's variables */
2180 sd.bptr->varstart = sd.vartop;
2182 #if defined(STACK_VERBOSE)
2183 stack_verbose_block_enter(&sd, false);
2186 /* reach exception handlers for this block */
2188 if (!stack_reach_handlers(&sd))
2191 /* iterate over ICMDs ****************************************/
2193 while (--len >= 0) {
2195 #if defined(STACK_VERBOSE)
2196 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2197 for( copy = curstack; copy; copy = copy->prev ) {
2198 printf("%2d(%d", copy->varnum, copy->type);
2201 if (IS_PREALLOC(copy))
2208 /* fetch the current opcode */
2212 /* automatically replace some ICMDs with builtins */
2214 #if defined(USEBUILTINTABLE)
2215 bte = builtintable_get_automatic(opcode);
2217 if (bte && bte->opcode == opcode) {
2218 iptr->opc = ICMD_BUILTIN;
2219 iptr->flags.bits = 0;
2220 iptr->sx.s23.s3.bte = bte;
2221 /* iptr->line is already set */
2222 jd->isleafmethod = false;
2225 #endif /* defined(USEBUILTINTABLE) */
2227 /* main opcode switch *************************************/
2239 case ICMD_CHECKNULL:
2240 coalescing_boundary = sd.new;
2241 COUNT(count_check_null);
2244 iptr->dst.varindex = iptr->s1.varindex;
2248 j = iptr->s1.varindex =
2249 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2251 #if defined(ENABLE_VERIFIER)
2252 if (sd.var[j].type != TYPE_RET) {
2253 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2260 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2261 superblockend = true;
2265 COUNT(count_pcmd_return);
2268 superblockend = true;
2272 /* pop 0 push 1 const */
2274 /************************** ICONST OPTIMIZATIONS **************************/
2277 COUNT(count_pcmd_load);
2281 switch (iptr[1].opc) {
2283 iptr->opc = ICMD_IADDCONST;
2287 iptr[1].opc = ICMD_NOP;
2288 OP1_1(TYPE_INT, TYPE_INT);
2289 COUNT(count_pcmd_op);
2293 iptr->opc = ICMD_ISUBCONST;
2294 goto icmd_iconst_tail;
2295 #if SUPPORT_CONST_MUL
2297 iptr->opc = ICMD_IMULCONST;
2298 goto icmd_iconst_tail;
2299 #else /* SUPPORT_CONST_MUL */
2301 if (iptr->sx.val.i == 0x00000002)
2303 else if (iptr->sx.val.i == 0x00000004)
2305 else if (iptr->sx.val.i == 0x00000008)
2307 else if (iptr->sx.val.i == 0x00000010)
2309 else if (iptr->sx.val.i == 0x00000020)
2311 else if (iptr->sx.val.i == 0x00000040)
2313 else if (iptr->sx.val.i == 0x00000080)
2315 else if (iptr->sx.val.i == 0x00000100)
2317 else if (iptr->sx.val.i == 0x00000200)
2319 else if (iptr->sx.val.i == 0x00000400)
2320 iptr->sx.val.i = 10;
2321 else if (iptr->sx.val.i == 0x00000800)
2322 iptr->sx.val.i = 11;
2323 else if (iptr->sx.val.i == 0x00001000)
2324 iptr->sx.val.i = 12;
2325 else if (iptr->sx.val.i == 0x00002000)
2326 iptr->sx.val.i = 13;
2327 else if (iptr->sx.val.i == 0x00004000)
2328 iptr->sx.val.i = 14;
2329 else if (iptr->sx.val.i == 0x00008000)
2330 iptr->sx.val.i = 15;
2331 else if (iptr->sx.val.i == 0x00010000)
2332 iptr->sx.val.i = 16;
2333 else if (iptr->sx.val.i == 0x00020000)
2334 iptr->sx.val.i = 17;
2335 else if (iptr->sx.val.i == 0x00040000)
2336 iptr->sx.val.i = 18;
2337 else if (iptr->sx.val.i == 0x00080000)
2338 iptr->sx.val.i = 19;
2339 else if (iptr->sx.val.i == 0x00100000)
2340 iptr->sx.val.i = 20;
2341 else if (iptr->sx.val.i == 0x00200000)
2342 iptr->sx.val.i = 21;
2343 else if (iptr->sx.val.i == 0x00400000)
2344 iptr->sx.val.i = 22;
2345 else if (iptr->sx.val.i == 0x00800000)
2346 iptr->sx.val.i = 23;
2347 else if (iptr->sx.val.i == 0x01000000)
2348 iptr->sx.val.i = 24;
2349 else if (iptr->sx.val.i == 0x02000000)
2350 iptr->sx.val.i = 25;
2351 else if (iptr->sx.val.i == 0x04000000)
2352 iptr->sx.val.i = 26;
2353 else if (iptr->sx.val.i == 0x08000000)
2354 iptr->sx.val.i = 27;
2355 else if (iptr->sx.val.i == 0x10000000)
2356 iptr->sx.val.i = 28;
2357 else if (iptr->sx.val.i == 0x20000000)
2358 iptr->sx.val.i = 29;
2359 else if (iptr->sx.val.i == 0x40000000)
2360 iptr->sx.val.i = 30;
2361 else if (iptr->sx.val.i == 0x80000000)
2362 iptr->sx.val.i = 31;
2366 iptr->opc = ICMD_IMULPOW2;
2367 goto icmd_iconst_tail;
2368 #endif /* SUPPORT_CONST_MUL */
2370 if (iptr->sx.val.i == 0x00000002)
2372 else if (iptr->sx.val.i == 0x00000004)
2374 else if (iptr->sx.val.i == 0x00000008)
2376 else if (iptr->sx.val.i == 0x00000010)
2378 else if (iptr->sx.val.i == 0x00000020)
2380 else if (iptr->sx.val.i == 0x00000040)
2382 else if (iptr->sx.val.i == 0x00000080)
2384 else if (iptr->sx.val.i == 0x00000100)
2386 else if (iptr->sx.val.i == 0x00000200)
2388 else if (iptr->sx.val.i == 0x00000400)
2389 iptr->sx.val.i = 10;
2390 else if (iptr->sx.val.i == 0x00000800)
2391 iptr->sx.val.i = 11;
2392 else if (iptr->sx.val.i == 0x00001000)
2393 iptr->sx.val.i = 12;
2394 else if (iptr->sx.val.i == 0x00002000)
2395 iptr->sx.val.i = 13;
2396 else if (iptr->sx.val.i == 0x00004000)
2397 iptr->sx.val.i = 14;
2398 else if (iptr->sx.val.i == 0x00008000)
2399 iptr->sx.val.i = 15;
2400 else if (iptr->sx.val.i == 0x00010000)
2401 iptr->sx.val.i = 16;
2402 else if (iptr->sx.val.i == 0x00020000)
2403 iptr->sx.val.i = 17;
2404 else if (iptr->sx.val.i == 0x00040000)
2405 iptr->sx.val.i = 18;
2406 else if (iptr->sx.val.i == 0x00080000)
2407 iptr->sx.val.i = 19;
2408 else if (iptr->sx.val.i == 0x00100000)
2409 iptr->sx.val.i = 20;
2410 else if (iptr->sx.val.i == 0x00200000)
2411 iptr->sx.val.i = 21;
2412 else if (iptr->sx.val.i == 0x00400000)
2413 iptr->sx.val.i = 22;
2414 else if (iptr->sx.val.i == 0x00800000)
2415 iptr->sx.val.i = 23;
2416 else if (iptr->sx.val.i == 0x01000000)
2417 iptr->sx.val.i = 24;
2418 else if (iptr->sx.val.i == 0x02000000)
2419 iptr->sx.val.i = 25;
2420 else if (iptr->sx.val.i == 0x04000000)
2421 iptr->sx.val.i = 26;
2422 else if (iptr->sx.val.i == 0x08000000)
2423 iptr->sx.val.i = 27;
2424 else if (iptr->sx.val.i == 0x10000000)
2425 iptr->sx.val.i = 28;
2426 else if (iptr->sx.val.i == 0x20000000)
2427 iptr->sx.val.i = 29;
2428 else if (iptr->sx.val.i == 0x40000000)
2429 iptr->sx.val.i = 30;
2430 else if (iptr->sx.val.i == 0x80000000)
2431 iptr->sx.val.i = 31;
2435 iptr->opc = ICMD_IDIVPOW2;
2436 goto icmd_iconst_tail;
2439 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2440 if ((iptr->sx.val.i == 0x00000002) ||
2441 (iptr->sx.val.i == 0x00000004) ||
2442 (iptr->sx.val.i == 0x00000008) ||
2443 (iptr->sx.val.i == 0x00000010) ||
2444 (iptr->sx.val.i == 0x00000020) ||
2445 (iptr->sx.val.i == 0x00000040) ||
2446 (iptr->sx.val.i == 0x00000080) ||
2447 (iptr->sx.val.i == 0x00000100) ||
2448 (iptr->sx.val.i == 0x00000200) ||
2449 (iptr->sx.val.i == 0x00000400) ||
2450 (iptr->sx.val.i == 0x00000800) ||
2451 (iptr->sx.val.i == 0x00001000) ||
2452 (iptr->sx.val.i == 0x00002000) ||
2453 (iptr->sx.val.i == 0x00004000) ||
2454 (iptr->sx.val.i == 0x00008000) ||
2455 (iptr->sx.val.i == 0x00010000) ||
2456 (iptr->sx.val.i == 0x00020000) ||
2457 (iptr->sx.val.i == 0x00040000) ||
2458 (iptr->sx.val.i == 0x00080000) ||
2459 (iptr->sx.val.i == 0x00100000) ||
2460 (iptr->sx.val.i == 0x00200000) ||
2461 (iptr->sx.val.i == 0x00400000) ||
2462 (iptr->sx.val.i == 0x00800000) ||
2463 (iptr->sx.val.i == 0x01000000) ||
2464 (iptr->sx.val.i == 0x02000000) ||
2465 (iptr->sx.val.i == 0x04000000) ||
2466 (iptr->sx.val.i == 0x08000000) ||
2467 (iptr->sx.val.i == 0x10000000) ||
2468 (iptr->sx.val.i == 0x20000000) ||
2469 (iptr->sx.val.i == 0x40000000) ||
2470 (iptr->sx.val.i == 0x80000000))
2472 iptr->opc = ICMD_IREMPOW2;
2473 iptr->sx.val.i -= 1;
2474 goto icmd_iconst_tail;
2477 #if SUPPORT_CONST_LOGICAL
2479 iptr->opc = ICMD_IANDCONST;
2480 goto icmd_iconst_tail;
2483 iptr->opc = ICMD_IORCONST;
2484 goto icmd_iconst_tail;
2487 iptr->opc = ICMD_IXORCONST;
2488 goto icmd_iconst_tail;
2490 #endif /* SUPPORT_CONST_LOGICAL */
2492 iptr->opc = ICMD_ISHLCONST;
2493 goto icmd_iconst_tail;
2496 iptr->opc = ICMD_ISHRCONST;
2497 goto icmd_iconst_tail;
2500 iptr->opc = ICMD_IUSHRCONST;
2501 goto icmd_iconst_tail;
2502 #if SUPPORT_LONG_SHIFT
2504 iptr->opc = ICMD_LSHLCONST;
2505 goto icmd_lconst_tail;
2508 iptr->opc = ICMD_LSHRCONST;
2509 goto icmd_lconst_tail;
2512 iptr->opc = ICMD_LUSHRCONST;
2513 goto icmd_lconst_tail;
2514 #endif /* SUPPORT_LONG_SHIFT */
2515 case ICMD_IF_ICMPEQ:
2516 iptr[1].opc = ICMD_IFEQ;
2520 /* set the constant for the following icmd */
2521 iptr[1].sx.val.i = iptr->sx.val.i;
2523 /* this instruction becomes a nop */
2524 iptr->opc = ICMD_NOP;
2527 case ICMD_IF_ICMPLT:
2528 iptr[1].opc = ICMD_IFLT;
2529 goto icmd_if_icmp_tail;
2531 case ICMD_IF_ICMPLE:
2532 iptr[1].opc = ICMD_IFLE;
2533 goto icmd_if_icmp_tail;
2535 case ICMD_IF_ICMPNE:
2536 iptr[1].opc = ICMD_IFNE;
2537 goto icmd_if_icmp_tail;
2539 case ICMD_IF_ICMPGT:
2540 iptr[1].opc = ICMD_IFGT;
2541 goto icmd_if_icmp_tail;
2543 case ICMD_IF_ICMPGE:
2544 iptr[1].opc = ICMD_IFGE;
2545 goto icmd_if_icmp_tail;
2547 #if SUPPORT_CONST_STORE
2552 # if SUPPORT_CONST_STORE_ZERO_ONLY
2553 if (iptr->sx.val.i != 0)
2556 switch (iptr[1].opc) {
2558 iptr->opc = ICMD_IASTORECONST;
2559 iptr->flags.bits |= INS_FLAG_CHECK;
2562 iptr->opc = ICMD_BASTORECONST;
2563 iptr->flags.bits |= INS_FLAG_CHECK;
2566 iptr->opc = ICMD_CASTORECONST;
2567 iptr->flags.bits |= INS_FLAG_CHECK;
2570 iptr->opc = ICMD_SASTORECONST;
2571 iptr->flags.bits |= INS_FLAG_CHECK;
2575 iptr[1].opc = ICMD_NOP;
2577 /* copy the constant to s3 */
2578 /* XXX constval -> astoreconstval? */
2579 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2580 OP2_0(TYPE_ADR, TYPE_INT);
2581 COUNT(count_pcmd_op);
2584 case ICMD_PUTSTATIC:
2586 # if SUPPORT_CONST_STORE_ZERO_ONLY
2587 if (iptr->sx.val.i != 0)
2590 /* XXX check field type? */
2592 /* copy the constant to s2 */
2593 /* XXX constval -> fieldconstval? */
2594 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2597 /* set the field reference (s3) */
2598 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2599 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2600 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2601 fmiref = iptr->sx.s23.s3.uf->fieldref;
2604 fmiref = iptr[1].sx.s23.s3.fmiref;
2605 iptr->sx.s23.s3.fmiref = fmiref;
2608 #if defined(ENABLE_VERIFIER)
2609 expectedtype = fmiref->parseddesc.fd->type;
2610 switch (iptr[0].opc) {
2612 if (expectedtype != TYPE_INT)
2613 goto throw_stack_type_error;
2616 if (expectedtype != TYPE_LNG)
2617 goto throw_stack_type_error;
2620 if (expectedtype != TYPE_ADR)
2621 goto throw_stack_type_error;
2626 #endif /* defined(ENABLE_VERIFIER) */
2628 switch (iptr[1].opc) {
2629 case ICMD_PUTSTATIC:
2630 iptr->opc = ICMD_PUTSTATICCONST;
2634 iptr->opc = ICMD_PUTFIELDCONST;
2639 iptr[1].opc = ICMD_NOP;
2640 COUNT(count_pcmd_op);
2642 #endif /* SUPPORT_CONST_STORE */
2648 /* if we get here, the ICONST has been optimized */
2652 /* normal case of an unoptimized ICONST */
2656 /************************** LCONST OPTIMIZATIONS **************************/
2659 COUNT(count_pcmd_load);
2663 /* switch depending on the following instruction */
2665 switch (iptr[1].opc) {
2666 #if SUPPORT_LONG_ADD
2668 iptr->opc = ICMD_LADDCONST;
2672 /* instruction of type LONG -> LONG */
2673 iptr[1].opc = ICMD_NOP;
2674 OP1_1(TYPE_LNG, TYPE_LNG);
2675 COUNT(count_pcmd_op);
2679 iptr->opc = ICMD_LSUBCONST;
2680 goto icmd_lconst_tail;
2682 #endif /* SUPPORT_LONG_ADD */
2683 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2685 iptr->opc = ICMD_LMULCONST;
2686 goto icmd_lconst_tail;
2687 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2688 # if SUPPORT_LONG_SHIFT
2690 if (iptr->sx.val.l == 0x00000002)
2692 else if (iptr->sx.val.l == 0x00000004)
2694 else if (iptr->sx.val.l == 0x00000008)
2696 else if (iptr->sx.val.l == 0x00000010)
2698 else if (iptr->sx.val.l == 0x00000020)
2700 else if (iptr->sx.val.l == 0x00000040)
2702 else if (iptr->sx.val.l == 0x00000080)
2704 else if (iptr->sx.val.l == 0x00000100)
2706 else if (iptr->sx.val.l == 0x00000200)
2708 else if (iptr->sx.val.l == 0x00000400)
2709 iptr->sx.val.i = 10;
2710 else if (iptr->sx.val.l == 0x00000800)
2711 iptr->sx.val.i = 11;
2712 else if (iptr->sx.val.l == 0x00001000)
2713 iptr->sx.val.i = 12;
2714 else if (iptr->sx.val.l == 0x00002000)
2715 iptr->sx.val.i = 13;
2716 else if (iptr->sx.val.l == 0x00004000)
2717 iptr->sx.val.i = 14;
2718 else if (iptr->sx.val.l == 0x00008000)
2719 iptr->sx.val.i = 15;
2720 else if (iptr->sx.val.l == 0x00010000)
2721 iptr->sx.val.i = 16;
2722 else if (iptr->sx.val.l == 0x00020000)
2723 iptr->sx.val.i = 17;
2724 else if (iptr->sx.val.l == 0x00040000)
2725 iptr->sx.val.i = 18;
2726 else if (iptr->sx.val.l == 0x00080000)
2727 iptr->sx.val.i = 19;
2728 else if (iptr->sx.val.l == 0x00100000)
2729 iptr->sx.val.i = 20;
2730 else if (iptr->sx.val.l == 0x00200000)
2731 iptr->sx.val.i = 21;
2732 else if (iptr->sx.val.l == 0x00400000)
2733 iptr->sx.val.i = 22;
2734 else if (iptr->sx.val.l == 0x00800000)
2735 iptr->sx.val.i = 23;
2736 else if (iptr->sx.val.l == 0x01000000)
2737 iptr->sx.val.i = 24;
2738 else if (iptr->sx.val.l == 0x02000000)
2739 iptr->sx.val.i = 25;
2740 else if (iptr->sx.val.l == 0x04000000)
2741 iptr->sx.val.i = 26;
2742 else if (iptr->sx.val.l == 0x08000000)
2743 iptr->sx.val.i = 27;
2744 else if (iptr->sx.val.l == 0x10000000)
2745 iptr->sx.val.i = 28;
2746 else if (iptr->sx.val.l == 0x20000000)
2747 iptr->sx.val.i = 29;
2748 else if (iptr->sx.val.l == 0x40000000)
2749 iptr->sx.val.i = 30;
2750 else if (iptr->sx.val.l == 0x80000000)
2751 iptr->sx.val.i = 31;
2755 iptr->opc = ICMD_LMULPOW2;
2756 goto icmd_lconst_tail;
2757 # endif /* SUPPORT_LONG_SHIFT */
2758 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2759 #if SUPPORT_LONG_DIV_POW2
2761 if (iptr->sx.val.l == 0x00000002)
2763 else if (iptr->sx.val.l == 0x00000004)
2765 else if (iptr->sx.val.l == 0x00000008)
2767 else if (iptr->sx.val.l == 0x00000010)
2769 else if (iptr->sx.val.l == 0x00000020)
2771 else if (iptr->sx.val.l == 0x00000040)
2773 else if (iptr->sx.val.l == 0x00000080)
2775 else if (iptr->sx.val.l == 0x00000100)
2777 else if (iptr->sx.val.l == 0x00000200)
2779 else if (iptr->sx.val.l == 0x00000400)
2780 iptr->sx.val.i = 10;
2781 else if (iptr->sx.val.l == 0x00000800)
2782 iptr->sx.val.i = 11;
2783 else if (iptr->sx.val.l == 0x00001000)
2784 iptr->sx.val.i = 12;
2785 else if (iptr->sx.val.l == 0x00002000)
2786 iptr->sx.val.i = 13;
2787 else if (iptr->sx.val.l == 0x00004000)
2788 iptr->sx.val.i = 14;
2789 else if (iptr->sx.val.l == 0x00008000)
2790 iptr->sx.val.i = 15;
2791 else if (iptr->sx.val.l == 0x00010000)
2792 iptr->sx.val.i = 16;
2793 else if (iptr->sx.val.l == 0x00020000)
2794 iptr->sx.val.i = 17;
2795 else if (iptr->sx.val.l == 0x00040000)
2796 iptr->sx.val.i = 18;
2797 else if (iptr->sx.val.l == 0x00080000)
2798 iptr->sx.val.i = 19;
2799 else if (iptr->sx.val.l == 0x00100000)
2800 iptr->sx.val.i = 20;
2801 else if (iptr->sx.val.l == 0x00200000)
2802 iptr->sx.val.i = 21;
2803 else if (iptr->sx.val.l == 0x00400000)
2804 iptr->sx.val.i = 22;
2805 else if (iptr->sx.val.l == 0x00800000)
2806 iptr->sx.val.i = 23;
2807 else if (iptr->sx.val.l == 0x01000000)
2808 iptr->sx.val.i = 24;
2809 else if (iptr->sx.val.l == 0x02000000)
2810 iptr->sx.val.i = 25;
2811 else if (iptr->sx.val.l == 0x04000000)
2812 iptr->sx.val.i = 26;
2813 else if (iptr->sx.val.l == 0x08000000)
2814 iptr->sx.val.i = 27;
2815 else if (iptr->sx.val.l == 0x10000000)
2816 iptr->sx.val.i = 28;
2817 else if (iptr->sx.val.l == 0x20000000)
2818 iptr->sx.val.i = 29;
2819 else if (iptr->sx.val.l == 0x40000000)
2820 iptr->sx.val.i = 30;
2821 else if (iptr->sx.val.l == 0x80000000)
2822 iptr->sx.val.i = 31;
2826 iptr->opc = ICMD_LDIVPOW2;
2827 goto icmd_lconst_tail;
2828 #endif /* SUPPORT_LONG_DIV_POW2 */
2830 #if SUPPORT_LONG_REM_POW2
2832 if ((iptr->sx.val.l == 0x00000002) ||
2833 (iptr->sx.val.l == 0x00000004) ||
2834 (iptr->sx.val.l == 0x00000008) ||
2835 (iptr->sx.val.l == 0x00000010) ||
2836 (iptr->sx.val.l == 0x00000020) ||
2837 (iptr->sx.val.l == 0x00000040) ||
2838 (iptr->sx.val.l == 0x00000080) ||
2839 (iptr->sx.val.l == 0x00000100) ||
2840 (iptr->sx.val.l == 0x00000200) ||
2841 (iptr->sx.val.l == 0x00000400) ||
2842 (iptr->sx.val.l == 0x00000800) ||
2843 (iptr->sx.val.l == 0x00001000) ||
2844 (iptr->sx.val.l == 0x00002000) ||
2845 (iptr->sx.val.l == 0x00004000) ||
2846 (iptr->sx.val.l == 0x00008000) ||
2847 (iptr->sx.val.l == 0x00010000) ||
2848 (iptr->sx.val.l == 0x00020000) ||
2849 (iptr->sx.val.l == 0x00040000) ||
2850 (iptr->sx.val.l == 0x00080000) ||
2851 (iptr->sx.val.l == 0x00100000) ||
2852 (iptr->sx.val.l == 0x00200000) ||
2853 (iptr->sx.val.l == 0x00400000) ||
2854 (iptr->sx.val.l == 0x00800000) ||
2855 (iptr->sx.val.l == 0x01000000) ||
2856 (iptr->sx.val.l == 0x02000000) ||
2857 (iptr->sx.val.l == 0x04000000) ||
2858 (iptr->sx.val.l == 0x08000000) ||
2859 (iptr->sx.val.l == 0x10000000) ||
2860 (iptr->sx.val.l == 0x20000000) ||
2861 (iptr->sx.val.l == 0x40000000) ||
2862 (iptr->sx.val.l == 0x80000000))
2864 iptr->opc = ICMD_LREMPOW2;
2865 iptr->sx.val.l -= 1;
2866 goto icmd_lconst_tail;
2869 #endif /* SUPPORT_LONG_REM_POW2 */
2871 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2874 iptr->opc = ICMD_LANDCONST;
2875 goto icmd_lconst_tail;
2878 iptr->opc = ICMD_LORCONST;
2879 goto icmd_lconst_tail;
2882 iptr->opc = ICMD_LXORCONST;
2883 goto icmd_lconst_tail;
2884 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2886 #if SUPPORT_LONG_CMP_CONST
2888 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2891 /* switch on the instruction after LCONST - LCMP */
2893 switch (iptr[2].opc) {
2895 iptr->opc = ICMD_IF_LEQ;
2898 icmd_lconst_lcmp_tail:
2899 /* convert LCONST, LCMP, IFXX to IF_LXX */
2900 iptr->dst.insindex = iptr[2].dst.insindex;
2901 iptr[1].opc = ICMD_NOP;
2902 iptr[2].opc = ICMD_NOP;
2904 OP1_BRANCH(TYPE_LNG);
2906 COUNT(count_pcmd_bra);
2907 COUNT(count_pcmd_op);
2911 iptr->opc = ICMD_IF_LNE;
2912 goto icmd_lconst_lcmp_tail;
2915 iptr->opc = ICMD_IF_LLT;
2916 goto icmd_lconst_lcmp_tail;
2919 iptr->opc = ICMD_IF_LGT;
2920 goto icmd_lconst_lcmp_tail;
2923 iptr->opc = ICMD_IF_LLE;
2924 goto icmd_lconst_lcmp_tail;
2927 iptr->opc = ICMD_IF_LGE;
2928 goto icmd_lconst_lcmp_tail;
2932 } /* end switch on opcode after LCONST - LCMP */
2934 #endif /* SUPPORT_LONG_CMP_CONST */
2936 #if SUPPORT_CONST_STORE
2938 # if SUPPORT_CONST_STORE_ZERO_ONLY
2939 if (iptr->sx.val.l != 0)
2942 #if SIZEOF_VOID_P == 4
2943 /* the constant must fit into a ptrint */
2944 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2947 /* move the constant to s3 */
2948 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2950 iptr->opc = ICMD_LASTORECONST;
2951 iptr->flags.bits |= INS_FLAG_CHECK;
2952 OP2_0(TYPE_ADR, TYPE_INT);
2954 iptr[1].opc = ICMD_NOP;
2955 COUNT(count_pcmd_op);
2958 case ICMD_PUTSTATIC:
2960 # if SUPPORT_CONST_STORE_ZERO_ONLY
2961 if (iptr->sx.val.l != 0)
2964 #if SIZEOF_VOID_P == 4
2965 /* the constant must fit into a ptrint */
2966 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2969 /* XXX check field type? */
2971 /* copy the constant to s2 */
2972 /* XXX constval -> fieldconstval? */
2973 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2977 #endif /* SUPPORT_CONST_STORE */
2981 } /* end switch opcode after LCONST */
2983 /* if we get here, the LCONST has been optimized */
2987 /* the normal case of an unoptimized LCONST */
2991 /************************ END OF LCONST OPTIMIZATIONS *********************/
2994 COUNT(count_pcmd_load);
2999 COUNT(count_pcmd_load);
3003 /************************** ACONST OPTIMIZATIONS **************************/
3006 coalescing_boundary = sd.new;
3007 COUNT(count_pcmd_load);
3008 #if SUPPORT_CONST_STORE
3009 /* We can only optimize if the ACONST is resolved
3010 * and there is an instruction after it. */
3012 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
3015 switch (iptr[1].opc) {
3017 /* We can only optimize for NULL values
3018 * here because otherwise a checkcast is
3020 if (iptr->sx.val.anyptr != NULL)
3023 /* copy the constant (NULL) to s3 */
3024 iptr->sx.s23.s3.constval = 0;
3025 iptr->opc = ICMD_AASTORECONST;
3026 iptr->flags.bits |= INS_FLAG_CHECK;
3027 OP2_0(TYPE_ADR, TYPE_INT);
3029 iptr[1].opc = ICMD_NOP;
3030 COUNT(count_pcmd_op);
3033 case ICMD_PUTSTATIC:
3035 # if SUPPORT_CONST_STORE_ZERO_ONLY
3036 if (iptr->sx.val.anyptr != NULL)
3039 /* XXX check field type? */
3040 /* copy the constant to s2 */
3041 /* XXX constval -> fieldconstval? */
3042 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3050 /* if we get here the ACONST has been optimized */
3054 #endif /* SUPPORT_CONST_STORE */
3059 /* pop 0 push 1 load */
3066 COUNT(count_load_instruction);
3067 i = opcode - ICMD_ILOAD; /* type */
3069 j = iptr->s1.varindex =
3070 jd->local_map[iptr->s1.varindex * 5 + i];
3072 #if defined(ENABLE_VERIFIER)
3073 if (sd.var[j].type == TYPE_RET) {
3074 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3079 #if defined(ENABLE_SSA)
3081 GET_NEW_VAR(sd, new_index, i);
3098 coalescing_boundary = sd.new;
3099 iptr->flags.bits |= INS_FLAG_CHECK;
3100 COUNT(count_check_null);
3101 COUNT(count_check_bound);
3102 COUNT(count_pcmd_mem);
3103 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3110 coalescing_boundary = sd.new;
3111 iptr->flags.bits |= INS_FLAG_CHECK;
3112 COUNT(count_check_null);
3113 COUNT(count_check_bound);
3114 COUNT(count_pcmd_mem);
3115 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3118 /* pop 0 push 0 iinc */
3121 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3122 #if defined(ENABLE_SSA)
3125 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3129 last_store_boundary[iptr->s1.varindex] = sd.new;
3132 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3137 if ((copy->varkind == LOCALVAR) &&
3138 (copy->varnum == iptr->s1.varindex))
3140 assert(IS_LOCALVAR(copy));
3146 #if defined(ENABLE_SSA)
3150 iptr->dst.varindex = iptr->s1.varindex;
3153 /* pop 1 push 0 store */
3162 i = opcode - ICMD_ISTORE; /* type */
3163 javaindex = iptr->dst.varindex;
3164 j = iptr->dst.varindex =
3165 jd->local_map[javaindex * 5 + i];
3167 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3169 #if defined(ENABLE_STATISTICS)
3172 i = sd.new - curstack;
3174 count_store_length[20]++;
3176 count_store_length[i]++;
3179 count_store_depth[10]++;
3181 count_store_depth[i]++;
3185 #if defined(ENABLE_SSA)
3188 /* check for conflicts as described in Figure 5.2 */
3190 copy = curstack->prev;
3193 if ((copy->varkind == LOCALVAR) &&
3194 (copy->varnum == j))
3196 copy->varkind = TEMPVAR;
3197 assert(IS_LOCALVAR(copy));
3204 /* if the variable is already coalesced, don't bother */
3206 /* We do not need to check against INOUT, as invars */
3207 /* are always before the coalescing boundary. */
3209 if (curstack->varkind == LOCALVAR)
3212 /* there is no STORE Lj while curstack is live */
3214 if (curstack < last_store_boundary[javaindex])
3215 goto assume_conflict;
3217 /* curstack must be after the coalescing boundary */
3219 if (curstack < coalescing_boundary)
3220 goto assume_conflict;
3222 /* there is no DEF LOCALVAR(j) while curstack is live */
3224 copy = sd.new; /* most recent stackslot created + 1 */
3225 while (--copy > curstack) {
3226 if (copy->varkind == LOCALVAR && copy->varnum == j)
3227 goto assume_conflict;
3230 /* coalesce the temporary variable with Lj */
3231 assert((curstack->varkind == TEMPVAR)
3232 || (curstack->varkind == UNDEFVAR));
3233 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3234 assert(!IS_INOUT(curstack));
3235 assert(!IS_PREALLOC(curstack));
3237 assert(curstack->creator);
3238 assert(curstack->creator->dst.varindex == curstack->varnum);
3239 assert(!(curstack->flags & PASSTHROUGH));
3240 RELEASE_INDEX(sd, curstack);
3241 curstack->varkind = LOCALVAR;
3242 curstack->varnum = j;
3243 curstack->creator->dst.varindex = j;
3246 /* revert the coalescing, if it has been done earlier */
3248 if ((curstack->varkind == LOCALVAR)
3249 && (curstack->varnum == j))
3251 assert(IS_LOCALVAR(curstack));
3252 SET_TEMPVAR(curstack);
3255 /* remember the stack boundary at this store */
3257 last_store_boundary[javaindex] = sd.new;
3258 #if defined(ENABLE_SSA)
3259 } /* if (ls != NULL) */
3262 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3265 STORE(opcode - ICMD_ISTORE, j);
3271 coalescing_boundary = sd.new;
3272 iptr->flags.bits |= INS_FLAG_CHECK;
3273 COUNT(count_check_null);
3274 COUNT(count_check_bound);
3275 COUNT(count_pcmd_mem);
3277 bte = builtintable_get_internal(BUILTIN_canstore);
3280 if (md->memuse > rd->memuse)
3281 rd->memuse = md->memuse;
3282 if (md->argintreguse > rd->argintreguse)
3283 rd->argintreguse = md->argintreguse;
3284 /* XXX non-leaf method? */
3286 /* make all stack variables saved */
3290 sd.var[copy->varnum].flags |= SAVEDVAR;
3291 /* in case copy->varnum is/will be a LOCALVAR */
3292 /* once and set back to a non LOCALVAR */
3293 /* the correct SAVEDVAR flag has to be */
3294 /* remembered in copy->flags, too */
3295 copy->flags |= SAVEDVAR;
3299 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3306 coalescing_boundary = sd.new;
3307 iptr->flags.bits |= INS_FLAG_CHECK;
3308 COUNT(count_check_null);
3309 COUNT(count_check_bound);
3310 COUNT(count_pcmd_mem);
3311 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3318 coalescing_boundary = sd.new;
3319 iptr->flags.bits |= INS_FLAG_CHECK;
3320 COUNT(count_check_null);
3321 COUNT(count_check_bound);
3322 COUNT(count_pcmd_mem);
3323 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3329 #ifdef ENABLE_VERIFIER
3332 if (IS_2_WORD_TYPE(curstack->type))
3333 goto throw_stack_category_error;
3344 coalescing_boundary = sd.new;
3345 /* Assert here that no LOCAL or INOUTS get */
3346 /* preallocated, since tha macros are not */
3347 /* available in md-abi.c! */
3348 if (IS_TEMPVAR(curstack))
3349 md_return_alloc(jd, curstack);
3350 COUNT(count_pcmd_return);
3351 OP1_0(opcode - ICMD_IRETURN);
3352 superblockend = true;
3356 coalescing_boundary = sd.new;
3357 COUNT(count_check_null);
3359 curstack = NULL; stackdepth = 0;
3360 superblockend = true;
3363 case ICMD_PUTSTATIC:
3364 coalescing_boundary = sd.new;
3365 COUNT(count_pcmd_mem);
3366 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3367 OP1_0(fmiref->parseddesc.fd->type);
3370 /* pop 1 push 0 branch */
3373 case ICMD_IFNONNULL:
3374 COUNT(count_pcmd_bra);
3375 OP1_BRANCH(TYPE_ADR);
3385 COUNT(count_pcmd_bra);
3386 /* iptr->sx.val.i is set implicitly in parse by
3387 clearing the memory or from IF_ICMPxx
3390 OP1_BRANCH(TYPE_INT);
3391 /* iptr->sx.val.i = 0; */
3395 /* pop 0 push 0 branch */
3398 COUNT(count_pcmd_bra);
3401 superblockend = true;
3404 /* pop 1 push 0 table branch */
3406 case ICMD_TABLESWITCH:
3407 COUNT(count_pcmd_table);
3408 OP1_BRANCH(TYPE_INT);
3410 table = iptr->dst.table;
3411 BRANCH_TARGET(*table, tbptr);
3414 i = iptr->sx.s23.s3.tablehigh
3415 - iptr->sx.s23.s2.tablelow + 1;
3418 BRANCH_TARGET(*table, tbptr);
3421 superblockend = true;
3424 /* pop 1 push 0 table branch */
3426 case ICMD_LOOKUPSWITCH:
3427 COUNT(count_pcmd_table);
3428 OP1_BRANCH(TYPE_INT);
3430 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3432 lookup = iptr->dst.lookup;
3434 i = iptr->sx.s23.s2.lookupcount;
3437 BRANCH_TARGET(lookup->target, tbptr);
3440 superblockend = true;
3443 case ICMD_MONITORENTER:
3444 case ICMD_MONITOREXIT:
3445 coalescing_boundary = sd.new;
3446 COUNT(count_check_null);
3450 /* pop 2 push 0 branch */
3452 case ICMD_IF_ICMPEQ:
3453 case ICMD_IF_ICMPNE:
3454 case ICMD_IF_ICMPLT:
3455 case ICMD_IF_ICMPGE:
3456 case ICMD_IF_ICMPGT:
3457 case ICMD_IF_ICMPLE:
3458 COUNT(count_pcmd_bra);
3459 OP2_BRANCH(TYPE_INT, TYPE_INT);
3463 case ICMD_IF_ACMPEQ:
3464 case ICMD_IF_ACMPNE:
3465 COUNT(count_pcmd_bra);
3466 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3473 coalescing_boundary = sd.new;
3474 COUNT(count_check_null);
3475 COUNT(count_pcmd_mem);
3476 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3477 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3482 if (!IS_2_WORD_TYPE(curstack->type)) {
3484 #ifdef ENABLE_VERIFIER
3487 if (IS_2_WORD_TYPE(curstack->prev->type))
3488 goto throw_stack_category_error;
3491 OP2_0_ANY_ANY; /* pop two slots */
3494 iptr->opc = ICMD_POP;
3495 OP1_0_ANY; /* pop one (two-word) slot */
3499 /* pop 0 push 1 dup */
3502 #ifdef ENABLE_VERIFIER
3505 if (IS_2_WORD_TYPE(curstack->type))
3506 goto throw_stack_category_error;
3509 COUNT(count_dup_instruction);
3515 coalescing_boundary = sd.new - 1;
3520 if (IS_2_WORD_TYPE(curstack->type)) {
3522 iptr->opc = ICMD_DUP;
3527 /* ..., ????, cat1 */
3528 #ifdef ENABLE_VERIFIER
3530 if (IS_2_WORD_TYPE(curstack->prev->type))
3531 goto throw_stack_category_error;
3534 src1 = curstack->prev;
3537 COPY_UP(src1); iptr++; len--;
3540 coalescing_boundary = sd.new;
3544 /* pop 2 push 3 dup */
3547 #ifdef ENABLE_VERIFIER
3550 if (IS_2_WORD_TYPE(curstack->type) ||
3551 IS_2_WORD_TYPE(curstack->prev->type))
3552 goto throw_stack_category_error;
3557 src1 = curstack->prev;
3562 /* move non-temporary sources out of the way */
3563 if (!IS_TEMPVAR(src2)) {
3564 MOVE_TO_TEMP(src2); iptr++; len--;
3567 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3569 MOVE_UP(src1); iptr++; len--;
3570 MOVE_UP(src2); iptr++; len--;
3572 COPY_DOWN(curstack, dst1);
3574 coalescing_boundary = sd.new;
3579 if (IS_2_WORD_TYPE(curstack->type)) {
3580 /* ..., ????, cat2 */
3581 #ifdef ENABLE_VERIFIER
3583 if (IS_2_WORD_TYPE(curstack->prev->type))
3584 goto throw_stack_category_error;
3587 iptr->opc = ICMD_DUP_X1;
3591 /* ..., ????, cat1 */
3592 #ifdef ENABLE_VERIFIER
3595 if (IS_2_WORD_TYPE(curstack->prev->type)
3596 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3597 goto throw_stack_category_error;
3602 src1 = curstack->prev->prev;
3603 src2 = curstack->prev;
3605 POPANY; POPANY; POPANY;
3608 /* move non-temporary sources out of the way */
3609 if (!IS_TEMPVAR(src2)) {
3610 MOVE_TO_TEMP(src2); iptr++; len--;
3612 if (!IS_TEMPVAR(src3)) {
3613 MOVE_TO_TEMP(src3); iptr++; len--;
3616 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3617 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3619 MOVE_UP(src1); iptr++; len--;
3620 MOVE_UP(src2); iptr++; len--;
3621 MOVE_UP(src3); iptr++; len--;
3623 COPY_DOWN(curstack, dst2); iptr++; len--;
3624 COPY_DOWN(curstack->prev, dst1);
3626 coalescing_boundary = sd.new;
3630 /* pop 3 push 4 dup */
3634 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3635 /* ..., cat2, ???? */
3636 #ifdef ENABLE_VERIFIER
3638 if (IS_2_WORD_TYPE(curstack->type))
3639 goto throw_stack_category_error;
3642 iptr->opc = ICMD_DUP_X1;
3646 /* ..., cat1, ???? */
3647 #ifdef ENABLE_VERIFIER
3650 if (IS_2_WORD_TYPE(curstack->type)
3651 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3652 goto throw_stack_category_error;
3656 src1 = curstack->prev->prev;
3657 src2 = curstack->prev;
3659 POPANY; POPANY; POPANY;
3662 /* move non-temporary sources out of the way */
3663 if (!IS_TEMPVAR(src2)) {
3664 MOVE_TO_TEMP(src2); iptr++; len--;
3666 if (!IS_TEMPVAR(src3)) {
3667 MOVE_TO_TEMP(src3); iptr++; len--;
3670 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3672 MOVE_UP(src1); iptr++; len--;
3673 MOVE_UP(src2); iptr++; len--;
3674 MOVE_UP(src3); iptr++; len--;
3676 COPY_DOWN(curstack, dst1);
3678 coalescing_boundary = sd.new;
3684 if (IS_2_WORD_TYPE(curstack->type)) {
3685 /* ..., ????, cat2 */
3686 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3687 /* ..., cat2, cat2 */
3688 iptr->opc = ICMD_DUP_X1;
3692 /* ..., cat1, cat2 */
3693 #ifdef ENABLE_VERIFIER
3696 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3697 goto throw_stack_category_error;
3700 iptr->opc = ICMD_DUP_X2;
3706 /* ..., ????, ????, cat1 */
3708 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3709 /* ..., cat2, ????, cat1 */
3710 #ifdef ENABLE_VERIFIER
3712 if (IS_2_WORD_TYPE(curstack->prev->type))
3713 goto throw_stack_category_error;
3716 iptr->opc = ICMD_DUP2_X1;
3720 /* ..., cat1, ????, cat1 */
3721 #ifdef ENABLE_VERIFIER
3724 if (IS_2_WORD_TYPE(curstack->prev->type)
3725 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3726 goto throw_stack_category_error;
3730 src1 = curstack->prev->prev->prev;
3731 src2 = curstack->prev->prev;
3732 src3 = curstack->prev;
3734 POPANY; POPANY; POPANY; POPANY;
3737 /* move non-temporary sources out of the way */
3738 if (!IS_TEMPVAR(src2)) {
3739 MOVE_TO_TEMP(src2); iptr++; len--;
3741 if (!IS_TEMPVAR(src3)) {
3742 MOVE_TO_TEMP(src3); iptr++; len--;
3744 if (!IS_TEMPVAR(src4)) {
3745 MOVE_TO_TEMP(src4); iptr++; len--;
3748 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3749 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3751 MOVE_UP(src1); iptr++; len--;
3752 MOVE_UP(src2); iptr++; len--;
3753 MOVE_UP(src3); iptr++; len--;
3754 MOVE_UP(src4); iptr++; len--;
3756 COPY_DOWN(curstack, dst2); iptr++; len--;
3757 COPY_DOWN(curstack->prev, dst1);
3759 coalescing_boundary = sd.new;
3763 /* pop 2 push 2 swap */
3766 #ifdef ENABLE_VERIFIER
3769 if (IS_2_WORD_TYPE(curstack->type)
3770 || IS_2_WORD_TYPE(curstack->prev->type))
3771 goto throw_stack_category_error;
3775 src1 = curstack->prev;
3780 /* move non-temporary sources out of the way */
3781 if (!IS_TEMPVAR(src1)) {
3782 MOVE_TO_TEMP(src1); iptr++; len--;
3785 MOVE_UP(src2); iptr++; len--;
3788 coalescing_boundary = sd.new;
3795 coalescing_boundary = sd.new;
3796 #if !SUPPORT_DIVISION
3797 bte = iptr->sx.s23.s3.bte;
3800 if (md->memuse > rd->memuse)
3801 rd->memuse = md->memuse;
3802 if (md->argintreguse > rd->argintreguse)
3803 rd->argintreguse = md->argintreguse;
3805 /* make all stack variables saved */
3809 sd.var[copy->varnum].flags |= SAVEDVAR;
3810 copy->flags |= SAVEDVAR;
3815 #endif /* !SUPPORT_DIVISION */
3826 COUNT(count_pcmd_op);
3827 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3832 coalescing_boundary = sd.new;
3833 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3834 bte = iptr->sx.s23.s3.bte;
3837 if (md->memuse > rd->memuse)
3838 rd->memuse = md->memuse;
3839 if (md->argintreguse > rd->argintreguse)
3840 rd->argintreguse = md->argintreguse;
3841 /* XXX non-leaf method? */
3843 /* make all stack variables saved */
3847 sd.var[copy->varnum].flags |= SAVEDVAR;
3848 copy->flags |= SAVEDVAR;
3853 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3858 #if SUPPORT_LONG_LOGICAL
3862 #endif /* SUPPORT_LONG_LOGICAL */
3863 COUNT(count_pcmd_op);
3864 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3870 COUNT(count_pcmd_op);
3871 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3879 COUNT(count_pcmd_op);
3880 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3888 COUNT(count_pcmd_op);
3889 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3893 COUNT(count_pcmd_op);
3894 #if SUPPORT_LONG_CMP_CONST
3895 if ((len == 0) || (iptr[1].sx.val.i != 0))
3898 switch (iptr[1].opc) {
3900 iptr->opc = ICMD_IF_LCMPEQ;
3902 iptr->dst.insindex = iptr[1].dst.insindex;
3903 iptr[1].opc = ICMD_NOP;
3905 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3908 COUNT(count_pcmd_bra);
3911 iptr->opc = ICMD_IF_LCMPNE;
3912 goto icmd_lcmp_if_tail;
3914 iptr->opc = ICMD_IF_LCMPLT;
3915 goto icmd_lcmp_if_tail;
3917 iptr->opc = ICMD_IF_LCMPGT;
3918 goto icmd_lcmp_if_tail;
3920 iptr->opc = ICMD_IF_LCMPLE;
3921 goto icmd_lcmp_if_tail;
3923 iptr->opc = ICMD_IF_LCMPGE;
3924 goto icmd_lcmp_if_tail;
3930 #endif /* SUPPORT_LONG_CMP_CONST */
3931 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3934 /* XXX why is this deactivated? */
3937 COUNT(count_pcmd_op);
3938 if ((len == 0) || (iptr[1].sx.val.i != 0))
3941 switch (iptr[1].opc) {
3943 iptr->opc = ICMD_IF_FCMPEQ;
3945 iptr->dst.insindex = iptr[1].dst.insindex;
3946 iptr[1].opc = ICMD_NOP;
3948 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3951 COUNT(count_pcmd_bra);
3954 iptr->opc = ICMD_IF_FCMPNE;
3955 goto icmd_if_fcmpl_tail;
3957 iptr->opc = ICMD_IF_FCMPL_LT;
3958 goto icmd_if_fcmpl_tail;
3960 iptr->opc = ICMD_IF_FCMPL_GT;
3961 goto icmd_if_fcmpl_tail;
3963 iptr->opc = ICMD_IF_FCMPL_LE;
3964 goto icmd_if_fcmpl_tail;
3966 iptr->opc = ICMD_IF_FCMPL_GE;
3967 goto icmd_if_fcmpl_tail;
3974 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3978 COUNT(count_pcmd_op);
3979 if ((len == 0) || (iptr[1].sx.val.i != 0))
3982 switch (iptr[1].opc) {
3984 iptr->opc = ICMD_IF_FCMPEQ;
3986 iptr->dst.insindex = iptr[1].dst.insindex;
3987 iptr[1].opc = ICMD_NOP;
3989 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3992 COUNT(count_pcmd_bra);
3995 iptr->opc = ICMD_IF_FCMPNE;
3996 goto icmd_if_fcmpg_tail;
3998 iptr->opc = ICMD_IF_FCMPG_LT;
3999 goto icmd_if_fcmpg_tail;
4001 iptr->opc = ICMD_IF_FCMPG_GT;
4002 goto icmd_if_fcmpg_tail;
4004 iptr->opc = ICMD_IF_FCMPG_LE;
4005 goto icmd_if_fcmpg_tail;
4007 iptr->opc = ICMD_IF_FCMPG_GE;
4008 goto icmd_if_fcmpg_tail;
4015 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4019 COUNT(count_pcmd_op);
4020 if ((len == 0) || (iptr[1].sx.val.i != 0))
4023 switch (iptr[1].opc) {
4025 iptr->opc = ICMD_IF_DCMPEQ;
4027 iptr->dst.insindex = iptr[1].dst.insindex;
4028 iptr[1].opc = ICMD_NOP;
4030 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4033 COUNT(count_pcmd_bra);
4036 iptr->opc = ICMD_IF_DCMPNE;
4037 goto icmd_if_dcmpl_tail;
4039 iptr->opc = ICMD_IF_DCMPL_LT;
4040 goto icmd_if_dcmpl_tail;
4042 iptr->opc = ICMD_IF_DCMPL_GT;
4043 goto icmd_if_dcmpl_tail;
4045 iptr->opc = ICMD_IF_DCMPL_LE;
4046 goto icmd_if_dcmpl_tail;
4048 iptr->opc = ICMD_IF_DCMPL_GE;
4049 goto icmd_if_dcmpl_tail;
4056 OPTT2_1(TYPE_DBL, TYPE_INT);
4060 COUNT(count_pcmd_op);
4061 if ((len == 0) || (iptr[1].sx.val.i != 0))
4064 switch (iptr[1].opc) {
4066 iptr->opc = ICMD_IF_DCMPEQ;
4068 iptr->dst.insindex = iptr[1].dst.insindex;
4069 iptr[1].opc = ICMD_NOP;
4071 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4074 COUNT(count_pcmd_bra);
4077 iptr->opc = ICMD_IF_DCMPNE;
4078 goto icmd_if_dcmpg_tail;
4080 iptr->opc = ICMD_IF_DCMPG_LT;
4081 goto icmd_if_dcmpg_tail;
4083 iptr->opc = ICMD_IF_DCMPG_GT;
4084 goto icmd_if_dcmpg_tail;
4086 iptr->opc = ICMD_IF_DCMPG_LE;
4087 goto icmd_if_dcmpg_tail;
4089 iptr->opc = ICMD_IF_DCMPG_GE;
4090 goto icmd_if_dcmpg_tail;
4097 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4102 COUNT(count_pcmd_op);
4103 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4108 COUNT(count_pcmd_op);
4109 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4118 case ICMD_INT2SHORT:
4119 COUNT(count_pcmd_op);
4120 OP1_1(TYPE_INT, TYPE_INT);
4123 COUNT(count_pcmd_op);
4124 OP1_1(TYPE_LNG, TYPE_LNG);
4127 COUNT(count_pcmd_op);
4128 OP1_1(TYPE_FLT, TYPE_FLT);
4131 COUNT(count_pcmd_op);
4132 OP1_1(TYPE_DBL, TYPE_DBL);
4136 COUNT(count_pcmd_op);
4137 OP1_1(TYPE_INT, TYPE_LNG);
4140 COUNT(count_pcmd_op);
4141 OP1_1(TYPE_INT, TYPE_FLT);
4144 COUNT(count_pcmd_op);
4145 OP1_1(TYPE_INT, TYPE_DBL);
4148 COUNT(count_pcmd_op);
4149 OP1_1(TYPE_LNG, TYPE_INT);
4152 COUNT(count_pcmd_op);
4153 OP1_1(TYPE_LNG, TYPE_FLT);
4156 COUNT(count_pcmd_op);
4157 OP1_1(TYPE_LNG, TYPE_DBL);
4160 COUNT(count_pcmd_op);
4161 OP1_1(TYPE_FLT, TYPE_INT);
4164 COUNT(count_pcmd_op);
4165 OP1_1(TYPE_FLT, TYPE_LNG);
4168 COUNT(count_pcmd_op);
4169 OP1_1(TYPE_FLT, TYPE_DBL);
4172 COUNT(count_pcmd_op);
4173 OP1_1(TYPE_DBL, TYPE_INT);
4176 COUNT(count_pcmd_op);
4177 OP1_1(TYPE_DBL, TYPE_LNG);
4180 COUNT(count_pcmd_op);
4181 OP1_1(TYPE_DBL, TYPE_FLT);
4184 case ICMD_CHECKCAST:
4185 coalescing_boundary = sd.new;
4186 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4187 /* array type cast-check */
4189 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4192 if (md->memuse > rd->memuse)
4193 rd->memuse = md->memuse;
4194 if (md->argintreguse > rd->argintreguse)
4195 rd->argintreguse = md->argintreguse;
4197 /* make all stack variables saved */
4201 sd.var[copy->varnum].flags |= SAVEDVAR;
4202 copy->flags |= SAVEDVAR;
4206 OP1_1(TYPE_ADR, TYPE_ADR);
4209 case ICMD_INSTANCEOF:
4210 case ICMD_ARRAYLENGTH:
4211 coalescing_boundary = sd.new;
4212 OP1_1(TYPE_ADR, TYPE_INT);
4216 case ICMD_ANEWARRAY:
4217 coalescing_boundary = sd.new;
4218 OP1_1(TYPE_INT, TYPE_ADR);
4222 coalescing_boundary = sd.new;
4223 COUNT(count_check_null);
4224 COUNT(count_pcmd_mem);
4225 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4226 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4231 case ICMD_GETSTATIC:
4232 coalescing_boundary = sd.new;
4233 COUNT(count_pcmd_mem);
4234 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4235 OP0_1(fmiref->parseddesc.fd->type);
4239 coalescing_boundary = sd.new;
4246 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4247 tbptr->type = BBTYPE_SBR;
4249 assert(sd.bptr->next); /* XXX exception */
4250 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4251 #if defined(ENABLE_VERIFIER)
4252 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4255 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4259 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4261 /* We need to check for overflow right here because
4262 * the pushed value is poped afterwards */
4265 superblockend = true;
4266 /* XXX should not be marked as interface, as it does not need to be */
4267 /* allocated. Same for the invar of the target. */
4270 /* pop many push any */
4274 bte = iptr->sx.s23.s3.bte;
4278 case ICMD_INVOKESTATIC:
4279 case ICMD_INVOKESPECIAL:
4280 case ICMD_INVOKEVIRTUAL:
4281 case ICMD_INVOKEINTERFACE:
4282 COUNT(count_pcmd_met);
4284 /* Check for functions to replace with builtin
4287 if (builtintable_replace_function(iptr))
4290 INSTRUCTION_GET_METHODDESC(iptr, md);
4291 /* XXX resurrect this COUNT? */
4292 /* if (lm->flags & ACC_STATIC) */
4293 /* {COUNT(count_check_null);} */
4297 coalescing_boundary = sd.new;
4301 if (md->memuse > rd->memuse)
4302 rd->memuse = md->memuse;
4303 if (md->argintreguse > rd->argintreguse)
4304 rd->argintreguse = md->argintreguse;
4305 if (md->argfltreguse > rd->argfltreguse)
4306 rd->argfltreguse = md->argfltreguse;
4310 iptr->s1.argcount = stackdepth;
4311 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4314 for (i-- ; i >= 0; i--) {
4315 iptr->sx.s23.s2.args[i] = copy->varnum;
4317 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4318 /* -> won't help anyway */
4319 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4321 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4322 /* If we pass float arguments in integer argument registers, we
4323 * are not allowed to precolor them here. Floats have to be moved
4324 * to this regs explicitly in codegen().
4325 * Only arguments that are passed by stack anyway can be precolored
4326 * (michi 2005/07/24) */
4327 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4328 (!IS_FLT_DBL_TYPE(copy->type)
4329 || md->params[i].inmemory)) {
4331 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4336 if (md->params[i].inmemory) {
4337 sd.var[copy->varnum].vv.regoff =
4338 md->params[i].regoff;
4339 sd.var[copy->varnum].flags |=
4343 if (IS_FLT_DBL_TYPE(copy->type)) {
4344 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4345 assert(0); /* XXX is this assert ok? */
4347 sd.var[copy->varnum].vv.regoff =
4348 rd->argfltregs[md->params[i].regoff];
4349 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4352 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4353 if (IS_2_WORD_TYPE(copy->type))
4354 sd.var[copy->varnum].vv.regoff =
4355 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4356 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4359 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4360 sd.var[copy->varnum].vv.regoff =
4361 rd->argintregs[md->params[i].regoff];
4369 /* deal with live-through stack slots "under" the */
4375 iptr->sx.s23.s2.args[i++] = copy->varnum;
4376 sd.var[copy->varnum].flags |= SAVEDVAR;
4377 copy->flags |= SAVEDVAR | PASSTHROUGH;
4381 /* pop the arguments */
4390 /* push the return value */
4392 if (md->returntype.type != TYPE_VOID) {
4393 GET_NEW_VAR(sd, new_index, md->returntype.type);
4394 DST(md->returntype.type, new_index);
4399 case ICMD_INLINE_START:
4400 case ICMD_INLINE_END:
4405 case ICMD_MULTIANEWARRAY:
4406 coalescing_boundary = sd.new;
4407 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4408 rd->argintreguse = MIN(3, INT_ARG_CNT);
4410 i = iptr->s1.argcount;
4414 iptr->sx.s23.s2.args = DMNEW(s4, i);
4416 #if defined(SPECIALMEMUSE)
4417 # if defined(__DARWIN__)
4418 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4419 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4421 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4422 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4425 # if defined(__I386__)
4426 if (rd->memuse < i + 3)
4427 rd->memuse = i + 3; /* n integer args spilled on stack */
4428 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4429 if (rd->memuse < i + 2)
4430 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4433 rd->memuse = i; /* n integer args spilled on stack */
4434 # endif /* defined(__I386__) */
4438 /* check INT type here? Currently typecheck does this. */
4439 iptr->sx.s23.s2.args[i] = copy->varnum;
4440 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4441 && (!IS_INOUT(copy))
4442 && (!IS_LOCALVAR(copy)) ) {
4443 copy->varkind = ARGVAR;
4444 sd.var[copy->varnum].flags |=
4445 INMEMORY & PREALLOC;
4446 #if defined(SPECIALMEMUSE)
4447 # if defined(__DARWIN__)
4448 sd.var[copy->varnum].vv.regoff = i +
4449 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4451 sd.var[copy->varnum].vv.regoff = i +
4452 LA_SIZE_IN_POINTERS + 3;
4455 # if defined(__I386__)
4456 sd.var[copy->varnum].vv.regoff = i + 3;
4457 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4458 sd.var[copy->varnum].vv.regoff = i + 2;
4460 sd.var[copy->varnum].vv.regoff = i;
4461 # endif /* defined(__I386__) */
4462 #endif /* defined(SPECIALMEMUSE) */
4467 sd.var[copy->varnum].flags |= SAVEDVAR;
4468 copy->flags |= SAVEDVAR;
4472 i = iptr->s1.argcount;
4477 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4478 DST(TYPE_ADR, new_index);
4484 new_internalerror("Unknown ICMD %d", opcode);
4490 } /* while instructions */
4492 /* stack slots at basic block end become interfaces */
4494 sd.bptr->outdepth = stackdepth;
4495 sd.bptr->outvars = DMNEW(s4, stackdepth);
4498 for (copy = curstack; copy; i--, copy = copy->prev) {
4502 /* with the new vars rd->interfaces will be removed */
4503 /* and all in and outvars have to be STACKVARS! */
4504 /* in the moment i.e. SWAP with in and out vars can */
4505 /* create an unresolvable conflict */
4512 v = sd.var + copy->varnum;
4515 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4516 /* no interface var until now for this depth and */
4518 jd->interface_map[i*5 + t].flags = v->flags;
4521 jd->interface_map[i*5 + t].flags |= v->flags;
4524 sd.bptr->outvars[i] = copy->varnum;
4527 /* check if interface slots at basic block begin must be saved */
4529 for (i=0; i<sd.bptr->indepth; ++i) {
4530 varinfo *v = sd.var + sd.bptr->invars[i];
4537 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4538 /* no interface var until now for this depth and */
4540 jd->interface_map[i*5 + t].flags = v->flags;
4543 jd->interface_map[i*5 + t].flags |= v->flags;
4547 /* store the number of this block's variables */
4549 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4551 #if defined(STACK_VERBOSE)
4552 stack_verbose_block_exit(&sd, superblockend);
4555 /* reach the following block, if any */
4558 if (!stack_reach_next_block(&sd))
4563 } while (sd.repeat && !deadcode);
4565 /* XXX reset TYPE_RET to TYPE_ADR */
4567 for (i=0; i<sd.vartop; ++i) {
4568 if (sd.var[i].type == TYPE_RET)
4569 sd.var[i].type = TYPE_ADR;
4572 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4574 ex = jd->exceptiontable;
4575 for (; ex != NULL; ex = ex->down) {
4576 if (ex->start == ex->end) {
4577 assert(ex->end->next);
4578 ex->end = ex->end->next;
4582 /* store number of created variables */
4584 jd->vartop = sd.vartop;
4586 /* gather statistics *****************************************************/
4588 #if defined(ENABLE_STATISTICS)
4590 if (jd->basicblockcount > count_max_basic_blocks)
4591 count_max_basic_blocks = jd->basicblockcount;
4592 count_basic_blocks += jd->basicblockcount;
4593 if (jd->instructioncount > count_max_javainstr)
4594 count_max_javainstr = jd->instructioncount;
4595 count_javainstr += jd->instructioncount;
4596 if (jd->stackcount > count_upper_bound_new_stack)
4597 count_upper_bound_new_stack = jd->stackcount;
4598 if ((sd.new - jd->stack) > count_max_new_stack)
4599 count_max_new_stack = (sd.new - jd->stack);
4601 sd.bptr = jd->basicblocks;
4602 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4603 if (sd.bptr->flags > BBREACHED) {
4604 if (sd.bptr->indepth >= 10)
4605 count_block_stack[10]++;
4607 count_block_stack[sd.bptr->indepth]++;
4608 len = sd.bptr->icount;
4610 count_block_size_distribution[len]++;
4612 count_block_size_distribution[10]++;
4614 count_block_size_distribution[11]++;
4616 count_block_size_distribution[12]++;
4618 count_block_size_distribution[13]++;
4620 count_block_size_distribution[14]++;
4622 count_block_size_distribution[15]++;
4624 count_block_size_distribution[16]++;
4626 count_block_size_distribution[17]++;
4630 if (iteration_count == 1)
4631 count_analyse_iterations[0]++;
4632 else if (iteration_count == 2)
4633 count_analyse_iterations[1]++;
4634 else if (iteration_count == 3)
4635 count_analyse_iterations[2]++;
4636 else if (iteration_count == 4)
4637 count_analyse_iterations[3]++;
4639 count_analyse_iterations[4]++;
4641 if (jd->basicblockcount <= 5)
4642 count_method_bb_distribution[0]++;
4643 else if (jd->basicblockcount <= 10)
4644 count_method_bb_distribution[1]++;
4645 else if (jd->basicblockcount <= 15)
4646 count_method_bb_distribution[2]++;
4647 else if (jd->basicblockcount <= 20)
4648 count_method_bb_distribution[3]++;
4649 else if (jd->basicblockcount <= 30)
4650 count_method_bb_distribution[4]++;
4651 else if (jd->basicblockcount <= 40)
4652 count_method_bb_distribution[5]++;
4653 else if (jd->basicblockcount <= 50)
4654 count_method_bb_distribution[6]++;
4655 else if (jd->basicblockcount <= 75)
4656 count_method_bb_distribution[7]++;
4658 count_method_bb_distribution[8]++;
4660 #endif /* defined(ENABLE_STATISTICS) */
4662 /* everything's ok *******************************************************/
4666 /* goto labels for throwing verifier exceptions **************************/
4668 #if defined(ENABLE_VERIFIER)
4670 throw_stack_underflow:
4671 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4674 throw_stack_overflow:
4675 exceptions_throw_verifyerror(m, "Stack size too large");
4678 throw_stack_type_error:
4679 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4682 throw_stack_category_error:
4683 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4690 /* functions for verbose stack analysis output ********************************/
4692 #if defined(STACK_VERBOSE)
4693 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4695 printf("%c", show_jit_type_letters[v->type]);
4696 if (v->type == TYPE_RET)
4697 printf("{L%03d}", v->vv.retaddr->nr);
4701 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4703 assert(index >= 0 && index < sd->vartop);
4704 stack_verbose_show_varinfo(sd, sd->var + index);
4708 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4712 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4714 for (i=0; i<bptr->indepth; ++i) {
4717 stack_verbose_show_variable(sd, bptr->invars[i]);
4722 printf("] inlocals [");
4723 if (bptr->inlocals) {
4724 for (i=0; i<sd->localcount; ++i) {
4727 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4732 printf("] out:%d [", bptr->outdepth);
4733 if (bptr->outvars) {
4734 for (i=0; i<bptr->outdepth; ++i) {
4737 stack_verbose_show_variable(sd, bptr->outvars[i]);
4745 printf(" (clone of L%03d)", bptr->original->nr);
4747 basicblock *b = bptr->copied_to;
4749 printf(" (copied to ");
4750 for (; b; b = b->copied_to)
4751 printf("L%03d ", b->nr);
4758 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4762 printf("======================================== STACK %sANALYSE BLOCK ",
4763 (reanalyse) ? "RE-" : "");
4764 stack_verbose_show_block(sd, sd->bptr);
4767 if (sd->handlers[0]) {
4768 printf("HANDLERS: ");
4769 for (i=0; sd->handlers[i]; ++i) {
4770 printf("L%03d ", sd->handlers[i]->handler->nr);
4778 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4780 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4781 stack_verbose_show_block(sd, sd->bptr);
4788 * These are local overrides for various environment variables in Emacs.
4789 * Please do not remove this and leave it at the end of the file, where
4790 * Emacs will automagically detect them.
4791 * ---------------------------------------------------------------------
4794 * indent-tabs-mode: t
4798 * vim:noexpandtab:sw=4:ts=4: