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 5721 2006-10-08 11:39:41Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/show.h"
67 #if defined(ENABLE_DISASSEMBLER)
68 # include "vm/jit/disass.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/stack.h"
74 #if defined(ENABLE_SSA)
75 # include "vm/jit/optimizing/lsra.h"
76 # include "vm/jit/optimizing/ssa.h"
77 #elif defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
81 /*#define STACK_VERBOSE*/
84 /* macro for saving #ifdefs ***************************************************/
86 #if defined(ENABLE_STATISTICS)
87 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
90 if (stackdepth >= 10) \
91 count_store_depth[10]++; \
93 count_store_depth[stackdepth]++; \
96 #else /* !defined(ENABLE_STATISTICS) */
97 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
101 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
104 /* For returnAddresses we use a field of the typeinfo to store from which */
105 /* subroutine the returnAddress will return, if used. */
106 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
107 /* to need it initialised to NULL. This should be investigated. */
109 #if defined(ENABLE_VERIFIER)
110 #define SBRSTART typeinfo.elementclass.any
114 /* stackdata_t *****************************************************************
116 This struct holds internal data during stack analysis.
118 *******************************************************************************/
120 typedef struct stackdata_t stackdata_t;
123 basicblock *bptr; /* the current basic block being analysed */
124 stackptr new; /* next free stackelement */
125 s4 vartop; /* next free variable index */
126 s4 localcount; /* number of locals (at the start of var) */
127 s4 varcount; /* total number of variables allocated */
128 varinfo *var; /* variable array (same as jd->var) */
129 methodinfo *m; /* the method being analysed */
130 jitdata *jd; /* current jitdata */
131 basicblock *last_real_block; /* the last block before the empty one */
132 bool repeat; /* if true, iterate the analysis again */
133 exceptiontable **handlers; /* exception handlers for the current block */
134 exceptiontable *extableend; /* points to the last exception entry */
135 stackelement exstack; /* instack for exception handlers */
139 /* macros for allocating/releasing variable indices *****************/
141 #define GET_NEW_INDEX(sd, new_varindex) \
143 assert((sd).vartop < (sd).varcount); \
144 (new_varindex) = ((sd).vartop)++; \
147 /* Not implemented now - could be used to reuse varindices. */
148 /* Pay attention to not release a localvar once implementing it! */
149 #define RELEASE_INDEX(sd, varindex)
151 #define GET_NEW_VAR(sd, newvarindex, newtype) \
153 GET_NEW_INDEX((sd), (newvarindex)); \
154 (sd).var[newvarindex].type = (newtype); \
158 /* macros for querying variable properties **************************/
160 #define IS_INOUT(sp) \
161 (sd.var[(sp)->varnum].flags & INOUT)
163 #define IS_PREALLOC(sp) \
164 (sd.var[(sp)->varnum].flags & PREALLOC)
166 #define IS_TEMPVAR(sp) \
167 ( ((sp)->varnum >= sd.localcount) \
168 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
171 #define IS_LOCALVAR_SD(sd, sp) \
172 ((sp)->varnum < (sd).localcount)
174 #define IS_LOCALVAR(sp) \
175 IS_LOCALVAR_SD(sd, (sp))
178 /* macros for setting variable properties ****************************/
180 #define SET_TEMPVAR(sp) \
182 if (IS_LOCALVAR((sp))) { \
183 stack_change_to_tempvar(&sd, (sp), iptr); \
185 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
188 #define SET_PREALLOC(sp) \
190 assert(!IS_LOCALVAR((sp))); \
191 sd.var[(sp)->varnum].flags |= PREALLOC; \
195 /* macros for source operands ***************************************/
198 (iptr->s1.varindex = -1)
200 #define USE_S1(type1) \
203 CHECK_BASIC_TYPE(type1, curstack->type); \
204 iptr->s1.varindex = curstack->varnum; \
210 iptr->s1.varindex = curstack->varnum; \
213 #define USE_S1_S2(type1, type2) \
216 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
217 CHECK_BASIC_TYPE(type2, curstack->type); \
218 iptr->sx.s23.s2.varindex = curstack->varnum; \
219 iptr->s1.varindex = curstack->prev->varnum; \
222 #define USE_S1_S2_ANY_ANY \
225 iptr->sx.s23.s2.varindex = curstack->varnum; \
226 iptr->s1.varindex = curstack->prev->varnum; \
229 #define USE_S1_S2_S3(type1, type2, type3) \
232 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
233 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
234 CHECK_BASIC_TYPE(type3, curstack->type); \
235 iptr->sx.s23.s3.varindex = curstack->varnum; \
236 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
237 iptr->s1.varindex = curstack->prev->prev->varnum; \
240 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
243 if (curstack->varkind == UNDEFVAR) \
244 curstack->varkind = TEMPVAR; \
245 curstack = curstack->prev; \
248 #define POP_S1(type1) \
251 if (curstack->varkind == UNDEFVAR) \
252 curstack->varkind = TEMPVAR; \
253 curstack = curstack->prev; \
259 if (curstack->varkind == UNDEFVAR) \
260 curstack->varkind = TEMPVAR; \
261 curstack = curstack->prev; \
264 #define POP_S1_S2(type1, type2) \
266 USE_S1_S2(type1, type2); \
267 if (curstack->varkind == UNDEFVAR) \
268 curstack->varkind = TEMPVAR; \
269 if (curstack->prev->varkind == UNDEFVAR) \
270 curstack->prev->varkind = TEMPVAR; \
271 curstack = curstack->prev->prev; \
274 #define POP_S1_S2_ANY_ANY \
277 if (curstack->varkind == UNDEFVAR) \
278 curstack->varkind = TEMPVAR; \
279 if (curstack->prev->varkind == UNDEFVAR) \
280 curstack->prev->varkind = TEMPVAR; \
281 curstack = curstack->prev->prev; \
284 #define POP_S1_S2_S3(type1, type2, type3) \
286 USE_S1_S2_S3(type1, type2, type3); \
287 if (curstack->varkind == UNDEFVAR) \
288 curstack->varkind = TEMPVAR; \
289 if (curstack->prev->varkind == UNDEFVAR) \
290 curstack->prev->varkind = TEMPVAR; \
291 if (curstack->prev->prev->varkind == UNDEFVAR) \
292 curstack->prev->prev->varkind = TEMPVAR; \
293 curstack = curstack->prev->prev->prev; \
300 /* macros for setting the destination operand ***********************/
303 (iptr->dst.varindex = -1)
305 #define DST(typed, index) \
307 NEWSTACKn((typed),(index)); \
308 curstack->creator = iptr; \
309 iptr->dst.varindex = (index); \
312 #define DST_LOCALVAR(typed, index) \
314 NEWSTACK((typed), LOCALVAR, (index)); \
315 curstack->creator = iptr; \
316 iptr->dst.varindex = (index); \
320 /* macro for propagating constant values ****************************/
322 #if defined(ENABLE_VERIFIER)
323 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
325 (dv)->type = (sv)->type; \
326 (dv)->vv = (sv)->vv; \
327 (dv)->SBRSTART = (sv)->SBRSTART; \
330 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
332 (dv)->type = (sv)->type; \
333 (dv)->vv = (sv)->vv; \
337 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
338 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
341 /* stack modelling macros *******************************************/
343 #define OP0_1(typed) \
346 GET_NEW_VAR(sd, new_index, (typed)); \
347 DST((typed), new_index); \
358 #define OP1_BRANCH(type1) \
364 #define OP1_1(type1, typed) \
367 GET_NEW_VAR(sd, new_index, (typed)); \
368 DST(typed, new_index); \
371 #define OP2_1(type1, type2, typed) \
373 POP_S1_S2(type1, type2); \
374 GET_NEW_VAR(sd, new_index, (typed)); \
375 DST(typed, new_index); \
390 #define OP1_0(type1) \
397 #define OP2_0(type1, type2) \
399 POP_S1_S2(type1, type2); \
404 #define OP2_BRANCH(type1, type2) \
406 POP_S1_S2(type1, type2); \
410 #define OP2_0_ANY_ANY \
417 #define OP3_0(type1, type2, type3) \
419 POP_S1_S2_S3(type1, type2, type3); \
424 #define LOAD(type1, index) \
426 DST_LOCALVAR(type1, index); \
430 #define STORE(type1, index) \
437 /* macros for DUP elimination ***************************************/
439 /* XXX replace NEW_VAR with NEW_INDEX */
440 #define DUP_SLOT(sp) \
442 GET_NEW_VAR(sd, new_index, (sp)->type); \
443 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
444 NEWSTACK((sp)->type, TEMPVAR, new_index); \
447 /* does not check input stackdepth */
448 #define MOVE_UP(sp) \
450 iptr->opc = ICMD_MOVE; \
451 iptr->s1.varindex = (sp)->varnum; \
453 curstack->creator = iptr; \
454 iptr->dst.varindex = curstack->varnum; \
458 /* does not check input stackdepth */
459 #define COPY_UP(sp) \
462 iptr->opc = ICMD_COPY; \
463 iptr->s1.varindex = (sp)->varnum; \
465 curstack->creator = iptr; \
466 iptr->dst.varindex = curstack->varnum; \
470 #define COPY_DOWN(s, d) \
473 iptr->opc = ICMD_COPY; \
474 iptr->s1.varindex = (s)->varnum; \
475 iptr->dst.varindex = (d)->varnum; \
476 (d)->creator = iptr; \
479 #define MOVE_TO_TEMP(sp) \
481 GET_NEW_INDEX(sd, new_index); \
482 iptr->opc = ICMD_MOVE; \
483 iptr->s1.varindex = (sp)->varnum; \
484 iptr->dst.varindex = new_index; \
485 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
486 (sp)->varnum = new_index; \
487 (sp)->varkind = TEMPVAR; \
490 /* macros for branching / reaching basic blocks *********************/
492 #define BRANCH_TARGET(bt, tempbptr) \
494 tempbptr = BLOCK_OF((bt).insindex); \
495 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
497 if (tempbptr == NULL) \
499 (bt).block = tempbptr; \
502 #define BRANCH(tempbptr) \
503 BRANCH_TARGET(iptr->dst, tempbptr)
506 /* forward declarations *******************************************************/
508 static void stack_create_invars(stackdata_t *sd, basicblock *b,
509 stackptr curstack, int stackdepth);
510 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
512 #if defined(STACK_VERBOSE)
513 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
514 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
515 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
516 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
517 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
521 /* stack_init ******************************************************************
523 Initialized the stack analysis subsystem (called by jit_init).
525 *******************************************************************************/
527 bool stack_init(void)
533 /* stack_grow_variable_array ***************************************************
535 Grow the variable array so the given number of additional variables fits in.
538 sd...........stack analysis data
539 num..........number of additional variables
541 *******************************************************************************/
543 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
552 /* XXX avoid too many reallocations */
553 newcount = sd->varcount + num;
555 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
556 sd->varcount = newcount;
557 sd->jd->var = sd->var;
558 sd->jd->varcount = newcount;
562 /* stack_append_block **********************************************************
564 Append the given block after the last real block of the method (before
565 the pseudo-block at the end).
568 sd...........stack analysis data
569 b............the block to append
571 *******************************************************************************/
573 static void stack_append_block(stackdata_t *sd, basicblock *b)
575 #if defined(STACK_VERBOSE)
576 printf("APPENDING BLOCK L%0d\n", b->nr);
579 b->next = sd->last_real_block->next;
580 sd->last_real_block->next = b;
581 sd->last_real_block = b;
582 sd->jd->basicblockcount++;
586 /* stack_clone_block ***********************************************************
588 Create a copy of the given block and insert it at the end of the method.
590 CAUTION: This function does not copy the any variables or the instruction
591 list. It _does_, however, reserve space for the block's invars in the
595 sd...........stack analysis data
596 b............the block to clone
599 a pointer to the copy
601 *******************************************************************************/
603 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
607 clone = DNEW(basicblock);
610 clone->iinstr = NULL;
611 clone->inlocals = NULL;
612 clone->invars = NULL;
614 clone->original = (b->original) ? b->original : b;
615 clone->copied_to = clone->original->copied_to;
616 clone->original->copied_to = clone;
617 clone->nr = sd->m->c_block_nr++;
619 clone->flags = BBREACHED;
621 stack_append_block(sd, clone);
623 /* allocate space for the invars of the clone */
625 stack_grow_variable_array(sd, b->indepth);
627 #if defined(STACK_VERBOSE)
628 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
635 /* stack_create_invars *********************************************************
637 Create the invars for the given basic block. Also make a copy of the locals.
640 sd...........stack analysis data
641 b............block to create the invars for
642 curstack.....current stack top
643 stackdepth...current stack depth
645 This function creates STACKDEPTH invars and sets their types to the
646 types to the types of the corresponding slot in the current stack.
648 *******************************************************************************/
650 static void stack_create_invars(stackdata_t *sd, basicblock *b,
651 stackptr curstack, int stackdepth)
659 assert(sd->vartop + stackdepth <= sd->varcount);
661 b->indepth = stackdepth;
662 b->invars = DMNEW(s4, stackdepth);
664 /* allocate the variable indices */
665 index = (sd->vartop += stackdepth);
668 for (sp = curstack; i--; sp = sp->prev) {
669 b->invars[i] = --index;
670 dv = sd->var + index;
671 sv = sd->var + sp->varnum;
673 COPY_VAL_AND_TYPE_VAR(sv, dv);
676 /* copy the current state of the local variables */
677 /* (one extra local is needed by the verifier) */
679 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
681 for (i=0; i<sd->localcount; ++i)
686 /* stack_create_invars_from_outvars ********************************************
688 Create the invars for the given basic block. Also make a copy of the locals.
689 Types are propagated from the outvars of the current block.
692 sd...........stack analysis data
693 b............block to create the invars for
695 *******************************************************************************/
697 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
703 n = sd->bptr->outdepth;
704 assert(sd->vartop + n <= sd->varcount);
707 b->invars = DMNEW(s4, n);
710 dv = sd->var + sd->vartop;
712 /* allocate the invars */
714 for (i=0; i<n; ++i, ++dv) {
715 sv = sd->var + sd->bptr->outvars[i];
716 b->invars[i] = sd->vartop++;
718 COPY_VAL_AND_TYPE_VAR(sv, dv);
722 /* copy the current state of the local variables */
723 /* (one extra local is needed by the verifier) */
725 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
727 for (i=0; i<sd->localcount; ++i)
732 /* stack_check_invars **********************************************************
734 Check the current stack against the invars of the given basic block.
735 Depth and types must match.
738 sd...........stack analysis data
739 b............block which invars to check against
740 curstack.....current stack top
741 stackdepth...current stack depth
745 NULL.........a VerifyError has been thrown
747 *******************************************************************************/
749 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
750 stackptr curstack, int stackdepth)
759 #if defined(STACK_VERBOSE)
760 printf("stack_check_invars(L%03d)\n", b->nr);
763 /* find original of b */
768 #if defined(STACK_VERBOSE)
769 printf("original is L%03d\n", orig->nr);
774 #if defined(ENABLE_VERIFIER)
775 if (i != stackdepth) {
776 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
784 #if defined(STACK_VERBOSE)
785 printf("checking against ");
786 stack_verbose_show_block(sd, b); printf("\n");
790 for (i = orig->indepth; i--; sp = sp->prev) {
791 dv = sd->var + b->invars[i];
792 sv = sd->var + sp->varnum;
794 #if defined(ENABLE_VERIFIER)
795 if (dv->type != sp->type) {
796 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
801 if (sp->type == TYPE_RET) {
802 #if defined(ENABLE_VERIFIER)
803 if (dv->SBRSTART != sv->SBRSTART) {
804 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
808 if (dv->vv.retaddr != sv->vv.retaddr) {
810 /* don't break! have to check the remaining stackslots */
816 for (i=0; i<sd->localcount; ++i) {
817 dv = b->inlocals + i;
819 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
821 #if defined(ENABLE_VERIFIER)
822 (sv->SBRSTART == dv->SBRSTART) &&
824 (sv->vv.retaddr != dv->vv.retaddr))
834 /* XXX mark mixed type variables void */
835 /* XXX cascading collapse? */
836 #if defined(ENABLE_VERIFIER)
838 for (i=0; i<sd->localcount; ++i) {
839 dv = b->inlocals + i;
841 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
842 && (sv->SBRSTART != dv->SBRSTART))
844 dv->type = TYPE_VOID;
845 b->flags = BBTYPECHECK_REACHED;
846 sd->repeat = true; /* This is very rare, so just repeat */
852 #if defined(STACK_VERBOSE)
853 printf("------> using L%03d\n", b->nr);
857 } while ((b = b->copied_to) != NULL);
859 b = stack_clone_block(sd, orig);
863 stack_create_invars(sd, b, curstack, stackdepth);
868 /* stack_check_invars_from_outvars *********************************************
870 Check the outvars of the current block against the invars of the given block.
871 Depth and types must match.
874 sd...........stack analysis data
875 b............block which invars to check against
879 NULL.........a VerifyError has been thrown
881 *******************************************************************************/
883 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
891 #if defined(STACK_VERBOSE)
892 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
895 /* find original of b */
900 #if defined(STACK_VERBOSE)
901 printf("original is L%03d\n", orig->nr);
905 n = sd->bptr->outdepth;
907 #if defined(ENABLE_VERIFIER)
909 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
917 #if defined(STACK_VERBOSE)
918 printf("checking against ");
919 stack_verbose_show_block(sd, b); printf("\n");
923 dv = sd->var + b->invars[0];
925 for (i=0; i<n; ++i, ++dv) {
926 sv = sd->var + sd->bptr->outvars[i];
928 #if defined(ENABLE_VERIFIER)
929 if (sv->type != dv->type) {
930 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
935 if (dv->type == TYPE_RET) {
936 #if defined(ENABLE_VERIFIER)
937 if (sv->SBRSTART != dv->SBRSTART) {
938 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
942 if (sv->vv.retaddr != dv->vv.retaddr) {
944 /* don't break! have to check the remaining stackslots */
951 for (i=0; i<sd->localcount; ++i) {
952 dv = b->inlocals + i;
955 #if defined(ENABLE_VERIFIER)
956 (sv->SBRSTART == dv->SBRSTART) &&
958 (sv->type == TYPE_RET && dv->type == TYPE_RET))
960 if (sv->vv.retaddr != dv->vv.retaddr) {
969 /* XXX mark mixed type variables void */
970 /* XXX cascading collapse? */
971 #if defined(ENABLE_VERIFIER)
973 for (i=0; i<sd->localcount; ++i) {
974 dv = b->inlocals + i;
976 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
977 && (sv->SBRSTART != dv->SBRSTART))
979 dv->type = TYPE_VOID;
980 b->flags = BBTYPECHECK_REACHED;
981 sd->repeat = true; /* This is very rare, so just repeat */
987 #if defined(STACK_VERBOSE)
988 printf("------> using L%03d\n", b->nr);
992 } while ((b = b->copied_to) != NULL);
994 b = stack_clone_block(sd, orig);
998 stack_create_invars_from_outvars(sd, b);
1003 /* stack_create_instack ********************************************************
1005 Create the instack of the current basic block.
1008 sd...........stack analysis data
1011 the current stack top at the start of the basic block.
1013 *******************************************************************************/
1015 static stackptr stack_create_instack(stackdata_t *sd)
1021 if ((depth = sd->bptr->indepth) == 0)
1024 sp = (sd->new += depth);
1028 index = sd->bptr->invars[depth];
1030 sp->type = sd->var[index].type;
1034 sp->varkind = STACKVAR;
1038 /* return the top of the created stack */
1043 /* stack_mark_reached **********************************************************
1045 Mark the given block reached and propagate the current stack and locals to
1046 it. This function specializes the target block, if necessary, and returns
1047 a pointer to the specialized target.
1050 sd...........stack analysis data
1051 b............the block to reach
1052 curstack.....the current stack top
1053 stackdepth...the current stack depth
1056 a pointer to (a specialized version of) the target
1057 NULL.........a VerifyError has been thrown
1059 *******************************************************************************/
1061 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1063 #if defined(STACK_VERBOSE)
1064 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1066 /* mark targets of backward branches */
1068 b->bitflags |= BBFLAG_REPLACEMENT;
1070 if (b->flags < BBREACHED) {
1071 /* b is reached for the first time. Create its invars. */
1073 #if defined(STACK_VERBOSE)
1074 printf("reached L%03d for the first time\n", b->nr);
1077 stack_create_invars(sd, b, curstack, stackdepth);
1079 b->flags = BBREACHED;
1084 /* b has been reached before. Check that its invars match. */
1086 return stack_check_invars(sd, b, curstack, stackdepth);
1091 /* stack_mark_reached_from_outvars *********************************************
1093 Mark the given block reached and propagate the outvars of the current block
1094 and the current locals to it. This function specializes the target block,
1095 if necessary, and returns a pointer to the specialized target.
1098 sd...........stack analysis data
1099 b............the block to reach
1102 a pointer to (a specialized version of) the target
1103 NULL.........a VerifyError has been thrown
1105 *******************************************************************************/
1107 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1109 #if defined(STACK_VERBOSE)
1110 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1112 /* mark targets of backward branches */
1114 b->bitflags |= BBFLAG_REPLACEMENT;
1116 if (b->flags < BBREACHED) {
1117 /* b is reached for the first time. Create its invars. */
1119 #if defined(STACK_VERBOSE)
1120 printf("reached L%03d for the first time\n", b->nr);
1123 stack_create_invars_from_outvars(sd, b);
1125 b->flags = BBREACHED;
1130 /* b has been reached before. Check that its invars match. */
1132 return stack_check_invars_from_outvars(sd, b);
1137 /* stack_reach_next_block ******************************************************
1139 Mark the following block reached and propagate the outvars of the current block
1140 and the current locals to it. This function specializes the target block,
1141 if necessary, and returns a pointer to the specialized target.
1144 sd...........stack analysis data
1147 a pointer to (a specialized version of) the following block
1148 NULL.........a VerifyError has been thrown
1150 *******************************************************************************/
1152 static bool stack_reach_next_block(stackdata_t *sd)
1157 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1158 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1162 if (tbptr != sd->bptr->next) {
1163 #if defined(STACK_VERBOSE)
1164 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1166 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1167 assert(iptr->opc == ICMD_NOP);
1168 iptr->opc = ICMD_GOTO;
1169 iptr->dst.block = tbptr;
1171 if (tbptr->flags < BBFINISHED)
1172 sd->repeat = true; /* XXX check if we really need to repeat */
1179 /* stack_reach_handlers ********************************************************
1181 Reach the exception handlers for the current block.
1184 sd...........stack analysis data
1187 true.........everything ok
1188 false........a VerifyError has been thrown
1190 *******************************************************************************/
1192 static bool stack_reach_handlers(stackdata_t *sd)
1197 #if defined(STACK_VERBOSE)
1198 printf("reaching exception handlers...\n");
1201 for (i=0; sd->handlers[i]; ++i) {
1202 tbptr = sd->handlers[i]->handler;
1204 tbptr->type = BBTYPE_EXH;
1205 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1207 /* reach (and specialize) the handler block */
1209 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1214 sd->handlers[i]->handler = tbptr;
1221 /* stack_reanalyse_block ******************************************************
1223 Re-analyse the current block. This is called if either the block itself
1224 has already been analysed before, or the current block is a clone of an
1225 already analysed block, and this clone is reached for the first time.
1226 In the latter case, this function does all that is necessary for fully
1227 cloning the block (cloning the instruction list and variables, etc.).
1230 sd...........stack analysis data
1233 true.........everything ok
1234 false........a VerifyError has been thrown
1236 *******************************************************************************/
1238 #define RELOCATE(index) \
1240 if ((index) >= blockvarstart) \
1241 (index) += blockvarshift; \
1242 else if ((index) >= invarstart) \
1243 (index) += invarshift; \
1246 bool stack_reanalyse_block(stackdata_t *sd)
1258 branch_target_t *table;
1259 lookup_target_t *lookup;
1262 bool cloneinstructions;
1265 #if defined(STACK_VERBOSE)
1266 stack_verbose_block_enter(sd, true);
1273 assert(orig != NULL);
1275 /* clone the instruction list */
1277 cloneinstructions = true;
1279 assert(orig->iinstr);
1281 iptr = DMNEW(instruction, len + 1);
1283 MCOPY(iptr, orig->iinstr, instruction, len);
1284 iptr[len].opc = ICMD_NOP;
1288 /* allocate space for the clone's block variables */
1290 stack_grow_variable_array(sd, orig->varcount);
1292 /* we already have the invars set */
1294 assert(b->indepth == orig->indepth);
1296 /* calculate relocation shifts for invars and block variables */
1298 if (orig->indepth) {
1299 invarstart = orig->invars[0];
1300 invarshift = b->invars[0] - invarstart;
1303 invarstart = INT_MAX;
1306 blockvarstart = orig->varstart;
1307 blockvarshift = sd->vartop - blockvarstart;
1309 /* copy block variables */
1311 b->varstart = sd->vartop;
1312 b->varcount = orig->varcount;
1313 sd->vartop += b->varcount;
1314 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1318 b->outdepth = orig->outdepth;
1319 b->outvars = DMNEW(s4, orig->outdepth);
1320 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1322 /* clone exception handlers */
1324 for (i=0; sd->handlers[i]; ++i) {
1325 ex = DNEW(exceptiontable);
1326 ex->handler = sd->handlers[i]->handler;
1328 ex->end = b; /* XXX hack, see end of stack_analyse */
1329 ex->catchtype = sd->handlers[i]->catchtype;
1332 assert(sd->extableend->down == NULL);
1333 sd->extableend->down = ex;
1334 sd->extableend = ex;
1335 sd->jd->cd->exceptiontablelength++;
1337 sd->handlers[i] = ex;
1341 cloneinstructions = false;
1344 invarstart = sd->vartop;
1345 blockvarstart = sd->vartop;
1350 /* find exception handlers for the cloned block */
1352 ex = sd->jd->cd->exceptiontable;
1353 for (; ex != NULL; ex = ex->down) {
1354 /* XXX the cloned exception handlers have identical */
1355 /* start end end blocks. */
1356 if ((ex->start == b) && (ex->end == b)) {
1357 sd->handlers[len++] = ex;
1360 sd->handlers[len] = NULL;
1363 #if defined(STACK_VERBOSE)
1364 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1365 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1368 /* mark block as finished */
1370 b->flags = BBFINISHED;
1372 /* initialize locals at the start of this block */
1375 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1377 /* reach exception handlers for this block */
1379 if (!stack_reach_handlers(sd))
1382 superblockend = false;
1384 for (len = b->icount; len--; iptr++) {
1385 #if defined(STACK_VERBOSE)
1386 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1392 switch (iptr->opc) {
1394 j = iptr->s1.varindex;
1396 #if defined(ENABLE_VERIFIER)
1397 if (sd->var[j].type != TYPE_RET) {
1398 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1403 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1404 superblockend = true;
1408 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1409 superblockend = true;
1413 superblockend = true;
1416 case ICMD_CHECKNULL:
1417 case ICMD_PUTSTATICCONST:
1423 case ICMD_INLINE_START:
1424 case ICMD_INLINE_END:
1425 case ICMD_INLINE_GOTO:
1429 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1430 superblockend = true;
1433 /* pop 0 push 1 const */
1442 /* pop 0 push 1 load */
1449 RELOCATE(iptr->dst.varindex);
1462 RELOCATE(iptr->sx.s23.s2.varindex);
1463 RELOCATE(iptr->s1.varindex);
1464 RELOCATE(iptr->dst.varindex);
1478 RELOCATE(iptr->sx.s23.s3.varindex);
1479 RELOCATE(iptr->sx.s23.s2.varindex);
1480 RELOCATE(iptr->s1.varindex);
1484 /* pop 1 push 0 store */
1491 RELOCATE(iptr->s1.varindex);
1493 j = iptr->dst.varindex;
1494 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1506 RELOCATE(iptr->s1.varindex);
1507 superblockend = true;
1510 case ICMD_PUTSTATIC:
1511 case ICMD_PUTFIELDCONST:
1514 RELOCATE(iptr->s1.varindex);
1517 /* pop 1 push 0 branch */
1520 case ICMD_IFNONNULL:
1535 RELOCATE(iptr->s1.varindex);
1536 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1539 /* pop 1 push 0 table branch */
1541 case ICMD_TABLESWITCH:
1542 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1544 if (cloneinstructions) {
1545 table = DMNEW(branch_target_t, i);
1546 MCOPY(table, iptr->dst.table, branch_target_t, i);
1547 iptr->dst.table = table;
1550 table = iptr->dst.table;
1553 RELOCATE(iptr->s1.varindex);
1555 table->block = stack_mark_reached_from_outvars(sd, table->block);
1558 superblockend = true;
1561 case ICMD_LOOKUPSWITCH:
1562 i = iptr->sx.s23.s2.lookupcount;
1563 if (cloneinstructions) {
1564 lookup = DMNEW(lookup_target_t, i);
1565 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1566 iptr->dst.lookup = lookup;
1569 lookup = iptr->dst.lookup;
1571 RELOCATE(iptr->s1.varindex);
1573 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1576 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1577 superblockend = true;
1580 case ICMD_MONITORENTER:
1581 case ICMD_MONITOREXIT:
1582 RELOCATE(iptr->s1.varindex);
1586 /* pop 2 push 0 branch */
1588 case ICMD_IF_ICMPEQ:
1589 case ICMD_IF_ICMPNE:
1590 case ICMD_IF_ICMPLT:
1591 case ICMD_IF_ICMPGE:
1592 case ICMD_IF_ICMPGT:
1593 case ICMD_IF_ICMPLE:
1595 case ICMD_IF_LCMPEQ:
1596 case ICMD_IF_LCMPNE:
1597 case ICMD_IF_LCMPLT:
1598 case ICMD_IF_LCMPGE:
1599 case ICMD_IF_LCMPGT:
1600 case ICMD_IF_LCMPLE:
1602 case ICMD_IF_FCMPEQ:
1603 case ICMD_IF_FCMPNE:
1605 case ICMD_IF_FCMPL_LT:
1606 case ICMD_IF_FCMPL_GE:
1607 case ICMD_IF_FCMPL_GT:
1608 case ICMD_IF_FCMPL_LE:
1610 case ICMD_IF_FCMPG_LT:
1611 case ICMD_IF_FCMPG_GE:
1612 case ICMD_IF_FCMPG_GT:
1613 case ICMD_IF_FCMPG_LE:
1615 case ICMD_IF_DCMPEQ:
1616 case ICMD_IF_DCMPNE:
1618 case ICMD_IF_DCMPL_LT:
1619 case ICMD_IF_DCMPL_GE:
1620 case ICMD_IF_DCMPL_GT:
1621 case ICMD_IF_DCMPL_LE:
1623 case ICMD_IF_DCMPG_LT:
1624 case ICMD_IF_DCMPG_GE:
1625 case ICMD_IF_DCMPG_GT:
1626 case ICMD_IF_DCMPG_LE:
1628 case ICMD_IF_ACMPEQ:
1629 case ICMD_IF_ACMPNE:
1630 RELOCATE(iptr->sx.s23.s2.varindex);
1631 RELOCATE(iptr->s1.varindex);
1632 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1638 case ICMD_IASTORECONST:
1639 case ICMD_LASTORECONST:
1640 case ICMD_AASTORECONST:
1641 case ICMD_BASTORECONST:
1642 case ICMD_CASTORECONST:
1643 case ICMD_SASTORECONST:
1646 RELOCATE(iptr->sx.s23.s2.varindex);
1647 RELOCATE(iptr->s1.varindex);
1650 /* pop 0 push 1 copy */
1654 RELOCATE(iptr->dst.varindex);
1655 RELOCATE(iptr->s1.varindex);
1656 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1699 RELOCATE(iptr->sx.s23.s2.varindex);
1700 RELOCATE(iptr->s1.varindex);
1701 RELOCATE(iptr->dst.varindex);
1706 case ICMD_CHECKCAST:
1707 case ICMD_ARRAYLENGTH:
1708 case ICMD_INSTANCEOF:
1710 case ICMD_ANEWARRAY:
1713 case ICMD_IADDCONST:
1714 case ICMD_ISUBCONST:
1715 case ICMD_IMULCONST:
1719 case ICMD_IANDCONST:
1721 case ICMD_IXORCONST:
1722 case ICMD_ISHLCONST:
1723 case ICMD_ISHRCONST:
1724 case ICMD_IUSHRCONST:
1725 case ICMD_LADDCONST:
1726 case ICMD_LSUBCONST:
1727 case ICMD_LMULCONST:
1731 case ICMD_LANDCONST:
1733 case ICMD_LXORCONST:
1734 case ICMD_LSHLCONST:
1735 case ICMD_LSHRCONST:
1736 case ICMD_LUSHRCONST:
1740 case ICMD_INT2SHORT:
1756 RELOCATE(iptr->s1.varindex);
1757 RELOCATE(iptr->dst.varindex);
1762 case ICMD_GETSTATIC:
1765 RELOCATE(iptr->dst.varindex);
1768 /* pop many push any */
1770 case ICMD_INVOKESTATIC:
1771 case ICMD_INVOKESPECIAL:
1772 case ICMD_INVOKEVIRTUAL:
1773 case ICMD_INVOKEINTERFACE:
1775 case ICMD_MULTIANEWARRAY:
1776 i = iptr->s1.argcount;
1777 if (cloneinstructions) {
1778 argp = DMNEW(s4, i);
1779 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1780 iptr->sx.s23.s2.args = argp;
1783 argp = iptr->sx.s23.s2.args;
1791 RELOCATE(iptr->dst.varindex);
1796 new_internalerror("Unknown ICMD %d during stack re-analysis",
1801 #if defined(STACK_VERBOSE)
1802 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1807 /* relocate outvars */
1809 for (i=0; i<b->outdepth; ++i) {
1810 RELOCATE(b->outvars[i]);
1813 #if defined(STACK_VERBOSE)
1814 stack_verbose_block_exit(sd, superblockend);
1817 /* propagate to the next block */
1820 if (!stack_reach_next_block(sd))
1827 /* stack_change_to_tempvar *****************************************************
1829 Change the given stackslot to a TEMPVAR. This includes creating a new
1830 temporary variable and changing the dst.varindex of the creator of the
1831 stacklot to the new variable index. If this stackslot has been passed
1832 through ICMDs between the point of its creation and the current point,
1833 then the variable index is also changed in these ICMDs.
1836 sd...........stack analysis data
1837 sp...........stackslot to change
1838 ilimit.......instruction up to which to look for ICMDs passing-through
1839 the stackslot (exclusive). This may point exactly after the
1840 last instruction, in which case the search is done to the
1843 *******************************************************************************/
1845 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1846 instruction *ilimit)
1853 oldindex = sp->varnum;
1855 /* create a new temporary variable */
1857 GET_NEW_VAR(*sd, newindex, sp->type);
1859 sd->var[newindex].flags = sp->flags;
1861 /* change the stackslot */
1863 sp->varnum = newindex;
1864 sp->varkind = TEMPVAR;
1866 /* change the dst.varindex of the stackslot's creator */
1869 sp->creator->dst.varindex = newindex;
1871 /* handle ICMDs this stackslot passed through, if any */
1873 if (sp->flags & PASSTHROUGH) {
1874 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1876 /* asser that the limit point to an ICMD, or after the last one */
1877 assert(ilimit >= sd->bptr->iinstr);
1878 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1880 for (; iptr < ilimit; ++iptr) {
1881 switch (iptr->opc) {
1882 case ICMD_INVOKESTATIC:
1883 case ICMD_INVOKESPECIAL:
1884 case ICMD_INVOKEVIRTUAL:
1885 case ICMD_INVOKEINTERFACE:
1888 for (i=0; i<iptr->s1.argcount; ++i)
1889 if (iptr->sx.s23.s2.args[i] == oldindex) {
1890 iptr->sx.s23.s2.args[i] = newindex;
1893 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1894 /* stackslot, it must be added in this switch! */
1901 /* stack_analyse ***************************************************************
1903 Analyse_stack uses the intermediate code created by parse.c to
1904 build a model of the JVM operand stack for the current method.
1906 The following checks are performed:
1907 - check for operand stack underflow (before each instruction)
1908 - check for operand stack overflow (after[1] each instruction)
1909 - check for matching stack depth at merging points
1910 - check for matching basic types[2] at merging points
1911 - check basic types for instruction input (except for BUILTIN*
1912 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1914 [1]) Checking this after the instruction should be ok. parse.c
1915 counts the number of required stack slots in such a way that it is
1916 only vital that we don't exceed `maxstack` at basic block
1919 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1920 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1921 types are not discerned.
1923 *******************************************************************************/
1925 bool stack_analyse(jitdata *jd)
1927 methodinfo *m; /* method being analyzed */
1932 #if defined(ENABLE_SSA)
1935 int b_index; /* basic block index */
1937 stackptr curstack; /* current stack top */
1939 int opcode; /* opcode of current instruction */
1942 int len; /* # of instructions after the current one */
1943 bool superblockend; /* if true, no fallthrough to next block */
1944 bool deadcode; /* true if no live code has been reached */
1945 instruction *iptr; /* the current instruction */
1947 basicblock *original;
1950 stackptr *last_store_boundary;
1951 stackptr coalescing_boundary;
1953 stackptr src1, src2, src3, src4, dst1, dst2;
1955 branch_target_t *table;
1956 lookup_target_t *lookup;
1957 #if defined(ENABLE_VERIFIER)
1958 int expectedtype; /* used by CHECK_BASIC_TYPE */
1960 builtintable_entry *bte;
1962 constant_FMIref *fmiref;
1963 #if defined(ENABLE_STATISTICS)
1964 int iteration_count; /* number of iterations of analysis */
1966 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1968 #if defined(STACK_VERBOSE)
1969 show_method(jd, SHOW_PARSE);
1972 /* get required compiler data - initialization */
1978 #if defined(ENABLE_SSA)
1982 /* initialize the stackdata_t struct */
1986 sd.varcount = jd->varcount;
1987 sd.vartop = jd->vartop;
1988 sd.localcount = jd->localcount;
1990 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1992 /* prepare the variable for exception handler stacks */
1993 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
1995 sd.exstack.type = TYPE_ADR;
1996 sd.exstack.prev = NULL;
1997 sd.exstack.varnum = sd.localcount;
1998 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2000 #if defined(ENABLE_LSRA)
2001 m->maxlifetimes = 0;
2004 #if defined(ENABLE_STATISTICS)
2005 iteration_count = 0;
2008 /* find the last real basic block */
2010 sd.last_real_block = NULL;
2011 tbptr = jd->basicblocks;
2012 while (tbptr->next) {
2013 sd.last_real_block = tbptr;
2014 tbptr = tbptr->next;
2016 assert(sd.last_real_block);
2018 /* find the last exception handler */
2020 if (cd->exceptiontablelength)
2021 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
2023 sd.extableend = NULL;
2025 /* init jd->interface_map */
2027 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2028 for (i = 0; i < m->maxstack * 5; i++)
2029 jd->interface_map[i].flags = UNUSED;
2031 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
2033 /* initialize flags and invars (none) of first block */
2035 jd->basicblocks[0].flags = BBREACHED;
2036 jd->basicblocks[0].invars = NULL;
2037 jd->basicblocks[0].indepth = 0;
2038 jd->basicblocks[0].inlocals =
2039 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2040 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2041 jd->localcount + VERIFIER_EXTRA_LOCALS);
2043 /* stack analysis loop (until fixpoint reached) **************************/
2046 #if defined(ENABLE_STATISTICS)
2050 /* initialize loop over basic blocks */
2052 sd.bptr = jd->basicblocks;
2053 superblockend = true;
2055 curstack = NULL; stackdepth = 0;
2058 /* iterate over basic blocks *****************************************/
2060 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2062 if (sd.bptr->flags == BBDELETED) {
2063 /* This block has been deleted - do nothing. */
2068 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2069 /* re-analyse a block because its input changed */
2070 if (!stack_reanalyse_block(&sd))
2072 superblockend = true; /* XXX */
2076 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2077 /* This block has not been reached so far, and we */
2078 /* don't fall into it, so we'll have to iterate again. */
2084 if (sd.bptr->flags > BBREACHED) {
2085 /* This block is already finished. */
2087 superblockend = true;
2091 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2092 /* This block is a clone and the original has not been */
2093 /* analysed, yet. Analyse it on the next iteration. */
2096 /* XXX superblockend? */
2100 /* This block has to be analysed now. */
2102 /* XXX The rest of this block is still indented one level too */
2103 /* much in order to avoid a giant diff by changing that. */
2105 /* We know that sd.bptr->flags == BBREACHED. */
2106 /* This block has been reached before. */
2108 assert(sd.bptr->flags == BBREACHED);
2109 stackdepth = sd.bptr->indepth;
2111 /* find exception handlers for this block */
2113 /* determine the active exception handlers for this block */
2114 /* XXX could use a faster algorithm with sorted lists or */
2117 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2120 ex = cd->exceptiontable;
2121 for (; ex != NULL; ex = ex->down) {
2122 if ((ex->start <= original) && (ex->end > original)) {
2123 sd.handlers[len++] = ex;
2126 sd.handlers[len] = NULL;
2129 /* reanalyse cloned block */
2131 if (sd.bptr->original) {
2132 if (!stack_reanalyse_block(&sd))
2137 /* reset the new pointer for allocating stackslots */
2141 /* create the instack of this block */
2143 curstack = stack_create_instack(&sd);
2145 /* initialize locals at the start of this block */
2147 if (sd.bptr->inlocals)
2148 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2150 /* set up local variables for analyzing this block */
2153 superblockend = false;
2154 len = sd.bptr->icount;
2155 iptr = sd.bptr->iinstr;
2156 b_index = sd.bptr - jd->basicblocks;
2158 /* mark the block as analysed */
2160 sd.bptr->flags = BBFINISHED;
2162 /* reset variables for dependency checking */
2164 coalescing_boundary = sd.new;
2165 for( i = 0; i < cd->maxlocals; i++)
2166 last_store_boundary[i] = sd.new;
2168 /* remember the start of this block's variables */
2170 sd.bptr->varstart = sd.vartop;
2172 #if defined(STACK_VERBOSE)
2173 stack_verbose_block_enter(&sd, false);
2176 /* reach exception handlers for this block */
2178 if (!stack_reach_handlers(&sd))
2181 /* iterate over ICMDs ****************************************/
2183 while (--len >= 0) {
2185 #if defined(STACK_VERBOSE)
2186 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2187 for( copy = curstack; copy; copy = copy->prev ) {
2188 printf("%2d(%d", copy->varnum, copy->type);
2191 if (IS_PREALLOC(copy))
2198 /* fetch the current opcode */
2202 /* automatically replace some ICMDs with builtins */
2204 #if defined(USEBUILTINTABLE)
2205 bte = builtintable_get_automatic(opcode);
2207 if (bte && bte->opcode == opcode) {
2208 iptr->opc = ICMD_BUILTIN;
2209 iptr->flags.bits = 0;
2210 iptr->sx.s23.s3.bte = bte;
2211 /* iptr->line is already set */
2212 jd->isleafmethod = false;
2215 #endif /* defined(USEBUILTINTABLE) */
2217 /* main opcode switch *************************************/
2229 case ICMD_CHECKNULL:
2230 coalescing_boundary = sd.new;
2231 COUNT(count_check_null);
2234 CLR_DST; /* XXX live through? */
2238 j = iptr->s1.varindex =
2239 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2241 #if defined(ENABLE_VERIFIER)
2242 if (sd.var[j].type != TYPE_RET) {
2243 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2250 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2251 superblockend = true;
2255 COUNT(count_pcmd_return);
2258 superblockend = true;
2262 /* pop 0 push 1 const */
2264 /************************** ICONST OPTIMIZATIONS **************************/
2267 COUNT(count_pcmd_load);
2271 switch (iptr[1].opc) {
2273 iptr->opc = ICMD_IADDCONST;
2277 iptr[1].opc = ICMD_NOP;
2278 OP1_1(TYPE_INT, TYPE_INT);
2279 COUNT(count_pcmd_op);
2283 iptr->opc = ICMD_ISUBCONST;
2284 goto icmd_iconst_tail;
2285 #if SUPPORT_CONST_MUL
2287 iptr->opc = ICMD_IMULCONST;
2288 goto icmd_iconst_tail;
2289 #else /* SUPPORT_CONST_MUL */
2291 if (iptr->sx.val.i == 0x00000002)
2293 else if (iptr->sx.val.i == 0x00000004)
2295 else if (iptr->sx.val.i == 0x00000008)
2297 else if (iptr->sx.val.i == 0x00000010)
2299 else if (iptr->sx.val.i == 0x00000020)
2301 else if (iptr->sx.val.i == 0x00000040)
2303 else if (iptr->sx.val.i == 0x00000080)
2305 else if (iptr->sx.val.i == 0x00000100)
2307 else if (iptr->sx.val.i == 0x00000200)
2309 else if (iptr->sx.val.i == 0x00000400)
2310 iptr->sx.val.i = 10;
2311 else if (iptr->sx.val.i == 0x00000800)
2312 iptr->sx.val.i = 11;
2313 else if (iptr->sx.val.i == 0x00001000)
2314 iptr->sx.val.i = 12;
2315 else if (iptr->sx.val.i == 0x00002000)
2316 iptr->sx.val.i = 13;
2317 else if (iptr->sx.val.i == 0x00004000)
2318 iptr->sx.val.i = 14;
2319 else if (iptr->sx.val.i == 0x00008000)
2320 iptr->sx.val.i = 15;
2321 else if (iptr->sx.val.i == 0x00010000)
2322 iptr->sx.val.i = 16;
2323 else if (iptr->sx.val.i == 0x00020000)
2324 iptr->sx.val.i = 17;
2325 else if (iptr->sx.val.i == 0x00040000)
2326 iptr->sx.val.i = 18;
2327 else if (iptr->sx.val.i == 0x00080000)
2328 iptr->sx.val.i = 19;
2329 else if (iptr->sx.val.i == 0x00100000)
2330 iptr->sx.val.i = 20;
2331 else if (iptr->sx.val.i == 0x00200000)
2332 iptr->sx.val.i = 21;
2333 else if (iptr->sx.val.i == 0x00400000)
2334 iptr->sx.val.i = 22;
2335 else if (iptr->sx.val.i == 0x00800000)
2336 iptr->sx.val.i = 23;
2337 else if (iptr->sx.val.i == 0x01000000)
2338 iptr->sx.val.i = 24;
2339 else if (iptr->sx.val.i == 0x02000000)
2340 iptr->sx.val.i = 25;
2341 else if (iptr->sx.val.i == 0x04000000)
2342 iptr->sx.val.i = 26;
2343 else if (iptr->sx.val.i == 0x08000000)
2344 iptr->sx.val.i = 27;
2345 else if (iptr->sx.val.i == 0x10000000)
2346 iptr->sx.val.i = 28;
2347 else if (iptr->sx.val.i == 0x20000000)
2348 iptr->sx.val.i = 29;
2349 else if (iptr->sx.val.i == 0x40000000)
2350 iptr->sx.val.i = 30;
2351 else if (iptr->sx.val.i == 0x80000000)
2352 iptr->sx.val.i = 31;
2356 iptr->opc = ICMD_IMULPOW2;
2357 goto icmd_iconst_tail;
2358 #endif /* SUPPORT_CONST_MUL */
2360 if (iptr->sx.val.i == 0x00000002)
2362 else if (iptr->sx.val.i == 0x00000004)
2364 else if (iptr->sx.val.i == 0x00000008)
2366 else if (iptr->sx.val.i == 0x00000010)
2368 else if (iptr->sx.val.i == 0x00000020)
2370 else if (iptr->sx.val.i == 0x00000040)
2372 else if (iptr->sx.val.i == 0x00000080)
2374 else if (iptr->sx.val.i == 0x00000100)
2376 else if (iptr->sx.val.i == 0x00000200)
2378 else if (iptr->sx.val.i == 0x00000400)
2379 iptr->sx.val.i = 10;
2380 else if (iptr->sx.val.i == 0x00000800)
2381 iptr->sx.val.i = 11;
2382 else if (iptr->sx.val.i == 0x00001000)
2383 iptr->sx.val.i = 12;
2384 else if (iptr->sx.val.i == 0x00002000)
2385 iptr->sx.val.i = 13;
2386 else if (iptr->sx.val.i == 0x00004000)
2387 iptr->sx.val.i = 14;
2388 else if (iptr->sx.val.i == 0x00008000)
2389 iptr->sx.val.i = 15;
2390 else if (iptr->sx.val.i == 0x00010000)
2391 iptr->sx.val.i = 16;
2392 else if (iptr->sx.val.i == 0x00020000)
2393 iptr->sx.val.i = 17;
2394 else if (iptr->sx.val.i == 0x00040000)
2395 iptr->sx.val.i = 18;
2396 else if (iptr->sx.val.i == 0x00080000)
2397 iptr->sx.val.i = 19;
2398 else if (iptr->sx.val.i == 0x00100000)
2399 iptr->sx.val.i = 20;
2400 else if (iptr->sx.val.i == 0x00200000)
2401 iptr->sx.val.i = 21;
2402 else if (iptr->sx.val.i == 0x00400000)
2403 iptr->sx.val.i = 22;
2404 else if (iptr->sx.val.i == 0x00800000)
2405 iptr->sx.val.i = 23;
2406 else if (iptr->sx.val.i == 0x01000000)
2407 iptr->sx.val.i = 24;
2408 else if (iptr->sx.val.i == 0x02000000)
2409 iptr->sx.val.i = 25;
2410 else if (iptr->sx.val.i == 0x04000000)
2411 iptr->sx.val.i = 26;
2412 else if (iptr->sx.val.i == 0x08000000)
2413 iptr->sx.val.i = 27;
2414 else if (iptr->sx.val.i == 0x10000000)
2415 iptr->sx.val.i = 28;
2416 else if (iptr->sx.val.i == 0x20000000)
2417 iptr->sx.val.i = 29;
2418 else if (iptr->sx.val.i == 0x40000000)
2419 iptr->sx.val.i = 30;
2420 else if (iptr->sx.val.i == 0x80000000)
2421 iptr->sx.val.i = 31;
2425 iptr->opc = ICMD_IDIVPOW2;
2426 goto icmd_iconst_tail;
2429 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2430 if ((iptr->sx.val.i == 0x00000002) ||
2431 (iptr->sx.val.i == 0x00000004) ||
2432 (iptr->sx.val.i == 0x00000008) ||
2433 (iptr->sx.val.i == 0x00000010) ||
2434 (iptr->sx.val.i == 0x00000020) ||
2435 (iptr->sx.val.i == 0x00000040) ||
2436 (iptr->sx.val.i == 0x00000080) ||
2437 (iptr->sx.val.i == 0x00000100) ||
2438 (iptr->sx.val.i == 0x00000200) ||
2439 (iptr->sx.val.i == 0x00000400) ||
2440 (iptr->sx.val.i == 0x00000800) ||
2441 (iptr->sx.val.i == 0x00001000) ||
2442 (iptr->sx.val.i == 0x00002000) ||
2443 (iptr->sx.val.i == 0x00004000) ||
2444 (iptr->sx.val.i == 0x00008000) ||
2445 (iptr->sx.val.i == 0x00010000) ||
2446 (iptr->sx.val.i == 0x00020000) ||
2447 (iptr->sx.val.i == 0x00040000) ||
2448 (iptr->sx.val.i == 0x00080000) ||
2449 (iptr->sx.val.i == 0x00100000) ||
2450 (iptr->sx.val.i == 0x00200000) ||
2451 (iptr->sx.val.i == 0x00400000) ||
2452 (iptr->sx.val.i == 0x00800000) ||
2453 (iptr->sx.val.i == 0x01000000) ||
2454 (iptr->sx.val.i == 0x02000000) ||
2455 (iptr->sx.val.i == 0x04000000) ||
2456 (iptr->sx.val.i == 0x08000000) ||
2457 (iptr->sx.val.i == 0x10000000) ||
2458 (iptr->sx.val.i == 0x20000000) ||
2459 (iptr->sx.val.i == 0x40000000) ||
2460 (iptr->sx.val.i == 0x80000000))
2462 iptr->opc = ICMD_IREMPOW2;
2463 iptr->sx.val.i -= 1;
2464 goto icmd_iconst_tail;
2467 #if SUPPORT_CONST_LOGICAL
2469 iptr->opc = ICMD_IANDCONST;
2470 goto icmd_iconst_tail;
2473 iptr->opc = ICMD_IORCONST;
2474 goto icmd_iconst_tail;
2477 iptr->opc = ICMD_IXORCONST;
2478 goto icmd_iconst_tail;
2480 #endif /* SUPPORT_CONST_LOGICAL */
2482 iptr->opc = ICMD_ISHLCONST;
2483 goto icmd_iconst_tail;
2486 iptr->opc = ICMD_ISHRCONST;
2487 goto icmd_iconst_tail;
2490 iptr->opc = ICMD_IUSHRCONST;
2491 goto icmd_iconst_tail;
2492 #if SUPPORT_LONG_SHIFT
2494 iptr->opc = ICMD_LSHLCONST;
2495 goto icmd_lconst_tail;
2498 iptr->opc = ICMD_LSHRCONST;
2499 goto icmd_lconst_tail;
2502 iptr->opc = ICMD_LUSHRCONST;
2503 goto icmd_lconst_tail;
2504 #endif /* SUPPORT_LONG_SHIFT */
2505 case ICMD_IF_ICMPEQ:
2506 iptr[1].opc = ICMD_IFEQ;
2510 /* set the constant for the following icmd */
2511 iptr[1].sx.val.i = iptr->sx.val.i;
2513 /* this instruction becomes a nop */
2514 iptr->opc = ICMD_NOP;
2517 case ICMD_IF_ICMPLT:
2518 iptr[1].opc = ICMD_IFLT;
2519 goto icmd_if_icmp_tail;
2521 case ICMD_IF_ICMPLE:
2522 iptr[1].opc = ICMD_IFLE;
2523 goto icmd_if_icmp_tail;
2525 case ICMD_IF_ICMPNE:
2526 iptr[1].opc = ICMD_IFNE;
2527 goto icmd_if_icmp_tail;
2529 case ICMD_IF_ICMPGT:
2530 iptr[1].opc = ICMD_IFGT;
2531 goto icmd_if_icmp_tail;
2533 case ICMD_IF_ICMPGE:
2534 iptr[1].opc = ICMD_IFGE;
2535 goto icmd_if_icmp_tail;
2537 #if SUPPORT_CONST_STORE
2542 # if SUPPORT_CONST_STORE_ZERO_ONLY
2543 if (iptr->sx.val.i != 0)
2546 switch (iptr[1].opc) {
2548 iptr->opc = ICMD_IASTORECONST;
2549 iptr->flags.bits |= INS_FLAG_CHECK;
2552 iptr->opc = ICMD_BASTORECONST;
2553 iptr->flags.bits |= INS_FLAG_CHECK;
2556 iptr->opc = ICMD_CASTORECONST;
2557 iptr->flags.bits |= INS_FLAG_CHECK;
2560 iptr->opc = ICMD_SASTORECONST;
2561 iptr->flags.bits |= INS_FLAG_CHECK;
2565 iptr[1].opc = ICMD_NOP;
2567 /* copy the constant to s3 */
2568 /* XXX constval -> astoreconstval? */
2569 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2570 OP2_0(TYPE_ADR, TYPE_INT);
2571 COUNT(count_pcmd_op);
2574 case ICMD_PUTSTATIC:
2576 # if SUPPORT_CONST_STORE_ZERO_ONLY
2577 if (iptr->sx.val.i != 0)
2580 /* XXX check field type? */
2582 /* copy the constant to s2 */
2583 /* XXX constval -> fieldconstval? */
2584 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2587 /* set the field reference (s3) */
2588 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2589 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2590 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2593 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2596 switch (iptr[1].opc) {
2597 case ICMD_PUTSTATIC:
2598 iptr->opc = ICMD_PUTSTATICCONST;
2602 iptr->opc = ICMD_PUTFIELDCONST;
2607 iptr[1].opc = ICMD_NOP;
2608 COUNT(count_pcmd_op);
2610 #endif /* SUPPORT_CONST_STORE */
2616 /* if we get here, the ICONST has been optimized */
2620 /* normal case of an unoptimized ICONST */
2624 /************************** LCONST OPTIMIZATIONS **************************/
2627 COUNT(count_pcmd_load);
2631 /* switch depending on the following instruction */
2633 switch (iptr[1].opc) {
2634 #if SUPPORT_LONG_ADD
2636 iptr->opc = ICMD_LADDCONST;
2640 /* instruction of type LONG -> LONG */
2641 iptr[1].opc = ICMD_NOP;
2642 OP1_1(TYPE_LNG, TYPE_LNG);
2643 COUNT(count_pcmd_op);
2647 iptr->opc = ICMD_LSUBCONST;
2648 goto icmd_lconst_tail;
2650 #endif /* SUPPORT_LONG_ADD */
2651 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2653 iptr->opc = ICMD_LMULCONST;
2654 goto icmd_lconst_tail;
2655 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2656 # if SUPPORT_LONG_SHIFT
2658 if (iptr->sx.val.l == 0x00000002)
2660 else if (iptr->sx.val.l == 0x00000004)
2662 else if (iptr->sx.val.l == 0x00000008)
2664 else if (iptr->sx.val.l == 0x00000010)
2666 else if (iptr->sx.val.l == 0x00000020)
2668 else if (iptr->sx.val.l == 0x00000040)
2670 else if (iptr->sx.val.l == 0x00000080)
2672 else if (iptr->sx.val.l == 0x00000100)
2674 else if (iptr->sx.val.l == 0x00000200)
2676 else if (iptr->sx.val.l == 0x00000400)
2677 iptr->sx.val.i = 10;
2678 else if (iptr->sx.val.l == 0x00000800)
2679 iptr->sx.val.i = 11;
2680 else if (iptr->sx.val.l == 0x00001000)
2681 iptr->sx.val.i = 12;
2682 else if (iptr->sx.val.l == 0x00002000)
2683 iptr->sx.val.i = 13;
2684 else if (iptr->sx.val.l == 0x00004000)
2685 iptr->sx.val.i = 14;
2686 else if (iptr->sx.val.l == 0x00008000)
2687 iptr->sx.val.i = 15;
2688 else if (iptr->sx.val.l == 0x00010000)
2689 iptr->sx.val.i = 16;
2690 else if (iptr->sx.val.l == 0x00020000)
2691 iptr->sx.val.i = 17;
2692 else if (iptr->sx.val.l == 0x00040000)
2693 iptr->sx.val.i = 18;
2694 else if (iptr->sx.val.l == 0x00080000)
2695 iptr->sx.val.i = 19;
2696 else if (iptr->sx.val.l == 0x00100000)
2697 iptr->sx.val.i = 20;
2698 else if (iptr->sx.val.l == 0x00200000)
2699 iptr->sx.val.i = 21;
2700 else if (iptr->sx.val.l == 0x00400000)
2701 iptr->sx.val.i = 22;
2702 else if (iptr->sx.val.l == 0x00800000)
2703 iptr->sx.val.i = 23;
2704 else if (iptr->sx.val.l == 0x01000000)
2705 iptr->sx.val.i = 24;
2706 else if (iptr->sx.val.l == 0x02000000)
2707 iptr->sx.val.i = 25;
2708 else if (iptr->sx.val.l == 0x04000000)
2709 iptr->sx.val.i = 26;
2710 else if (iptr->sx.val.l == 0x08000000)
2711 iptr->sx.val.i = 27;
2712 else if (iptr->sx.val.l == 0x10000000)
2713 iptr->sx.val.i = 28;
2714 else if (iptr->sx.val.l == 0x20000000)
2715 iptr->sx.val.i = 29;
2716 else if (iptr->sx.val.l == 0x40000000)
2717 iptr->sx.val.i = 30;
2718 else if (iptr->sx.val.l == 0x80000000)
2719 iptr->sx.val.i = 31;
2723 iptr->opc = ICMD_LMULPOW2;
2724 goto icmd_lconst_tail;
2725 # endif /* SUPPORT_LONG_SHIFT */
2726 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2727 #if SUPPORT_LONG_DIV_POW2
2729 if (iptr->sx.val.l == 0x00000002)
2731 else if (iptr->sx.val.l == 0x00000004)
2733 else if (iptr->sx.val.l == 0x00000008)
2735 else if (iptr->sx.val.l == 0x00000010)
2737 else if (iptr->sx.val.l == 0x00000020)
2739 else if (iptr->sx.val.l == 0x00000040)
2741 else if (iptr->sx.val.l == 0x00000080)
2743 else if (iptr->sx.val.l == 0x00000100)
2745 else if (iptr->sx.val.l == 0x00000200)
2747 else if (iptr->sx.val.l == 0x00000400)
2748 iptr->sx.val.i = 10;
2749 else if (iptr->sx.val.l == 0x00000800)
2750 iptr->sx.val.i = 11;
2751 else if (iptr->sx.val.l == 0x00001000)
2752 iptr->sx.val.i = 12;
2753 else if (iptr->sx.val.l == 0x00002000)
2754 iptr->sx.val.i = 13;
2755 else if (iptr->sx.val.l == 0x00004000)
2756 iptr->sx.val.i = 14;
2757 else if (iptr->sx.val.l == 0x00008000)
2758 iptr->sx.val.i = 15;
2759 else if (iptr->sx.val.l == 0x00010000)
2760 iptr->sx.val.i = 16;
2761 else if (iptr->sx.val.l == 0x00020000)
2762 iptr->sx.val.i = 17;
2763 else if (iptr->sx.val.l == 0x00040000)
2764 iptr->sx.val.i = 18;
2765 else if (iptr->sx.val.l == 0x00080000)
2766 iptr->sx.val.i = 19;
2767 else if (iptr->sx.val.l == 0x00100000)
2768 iptr->sx.val.i = 20;
2769 else if (iptr->sx.val.l == 0x00200000)
2770 iptr->sx.val.i = 21;
2771 else if (iptr->sx.val.l == 0x00400000)
2772 iptr->sx.val.i = 22;
2773 else if (iptr->sx.val.l == 0x00800000)
2774 iptr->sx.val.i = 23;
2775 else if (iptr->sx.val.l == 0x01000000)
2776 iptr->sx.val.i = 24;
2777 else if (iptr->sx.val.l == 0x02000000)
2778 iptr->sx.val.i = 25;
2779 else if (iptr->sx.val.l == 0x04000000)
2780 iptr->sx.val.i = 26;
2781 else if (iptr->sx.val.l == 0x08000000)
2782 iptr->sx.val.i = 27;
2783 else if (iptr->sx.val.l == 0x10000000)
2784 iptr->sx.val.i = 28;
2785 else if (iptr->sx.val.l == 0x20000000)
2786 iptr->sx.val.i = 29;
2787 else if (iptr->sx.val.l == 0x40000000)
2788 iptr->sx.val.i = 30;
2789 else if (iptr->sx.val.l == 0x80000000)
2790 iptr->sx.val.i = 31;
2794 iptr->opc = ICMD_LDIVPOW2;
2795 goto icmd_lconst_tail;
2796 #endif /* SUPPORT_LONG_DIV_POW2 */
2798 #if SUPPORT_LONG_REM_POW2
2800 if ((iptr->sx.val.l == 0x00000002) ||
2801 (iptr->sx.val.l == 0x00000004) ||
2802 (iptr->sx.val.l == 0x00000008) ||
2803 (iptr->sx.val.l == 0x00000010) ||
2804 (iptr->sx.val.l == 0x00000020) ||
2805 (iptr->sx.val.l == 0x00000040) ||
2806 (iptr->sx.val.l == 0x00000080) ||
2807 (iptr->sx.val.l == 0x00000100) ||
2808 (iptr->sx.val.l == 0x00000200) ||
2809 (iptr->sx.val.l == 0x00000400) ||
2810 (iptr->sx.val.l == 0x00000800) ||
2811 (iptr->sx.val.l == 0x00001000) ||
2812 (iptr->sx.val.l == 0x00002000) ||
2813 (iptr->sx.val.l == 0x00004000) ||
2814 (iptr->sx.val.l == 0x00008000) ||
2815 (iptr->sx.val.l == 0x00010000) ||
2816 (iptr->sx.val.l == 0x00020000) ||
2817 (iptr->sx.val.l == 0x00040000) ||
2818 (iptr->sx.val.l == 0x00080000) ||
2819 (iptr->sx.val.l == 0x00100000) ||
2820 (iptr->sx.val.l == 0x00200000) ||
2821 (iptr->sx.val.l == 0x00400000) ||
2822 (iptr->sx.val.l == 0x00800000) ||
2823 (iptr->sx.val.l == 0x01000000) ||
2824 (iptr->sx.val.l == 0x02000000) ||
2825 (iptr->sx.val.l == 0x04000000) ||
2826 (iptr->sx.val.l == 0x08000000) ||
2827 (iptr->sx.val.l == 0x10000000) ||
2828 (iptr->sx.val.l == 0x20000000) ||
2829 (iptr->sx.val.l == 0x40000000) ||
2830 (iptr->sx.val.l == 0x80000000))
2832 iptr->opc = ICMD_LREMPOW2;
2833 iptr->sx.val.l -= 1;
2834 goto icmd_lconst_tail;
2837 #endif /* SUPPORT_LONG_REM_POW2 */
2839 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2842 iptr->opc = ICMD_LANDCONST;
2843 goto icmd_lconst_tail;
2846 iptr->opc = ICMD_LORCONST;
2847 goto icmd_lconst_tail;
2850 iptr->opc = ICMD_LXORCONST;
2851 goto icmd_lconst_tail;
2852 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2854 #if SUPPORT_LONG_CMP_CONST
2856 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2859 /* switch on the instruction after LCONST - LCMP */
2861 switch (iptr[2].opc) {
2863 iptr->opc = ICMD_IF_LEQ;
2866 icmd_lconst_lcmp_tail:
2867 /* convert LCONST, LCMP, IFXX to IF_LXX */
2868 iptr->dst.insindex = iptr[2].dst.insindex;
2869 iptr[1].opc = ICMD_NOP;
2870 iptr[2].opc = ICMD_NOP;
2872 OP1_BRANCH(TYPE_LNG);
2874 COUNT(count_pcmd_bra);
2875 COUNT(count_pcmd_op);
2879 iptr->opc = ICMD_IF_LNE;
2880 goto icmd_lconst_lcmp_tail;
2883 iptr->opc = ICMD_IF_LLT;
2884 goto icmd_lconst_lcmp_tail;
2887 iptr->opc = ICMD_IF_LGT;
2888 goto icmd_lconst_lcmp_tail;
2891 iptr->opc = ICMD_IF_LLE;
2892 goto icmd_lconst_lcmp_tail;
2895 iptr->opc = ICMD_IF_LGE;
2896 goto icmd_lconst_lcmp_tail;
2900 } /* end switch on opcode after LCONST - LCMP */
2902 #endif /* SUPPORT_LONG_CMP_CONST */
2904 #if SUPPORT_CONST_STORE
2906 # if SUPPORT_CONST_STORE_ZERO_ONLY
2907 if (iptr->sx.val.l != 0)
2910 #if SIZEOF_VOID_P == 4
2911 /* the constant must fit into a ptrint */
2912 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2915 /* move the constant to s3 */
2916 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2918 iptr->opc = ICMD_LASTORECONST;
2919 iptr->flags.bits |= INS_FLAG_CHECK;
2920 OP2_0(TYPE_ADR, TYPE_INT);
2922 iptr[1].opc = ICMD_NOP;
2923 COUNT(count_pcmd_op);
2926 case ICMD_PUTSTATIC:
2928 # if SUPPORT_CONST_STORE_ZERO_ONLY
2929 if (iptr->sx.val.l != 0)
2932 #if SIZEOF_VOID_P == 4
2933 /* the constant must fit into a ptrint */
2934 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2937 /* XXX check field type? */
2939 /* copy the constant to s2 */
2940 /* XXX constval -> fieldconstval? */
2941 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2945 #endif /* SUPPORT_CONST_STORE */
2949 } /* end switch opcode after LCONST */
2951 /* if we get here, the LCONST has been optimized */
2955 /* the normal case of an unoptimized LCONST */
2959 /************************ END OF LCONST OPTIMIZATIONS *********************/
2962 COUNT(count_pcmd_load);
2967 COUNT(count_pcmd_load);
2971 /************************** ACONST OPTIMIZATIONS **************************/
2974 coalescing_boundary = sd.new;
2975 COUNT(count_pcmd_load);
2976 #if SUPPORT_CONST_STORE
2977 /* We can only optimize if the ACONST is resolved
2978 * and there is an instruction after it. */
2980 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2983 switch (iptr[1].opc) {
2985 /* We can only optimize for NULL values
2986 * here because otherwise a checkcast is
2988 if (iptr->sx.val.anyptr != NULL)
2991 /* copy the constant (NULL) to s3 */
2992 iptr->sx.s23.s3.constval = 0;
2993 iptr->opc = ICMD_AASTORECONST;
2994 iptr->flags.bits |= INS_FLAG_CHECK;
2995 OP2_0(TYPE_ADR, TYPE_INT);
2997 iptr[1].opc = ICMD_NOP;
2998 COUNT(count_pcmd_op);
3001 case ICMD_PUTSTATIC:
3003 # if SUPPORT_CONST_STORE_ZERO_ONLY
3004 if (iptr->sx.val.anyptr != NULL)
3007 /* XXX check field type? */
3008 /* copy the constant to s2 */
3009 /* XXX constval -> fieldconstval? */
3010 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3018 /* if we get here the ACONST has been optimized */
3022 #endif /* SUPPORT_CONST_STORE */
3027 /* pop 0 push 1 load */
3034 COUNT(count_load_instruction);
3035 i = opcode - ICMD_ILOAD; /* type */
3037 j = iptr->s1.varindex =
3038 jd->local_map[iptr->s1.varindex * 5 + i];
3040 #if defined(ENABLE_VERIFIER)
3041 if (sd.var[j].type == TYPE_RET) {
3042 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3047 #if defined(ENABLE_SSA)
3049 GET_NEW_VAR(sd, new_index, i);
3066 coalescing_boundary = sd.new;
3067 iptr->flags.bits |= INS_FLAG_CHECK;
3068 COUNT(count_check_null);
3069 COUNT(count_check_bound);
3070 COUNT(count_pcmd_mem);
3071 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3078 coalescing_boundary = sd.new;
3079 iptr->flags.bits |= INS_FLAG_CHECK;
3080 COUNT(count_check_null);
3081 COUNT(count_check_bound);
3082 COUNT(count_pcmd_mem);
3083 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3086 /* pop 0 push 0 iinc */
3089 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3090 #if defined(ENABLE_SSA)
3093 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3097 last_store_boundary[iptr->s1.varindex] = sd.new;
3100 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3105 if ((copy->varkind == LOCALVAR) &&
3106 (copy->varnum == iptr->s1.varindex))
3108 assert(IS_LOCALVAR(copy));
3114 #if defined(ENABLE_SSA)
3118 iptr->dst.varindex = iptr->s1.varindex;
3121 /* pop 1 push 0 store */
3130 i = opcode - ICMD_ISTORE; /* type */
3131 javaindex = iptr->dst.varindex;
3132 j = iptr->dst.varindex =
3133 jd->local_map[javaindex * 5 + i];
3135 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3137 #if defined(ENABLE_STATISTICS)
3140 i = sd.new - curstack;
3142 count_store_length[20]++;
3144 count_store_length[i]++;
3147 count_store_depth[10]++;
3149 count_store_depth[i]++;
3153 #if defined(ENABLE_SSA)
3156 /* check for conflicts as described in Figure 5.2 */
3158 copy = curstack->prev;
3161 if ((copy->varkind == LOCALVAR) &&
3162 (copy->varnum == j))
3164 copy->varkind = TEMPVAR;
3165 assert(IS_LOCALVAR(copy));
3172 /* if the variable is already coalesced, don't bother */
3174 /* We do not need to check against INOUT, as invars */
3175 /* are always before the coalescing boundary. */
3177 if (curstack->varkind == LOCALVAR)
3180 /* there is no STORE Lj while curstack is live */
3182 if (curstack < last_store_boundary[javaindex])
3183 goto assume_conflict;
3185 /* curstack must be after the coalescing boundary */
3187 if (curstack < coalescing_boundary)
3188 goto assume_conflict;
3190 /* there is no DEF LOCALVAR(j) while curstack is live */
3192 copy = sd.new; /* most recent stackslot created + 1 */
3193 while (--copy > curstack) {
3194 if (copy->varkind == LOCALVAR && copy->varnum == j)
3195 goto assume_conflict;
3198 /* coalesce the temporary variable with Lj */
3199 assert((curstack->varkind == TEMPVAR)
3200 || (curstack->varkind == UNDEFVAR));
3201 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3202 assert(!IS_INOUT(curstack));
3203 assert(!IS_PREALLOC(curstack));
3205 assert(curstack->creator);
3206 assert(curstack->creator->dst.varindex == curstack->varnum);
3207 assert(!(curstack->flags & PASSTHROUGH));
3208 RELEASE_INDEX(sd, curstack);
3209 curstack->varkind = LOCALVAR;
3210 curstack->varnum = j;
3211 curstack->creator->dst.varindex = j;
3214 /* revert the coalescing, if it has been done earlier */
3216 if ((curstack->varkind == LOCALVAR)
3217 && (curstack->varnum == j))
3219 assert(IS_LOCALVAR(curstack));
3220 SET_TEMPVAR(curstack);
3223 /* remember the stack boundary at this store */
3225 last_store_boundary[javaindex] = sd.new;
3226 #if defined(ENABLE_SSA)
3227 } /* if (ls != NULL) */
3230 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3233 STORE(opcode - ICMD_ISTORE, j);
3239 coalescing_boundary = sd.new;
3240 iptr->flags.bits |= INS_FLAG_CHECK;
3241 COUNT(count_check_null);
3242 COUNT(count_check_bound);
3243 COUNT(count_pcmd_mem);
3245 bte = builtintable_get_internal(BUILTIN_canstore);
3248 if (md->memuse > rd->memuse)
3249 rd->memuse = md->memuse;
3250 if (md->argintreguse > rd->argintreguse)
3251 rd->argintreguse = md->argintreguse;
3252 /* XXX non-leaf method? */
3254 /* make all stack variables saved */
3258 sd.var[copy->varnum].flags |= SAVEDVAR;
3259 /* in case copy->varnum is/will be a LOCALVAR */
3260 /* once and set back to a non LOCALVAR */
3261 /* the correct SAVEDVAR flag has to be */
3262 /* remembered in copy->flags, too */
3263 copy->flags |= SAVEDVAR;
3267 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3274 coalescing_boundary = sd.new;
3275 iptr->flags.bits |= INS_FLAG_CHECK;
3276 COUNT(count_check_null);
3277 COUNT(count_check_bound);
3278 COUNT(count_pcmd_mem);
3279 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3286 coalescing_boundary = sd.new;
3287 iptr->flags.bits |= INS_FLAG_CHECK;
3288 COUNT(count_check_null);
3289 COUNT(count_check_bound);
3290 COUNT(count_pcmd_mem);
3291 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3297 #ifdef ENABLE_VERIFIER
3300 if (IS_2_WORD_TYPE(curstack->type))
3301 goto throw_stack_category_error;
3312 coalescing_boundary = sd.new;
3313 /* Assert here that no LOCAL or INOUTS get */
3314 /* preallocated, since tha macros are not */
3315 /* available in md-abi.c! */
3316 if (IS_TEMPVAR(curstack))
3317 md_return_alloc(jd, curstack);
3318 COUNT(count_pcmd_return);
3319 OP1_0(opcode - ICMD_IRETURN);
3320 superblockend = true;
3324 coalescing_boundary = sd.new;
3325 COUNT(count_check_null);
3327 curstack = NULL; stackdepth = 0;
3328 superblockend = true;
3331 case ICMD_PUTSTATIC:
3332 coalescing_boundary = sd.new;
3333 COUNT(count_pcmd_mem);
3334 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3335 OP1_0(fmiref->parseddesc.fd->type);
3338 /* pop 1 push 0 branch */
3341 case ICMD_IFNONNULL:
3342 COUNT(count_pcmd_bra);
3343 OP1_BRANCH(TYPE_ADR);
3353 COUNT(count_pcmd_bra);
3354 /* iptr->sx.val.i is set implicitly in parse by
3355 clearing the memory or from IF_ICMPxx
3358 OP1_BRANCH(TYPE_INT);
3359 /* iptr->sx.val.i = 0; */
3363 /* pop 0 push 0 branch */
3366 COUNT(count_pcmd_bra);
3369 superblockend = true;
3372 /* pop 1 push 0 table branch */
3374 case ICMD_TABLESWITCH:
3375 COUNT(count_pcmd_table);
3376 OP1_BRANCH(TYPE_INT);
3378 table = iptr->dst.table;
3379 BRANCH_TARGET(*table, tbptr);
3382 i = iptr->sx.s23.s3.tablehigh
3383 - iptr->sx.s23.s2.tablelow + 1;
3386 BRANCH_TARGET(*table, tbptr);
3389 superblockend = true;
3392 /* pop 1 push 0 table branch */
3394 case ICMD_LOOKUPSWITCH:
3395 COUNT(count_pcmd_table);
3396 OP1_BRANCH(TYPE_INT);
3398 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3400 lookup = iptr->dst.lookup;
3402 i = iptr->sx.s23.s2.lookupcount;
3405 BRANCH_TARGET(lookup->target, tbptr);
3408 superblockend = true;
3411 case ICMD_MONITORENTER:
3412 case ICMD_MONITOREXIT:
3413 coalescing_boundary = sd.new;
3414 COUNT(count_check_null);
3418 /* pop 2 push 0 branch */
3420 case ICMD_IF_ICMPEQ:
3421 case ICMD_IF_ICMPNE:
3422 case ICMD_IF_ICMPLT:
3423 case ICMD_IF_ICMPGE:
3424 case ICMD_IF_ICMPGT:
3425 case ICMD_IF_ICMPLE:
3426 COUNT(count_pcmd_bra);
3427 OP2_BRANCH(TYPE_INT, TYPE_INT);
3431 case ICMD_IF_ACMPEQ:
3432 case ICMD_IF_ACMPNE:
3433 COUNT(count_pcmd_bra);
3434 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3441 coalescing_boundary = sd.new;
3442 COUNT(count_check_null);
3443 COUNT(count_pcmd_mem);
3444 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3445 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3450 if (!IS_2_WORD_TYPE(curstack->type)) {
3452 #ifdef ENABLE_VERIFIER
3455 if (IS_2_WORD_TYPE(curstack->prev->type))
3456 goto throw_stack_category_error;
3459 OP2_0_ANY_ANY; /* pop two slots */
3462 iptr->opc = ICMD_POP;
3463 OP1_0_ANY; /* pop one (two-word) slot */
3467 /* pop 0 push 1 dup */
3470 #ifdef ENABLE_VERIFIER
3473 if (IS_2_WORD_TYPE(curstack->type))
3474 goto throw_stack_category_error;
3477 COUNT(count_dup_instruction);
3483 coalescing_boundary = sd.new - 1;
3488 if (IS_2_WORD_TYPE(curstack->type)) {
3490 iptr->opc = ICMD_DUP;
3495 /* ..., ????, cat1 */
3496 #ifdef ENABLE_VERIFIER
3498 if (IS_2_WORD_TYPE(curstack->prev->type))
3499 goto throw_stack_category_error;
3502 src1 = curstack->prev;
3505 COPY_UP(src1); iptr++; len--;
3508 coalescing_boundary = sd.new;
3512 /* pop 2 push 3 dup */
3515 #ifdef ENABLE_VERIFIER
3518 if (IS_2_WORD_TYPE(curstack->type) ||
3519 IS_2_WORD_TYPE(curstack->prev->type))
3520 goto throw_stack_category_error;
3525 src1 = curstack->prev;
3530 /* move non-temporary sources out of the way */
3531 if (!IS_TEMPVAR(src2)) {
3532 MOVE_TO_TEMP(src2); iptr++; len--;
3535 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3537 MOVE_UP(src1); iptr++; len--;
3538 MOVE_UP(src2); iptr++; len--;
3540 COPY_DOWN(curstack, dst1);
3542 coalescing_boundary = sd.new;
3547 if (IS_2_WORD_TYPE(curstack->type)) {
3548 /* ..., ????, cat2 */
3549 #ifdef ENABLE_VERIFIER
3551 if (IS_2_WORD_TYPE(curstack->prev->type))
3552 goto throw_stack_category_error;
3555 iptr->opc = ICMD_DUP_X1;
3559 /* ..., ????, cat1 */
3560 #ifdef ENABLE_VERIFIER
3563 if (IS_2_WORD_TYPE(curstack->prev->type)
3564 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3565 goto throw_stack_category_error;
3570 src1 = curstack->prev->prev;
3571 src2 = curstack->prev;
3573 POPANY; POPANY; POPANY;
3576 /* move non-temporary sources out of the way */
3577 if (!IS_TEMPVAR(src2)) {
3578 MOVE_TO_TEMP(src2); iptr++; len--;
3580 if (!IS_TEMPVAR(src3)) {
3581 MOVE_TO_TEMP(src3); iptr++; len--;
3584 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3585 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3587 MOVE_UP(src1); iptr++; len--;
3588 MOVE_UP(src2); iptr++; len--;
3589 MOVE_UP(src3); iptr++; len--;
3591 COPY_DOWN(curstack, dst2); iptr++; len--;
3592 COPY_DOWN(curstack->prev, dst1);
3594 coalescing_boundary = sd.new;
3598 /* pop 3 push 4 dup */
3602 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3603 /* ..., cat2, ???? */
3604 #ifdef ENABLE_VERIFIER
3606 if (IS_2_WORD_TYPE(curstack->type))
3607 goto throw_stack_category_error;
3610 iptr->opc = ICMD_DUP_X1;
3614 /* ..., cat1, ???? */
3615 #ifdef ENABLE_VERIFIER
3618 if (IS_2_WORD_TYPE(curstack->type)
3619 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3620 goto throw_stack_category_error;
3624 src1 = curstack->prev->prev;
3625 src2 = curstack->prev;
3627 POPANY; POPANY; POPANY;
3630 /* move non-temporary sources out of the way */
3631 if (!IS_TEMPVAR(src2)) {
3632 MOVE_TO_TEMP(src2); iptr++; len--;
3634 if (!IS_TEMPVAR(src3)) {
3635 MOVE_TO_TEMP(src3); iptr++; len--;
3638 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3640 MOVE_UP(src1); iptr++; len--;
3641 MOVE_UP(src2); iptr++; len--;
3642 MOVE_UP(src3); iptr++; len--;
3644 COPY_DOWN(curstack, dst1);
3646 coalescing_boundary = sd.new;
3652 if (IS_2_WORD_TYPE(curstack->type)) {
3653 /* ..., ????, cat2 */
3654 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3655 /* ..., cat2, cat2 */
3656 iptr->opc = ICMD_DUP_X1;
3660 /* ..., cat1, cat2 */
3661 #ifdef ENABLE_VERIFIER
3664 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3665 goto throw_stack_category_error;
3668 iptr->opc = ICMD_DUP_X2;
3674 /* ..., ????, ????, cat1 */
3676 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3677 /* ..., cat2, ????, cat1 */
3678 #ifdef ENABLE_VERIFIER
3680 if (IS_2_WORD_TYPE(curstack->prev->type))
3681 goto throw_stack_category_error;
3684 iptr->opc = ICMD_DUP2_X1;
3688 /* ..., cat1, ????, cat1 */
3689 #ifdef ENABLE_VERIFIER
3692 if (IS_2_WORD_TYPE(curstack->prev->type)
3693 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3694 goto throw_stack_category_error;
3698 src1 = curstack->prev->prev->prev;
3699 src2 = curstack->prev->prev;
3700 src3 = curstack->prev;
3702 POPANY; POPANY; POPANY; POPANY;
3705 /* move non-temporary sources out of the way */
3706 if (!IS_TEMPVAR(src2)) {
3707 MOVE_TO_TEMP(src2); iptr++; len--;
3709 if (!IS_TEMPVAR(src3)) {
3710 MOVE_TO_TEMP(src3); iptr++; len--;
3712 if (!IS_TEMPVAR(src4)) {
3713 MOVE_TO_TEMP(src4); iptr++; len--;
3716 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3717 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3719 MOVE_UP(src1); iptr++; len--;
3720 MOVE_UP(src2); iptr++; len--;
3721 MOVE_UP(src3); iptr++; len--;
3722 MOVE_UP(src4); iptr++; len--;
3724 COPY_DOWN(curstack, dst2); iptr++; len--;
3725 COPY_DOWN(curstack->prev, dst1);
3727 coalescing_boundary = sd.new;
3731 /* pop 2 push 2 swap */
3734 #ifdef ENABLE_VERIFIER
3737 if (IS_2_WORD_TYPE(curstack->type)
3738 || IS_2_WORD_TYPE(curstack->prev->type))
3739 goto throw_stack_category_error;
3743 src1 = curstack->prev;
3748 /* move non-temporary sources out of the way */
3749 if (!IS_TEMPVAR(src1)) {
3750 MOVE_TO_TEMP(src1); iptr++; len--;
3753 MOVE_UP(src2); iptr++; len--;
3756 coalescing_boundary = sd.new;
3763 coalescing_boundary = sd.new;
3764 #if !SUPPORT_DIVISION
3765 bte = iptr->sx.s23.s3.bte;
3768 if (md->memuse > rd->memuse)
3769 rd->memuse = md->memuse;
3770 if (md->argintreguse > rd->argintreguse)
3771 rd->argintreguse = md->argintreguse;
3773 /* make all stack variables saved */
3777 sd.var[copy->varnum].flags |= SAVEDVAR;
3778 copy->flags |= SAVEDVAR;
3783 #endif /* !SUPPORT_DIVISION */
3794 COUNT(count_pcmd_op);
3795 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3800 coalescing_boundary = sd.new;
3801 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3802 bte = iptr->sx.s23.s3.bte;
3805 if (md->memuse > rd->memuse)
3806 rd->memuse = md->memuse;
3807 if (md->argintreguse > rd->argintreguse)
3808 rd->argintreguse = md->argintreguse;
3809 /* XXX non-leaf method? */
3811 /* make all stack variables saved */
3815 sd.var[copy->varnum].flags |= SAVEDVAR;
3816 copy->flags |= SAVEDVAR;
3821 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3826 #if SUPPORT_LONG_LOGICAL
3830 #endif /* SUPPORT_LONG_LOGICAL */
3831 COUNT(count_pcmd_op);
3832 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3838 COUNT(count_pcmd_op);
3839 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3847 COUNT(count_pcmd_op);
3848 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3856 COUNT(count_pcmd_op);
3857 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3861 COUNT(count_pcmd_op);
3862 #if SUPPORT_LONG_CMP_CONST
3863 if ((len == 0) || (iptr[1].sx.val.i != 0))
3866 switch (iptr[1].opc) {
3868 iptr->opc = ICMD_IF_LCMPEQ;
3870 iptr->dst.insindex = iptr[1].dst.insindex;
3871 iptr[1].opc = ICMD_NOP;
3873 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3876 COUNT(count_pcmd_bra);
3879 iptr->opc = ICMD_IF_LCMPNE;
3880 goto icmd_lcmp_if_tail;
3882 iptr->opc = ICMD_IF_LCMPLT;
3883 goto icmd_lcmp_if_tail;
3885 iptr->opc = ICMD_IF_LCMPGT;
3886 goto icmd_lcmp_if_tail;
3888 iptr->opc = ICMD_IF_LCMPLE;
3889 goto icmd_lcmp_if_tail;
3891 iptr->opc = ICMD_IF_LCMPGE;
3892 goto icmd_lcmp_if_tail;
3898 #endif /* SUPPORT_LONG_CMP_CONST */
3899 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3902 /* XXX why is this deactivated? */
3905 COUNT(count_pcmd_op);
3906 if ((len == 0) || (iptr[1].sx.val.i != 0))
3909 switch (iptr[1].opc) {
3911 iptr->opc = ICMD_IF_FCMPEQ;
3913 iptr->dst.insindex = iptr[1].dst.insindex;
3914 iptr[1].opc = ICMD_NOP;
3916 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3919 COUNT(count_pcmd_bra);
3922 iptr->opc = ICMD_IF_FCMPNE;
3923 goto icmd_if_fcmpl_tail;
3925 iptr->opc = ICMD_IF_FCMPL_LT;
3926 goto icmd_if_fcmpl_tail;
3928 iptr->opc = ICMD_IF_FCMPL_GT;
3929 goto icmd_if_fcmpl_tail;
3931 iptr->opc = ICMD_IF_FCMPL_LE;
3932 goto icmd_if_fcmpl_tail;
3934 iptr->opc = ICMD_IF_FCMPL_GE;
3935 goto icmd_if_fcmpl_tail;
3942 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3946 COUNT(count_pcmd_op);
3947 if ((len == 0) || (iptr[1].sx.val.i != 0))
3950 switch (iptr[1].opc) {
3952 iptr->opc = ICMD_IF_FCMPEQ;
3954 iptr->dst.insindex = iptr[1].dst.insindex;
3955 iptr[1].opc = ICMD_NOP;
3957 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3960 COUNT(count_pcmd_bra);
3963 iptr->opc = ICMD_IF_FCMPNE;
3964 goto icmd_if_fcmpg_tail;
3966 iptr->opc = ICMD_IF_FCMPG_LT;
3967 goto icmd_if_fcmpg_tail;
3969 iptr->opc = ICMD_IF_FCMPG_GT;
3970 goto icmd_if_fcmpg_tail;
3972 iptr->opc = ICMD_IF_FCMPG_LE;
3973 goto icmd_if_fcmpg_tail;
3975 iptr->opc = ICMD_IF_FCMPG_GE;
3976 goto icmd_if_fcmpg_tail;
3983 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3987 COUNT(count_pcmd_op);
3988 if ((len == 0) || (iptr[1].sx.val.i != 0))
3991 switch (iptr[1].opc) {
3993 iptr->opc = ICMD_IF_DCMPEQ;
3995 iptr->dst.insindex = iptr[1].dst.insindex;
3996 iptr[1].opc = ICMD_NOP;
3998 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4001 COUNT(count_pcmd_bra);
4004 iptr->opc = ICMD_IF_DCMPNE;
4005 goto icmd_if_dcmpl_tail;
4007 iptr->opc = ICMD_IF_DCMPL_LT;
4008 goto icmd_if_dcmpl_tail;
4010 iptr->opc = ICMD_IF_DCMPL_GT;
4011 goto icmd_if_dcmpl_tail;
4013 iptr->opc = ICMD_IF_DCMPL_LE;
4014 goto icmd_if_dcmpl_tail;
4016 iptr->opc = ICMD_IF_DCMPL_GE;
4017 goto icmd_if_dcmpl_tail;
4024 OPTT2_1(TYPE_DBL, TYPE_INT);
4028 COUNT(count_pcmd_op);
4029 if ((len == 0) || (iptr[1].sx.val.i != 0))
4032 switch (iptr[1].opc) {
4034 iptr->opc = ICMD_IF_DCMPEQ;
4036 iptr->dst.insindex = iptr[1].dst.insindex;
4037 iptr[1].opc = ICMD_NOP;
4039 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4042 COUNT(count_pcmd_bra);
4045 iptr->opc = ICMD_IF_DCMPNE;
4046 goto icmd_if_dcmpg_tail;
4048 iptr->opc = ICMD_IF_DCMPG_LT;
4049 goto icmd_if_dcmpg_tail;
4051 iptr->opc = ICMD_IF_DCMPG_GT;
4052 goto icmd_if_dcmpg_tail;
4054 iptr->opc = ICMD_IF_DCMPG_LE;
4055 goto icmd_if_dcmpg_tail;
4057 iptr->opc = ICMD_IF_DCMPG_GE;
4058 goto icmd_if_dcmpg_tail;
4065 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4070 COUNT(count_pcmd_op);
4071 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4076 COUNT(count_pcmd_op);
4077 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4086 case ICMD_INT2SHORT:
4087 COUNT(count_pcmd_op);
4088 OP1_1(TYPE_INT, TYPE_INT);
4091 COUNT(count_pcmd_op);
4092 OP1_1(TYPE_LNG, TYPE_LNG);
4095 COUNT(count_pcmd_op);
4096 OP1_1(TYPE_FLT, TYPE_FLT);
4099 COUNT(count_pcmd_op);
4100 OP1_1(TYPE_DBL, TYPE_DBL);
4104 COUNT(count_pcmd_op);
4105 OP1_1(TYPE_INT, TYPE_LNG);
4108 COUNT(count_pcmd_op);
4109 OP1_1(TYPE_INT, TYPE_FLT);
4112 COUNT(count_pcmd_op);
4113 OP1_1(TYPE_INT, TYPE_DBL);
4116 COUNT(count_pcmd_op);
4117 OP1_1(TYPE_LNG, TYPE_INT);
4120 COUNT(count_pcmd_op);
4121 OP1_1(TYPE_LNG, TYPE_FLT);
4124 COUNT(count_pcmd_op);
4125 OP1_1(TYPE_LNG, TYPE_DBL);
4128 COUNT(count_pcmd_op);
4129 OP1_1(TYPE_FLT, TYPE_INT);
4132 COUNT(count_pcmd_op);
4133 OP1_1(TYPE_FLT, TYPE_LNG);
4136 COUNT(count_pcmd_op);
4137 OP1_1(TYPE_FLT, TYPE_DBL);
4140 COUNT(count_pcmd_op);
4141 OP1_1(TYPE_DBL, TYPE_INT);
4144 COUNT(count_pcmd_op);
4145 OP1_1(TYPE_DBL, TYPE_LNG);
4148 COUNT(count_pcmd_op);
4149 OP1_1(TYPE_DBL, TYPE_FLT);
4152 case ICMD_CHECKCAST:
4153 coalescing_boundary = sd.new;
4154 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4155 /* array type cast-check */
4157 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4160 if (md->memuse > rd->memuse)
4161 rd->memuse = md->memuse;
4162 if (md->argintreguse > rd->argintreguse)
4163 rd->argintreguse = md->argintreguse;
4165 /* make all stack variables saved */
4169 sd.var[copy->varnum].flags |= SAVEDVAR;
4170 copy->flags |= SAVEDVAR;
4174 OP1_1(TYPE_ADR, TYPE_ADR);
4177 case ICMD_INSTANCEOF:
4178 case ICMD_ARRAYLENGTH:
4179 coalescing_boundary = sd.new;
4180 OP1_1(TYPE_ADR, TYPE_INT);
4184 case ICMD_ANEWARRAY:
4185 coalescing_boundary = sd.new;
4186 OP1_1(TYPE_INT, TYPE_ADR);
4190 coalescing_boundary = sd.new;
4191 COUNT(count_check_null);
4192 COUNT(count_pcmd_mem);
4193 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4194 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4199 case ICMD_GETSTATIC:
4200 coalescing_boundary = sd.new;
4201 COUNT(count_pcmd_mem);
4202 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4203 OP0_1(fmiref->parseddesc.fd->type);
4207 coalescing_boundary = sd.new;
4214 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4215 tbptr->type = BBTYPE_SBR;
4217 assert(sd.bptr->next); /* XXX exception */
4218 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4219 #if defined(ENABLE_VERIFIER)
4220 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4223 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4227 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4229 /* We need to check for overflow right here because
4230 * the pushed value is poped afterwards */
4233 superblockend = true;
4234 /* XXX should not be marked as interface, as it does not need to be */
4235 /* allocated. Same for the invar of the target. */
4238 /* pop many push any */
4242 bte = iptr->sx.s23.s3.bte;
4246 case ICMD_INVOKESTATIC:
4247 case ICMD_INVOKESPECIAL:
4248 case ICMD_INVOKEVIRTUAL:
4249 case ICMD_INVOKEINTERFACE:
4250 COUNT(count_pcmd_met);
4252 /* Check for functions to replace with builtin
4255 if (builtintable_replace_function(iptr))
4258 INSTRUCTION_GET_METHODDESC(iptr, md);
4259 /* XXX resurrect this COUNT? */
4260 /* if (lm->flags & ACC_STATIC) */
4261 /* {COUNT(count_check_null);} */
4265 coalescing_boundary = sd.new;
4269 if (md->memuse > rd->memuse)
4270 rd->memuse = md->memuse;
4271 if (md->argintreguse > rd->argintreguse)
4272 rd->argintreguse = md->argintreguse;
4273 if (md->argfltreguse > rd->argfltreguse)
4274 rd->argfltreguse = md->argfltreguse;
4278 iptr->s1.argcount = stackdepth;
4279 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4282 for (i-- ; i >= 0; i--) {
4283 iptr->sx.s23.s2.args[i] = copy->varnum;
4285 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4286 /* -> won't help anyway */
4287 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4289 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4290 /* If we pass float arguments in integer argument registers, we
4291 * are not allowed to precolor them here. Floats have to be moved
4292 * to this regs explicitly in codegen().
4293 * Only arguments that are passed by stack anyway can be precolored
4294 * (michi 2005/07/24) */
4295 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4296 (!IS_FLT_DBL_TYPE(copy->type)
4297 || md->params[i].inmemory)) {
4299 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4304 if (md->params[i].inmemory) {
4305 sd.var[copy->varnum].vv.regoff =
4306 md->params[i].regoff;
4307 sd.var[copy->varnum].flags |=
4311 if (IS_FLT_DBL_TYPE(copy->type)) {
4312 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4313 assert(0); /* XXX is this assert ok? */
4315 sd.var[copy->varnum].vv.regoff =
4316 rd->argfltregs[md->params[i].regoff];
4317 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4320 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4321 if (IS_2_WORD_TYPE(copy->type))
4322 sd.var[copy->varnum].vv.regoff =
4323 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4324 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4327 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4328 sd.var[copy->varnum].vv.regoff =
4329 rd->argintregs[md->params[i].regoff];
4337 /* deal with live-through stack slots "under" the */
4343 iptr->sx.s23.s2.args[i++] = copy->varnum;
4344 sd.var[copy->varnum].flags |= SAVEDVAR;
4345 copy->flags |= SAVEDVAR | PASSTHROUGH;
4349 /* pop the arguments */
4358 /* push the return value */
4360 if (md->returntype.type != TYPE_VOID) {
4361 GET_NEW_VAR(sd, new_index, md->returntype.type);
4362 DST(md->returntype.type, new_index);
4367 case ICMD_INLINE_START:
4368 case ICMD_INLINE_END:
4373 case ICMD_MULTIANEWARRAY:
4374 coalescing_boundary = sd.new;
4375 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4376 rd->argintreguse = MIN(3, INT_ARG_CNT);
4378 i = iptr->s1.argcount;
4382 iptr->sx.s23.s2.args = DMNEW(s4, i);
4384 #if defined(SPECIALMEMUSE)
4385 # if defined(__DARWIN__)
4386 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4387 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4389 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4390 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4393 # if defined(__I386__)
4394 if (rd->memuse < i + 3)
4395 rd->memuse = i + 3; /* n integer args spilled on stack */
4396 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4397 if (rd->memuse < i + 2)
4398 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4401 rd->memuse = i; /* n integer args spilled on stack */
4402 # endif /* defined(__I386__) */
4406 /* check INT type here? Currently typecheck does this. */
4407 iptr->sx.s23.s2.args[i] = copy->varnum;
4408 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4409 && (!IS_INOUT(copy))
4410 && (!IS_LOCALVAR(copy)) ) {
4411 copy->varkind = ARGVAR;
4412 sd.var[copy->varnum].flags |=
4413 INMEMORY & PREALLOC;
4414 #if defined(SPECIALMEMUSE)
4415 # if defined(__DARWIN__)
4416 sd.var[copy->varnum].vv.regoff = i +
4417 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4419 sd.var[copy->varnum].vv.regoff = i +
4420 LA_SIZE_IN_POINTERS + 3;
4423 # if defined(__I386__)
4424 sd.var[copy->varnum].vv.regoff = i + 3;
4425 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4426 sd.var[copy->varnum].vv.regoff = i + 2;
4428 sd.var[copy->varnum].vv.regoff = i;
4429 # endif /* defined(__I386__) */
4430 #endif /* defined(SPECIALMEMUSE) */
4435 sd.var[copy->varnum].flags |= SAVEDVAR;
4436 copy->flags |= SAVEDVAR;
4440 i = iptr->s1.argcount;
4445 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4446 DST(TYPE_ADR, new_index);
4452 new_internalerror("Unknown ICMD %d", opcode);
4458 } /* while instructions */
4460 /* stack slots at basic block end become interfaces */
4462 sd.bptr->outdepth = stackdepth;
4463 sd.bptr->outvars = DMNEW(s4, stackdepth);
4466 for (copy = curstack; copy; i--, copy = copy->prev) {
4470 /* with the new vars rd->interfaces will be removed */
4471 /* and all in and outvars have to be STACKVARS! */
4472 /* in the moment i.e. SWAP with in and out vars can */
4473 /* create an unresolvable conflict */
4480 v = sd.var + copy->varnum;
4483 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4484 /* no interface var until now for this depth and */
4486 jd->interface_map[i*5 + t].flags = v->flags;
4489 jd->interface_map[i*5 + t].flags |= v->flags;
4492 sd.bptr->outvars[i] = copy->varnum;
4495 /* check if interface slots at basic block begin must be saved */
4497 for (i=0; i<sd.bptr->indepth; ++i) {
4498 varinfo *v = sd.var + sd.bptr->invars[i];
4505 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4506 /* no interface var until now for this depth and */
4508 jd->interface_map[i*5 + t].flags = v->flags;
4511 jd->interface_map[i*5 + t].flags |= v->flags;
4515 /* store the number of this block's variables */
4517 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4519 #if defined(STACK_VERBOSE)
4520 stack_verbose_block_exit(&sd, superblockend);
4523 /* reach the following block, if any */
4526 if (!stack_reach_next_block(&sd))
4531 } while (sd.repeat && !deadcode);
4533 /* XXX reset TYPE_RET to TYPE_ADR */
4535 for (i=0; i<sd.vartop; ++i) {
4536 if (sd.var[i].type == TYPE_RET)
4537 sd.var[i].type = TYPE_ADR;
4540 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4542 ex = cd->exceptiontable;
4543 for (; ex != NULL; ex = ex->down) {
4544 if (ex->start == ex->end) {
4545 assert(ex->end->next);
4546 ex->end = ex->end->next;
4550 /* gather statistics *****************************************************/
4552 #if defined(ENABLE_STATISTICS)
4554 if (jd->basicblockcount > count_max_basic_blocks)
4555 count_max_basic_blocks = jd->basicblockcount;
4556 count_basic_blocks += jd->basicblockcount;
4557 if (jd->instructioncount > count_max_javainstr)
4558 count_max_javainstr = jd->instructioncount;
4559 count_javainstr += jd->instructioncount;
4560 if (jd->stackcount > count_upper_bound_new_stack)
4561 count_upper_bound_new_stack = jd->stackcount;
4562 if ((sd.new - jd->stack) > count_max_new_stack)
4563 count_max_new_stack = (sd.new - jd->stack);
4565 sd.bptr = jd->basicblocks;
4566 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4567 if (sd.bptr->flags > BBREACHED) {
4568 if (sd.bptr->indepth >= 10)
4569 count_block_stack[10]++;
4571 count_block_stack[sd.bptr->indepth]++;
4572 len = sd.bptr->icount;
4574 count_block_size_distribution[len]++;
4576 count_block_size_distribution[10]++;
4578 count_block_size_distribution[11]++;
4580 count_block_size_distribution[12]++;
4582 count_block_size_distribution[13]++;
4584 count_block_size_distribution[14]++;
4586 count_block_size_distribution[15]++;
4588 count_block_size_distribution[16]++;
4590 count_block_size_distribution[17]++;
4594 if (iteration_count == 1)
4595 count_analyse_iterations[0]++;
4596 else if (iteration_count == 2)
4597 count_analyse_iterations[1]++;
4598 else if (iteration_count == 3)
4599 count_analyse_iterations[2]++;
4600 else if (iteration_count == 4)
4601 count_analyse_iterations[3]++;
4603 count_analyse_iterations[4]++;
4605 if (jd->basicblockcount <= 5)
4606 count_method_bb_distribution[0]++;
4607 else if (jd->basicblockcount <= 10)
4608 count_method_bb_distribution[1]++;
4609 else if (jd->basicblockcount <= 15)
4610 count_method_bb_distribution[2]++;
4611 else if (jd->basicblockcount <= 20)
4612 count_method_bb_distribution[3]++;
4613 else if (jd->basicblockcount <= 30)
4614 count_method_bb_distribution[4]++;
4615 else if (jd->basicblockcount <= 40)
4616 count_method_bb_distribution[5]++;
4617 else if (jd->basicblockcount <= 50)
4618 count_method_bb_distribution[6]++;
4619 else if (jd->basicblockcount <= 75)
4620 count_method_bb_distribution[7]++;
4622 count_method_bb_distribution[8]++;
4624 #endif /* defined(ENABLE_STATISTICS) */
4626 /* everything's ok *******************************************************/
4630 /* goto labels for throwing verifier exceptions **************************/
4632 #if defined(ENABLE_VERIFIER)
4634 throw_stack_underflow:
4635 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4638 throw_stack_overflow:
4639 exceptions_throw_verifyerror(m, "Stack size too large");
4642 throw_stack_type_error:
4643 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4646 throw_stack_category_error:
4647 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4654 /* functions for verbose stack analysis output ********************************/
4656 #if defined(STACK_VERBOSE)
4657 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4659 printf("%c", show_jit_type_letters[v->type]);
4660 if (v->type == TYPE_RET)
4661 printf("{L%03d}", v->vv.retaddr->nr);
4665 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4667 assert(index >= 0 && index < sd->vartop);
4668 stack_verbose_show_varinfo(sd, sd->var + index);
4672 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4676 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4678 for (i=0; i<bptr->indepth; ++i) {
4681 stack_verbose_show_variable(sd, bptr->invars[i]);
4686 printf("] inlocals [");
4687 if (bptr->inlocals) {
4688 for (i=0; i<sd->localcount; ++i) {
4691 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4696 printf("] out:%d [", bptr->outdepth);
4697 if (bptr->outvars) {
4698 for (i=0; i<bptr->outdepth; ++i) {
4701 stack_verbose_show_variable(sd, bptr->outvars[i]);
4709 printf(" (clone of L%03d)", bptr->original->nr);
4711 basicblock *b = bptr->copied_to;
4713 printf(" (copied to ");
4714 for (; b; b = b->copied_to)
4715 printf("L%03d ", b->nr);
4722 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4726 printf("======================================== STACK %sANALYSE BLOCK ",
4727 (reanalyse) ? "RE-" : "");
4728 stack_verbose_show_block(sd, sd->bptr);
4731 if (sd->handlers[0]) {
4732 printf("HANDLERS: ");
4733 for (i=0; sd->handlers[i]; ++i) {
4734 printf("L%03d ", sd->handlers[i]->handler->nr);
4742 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4744 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4745 stack_verbose_show_block(sd, sd->bptr);
4752 * These are local overrides for various environment variables in Emacs.
4753 * Please do not remove this and leave it at the end of the file, where
4754 * Emacs will automagically detect them.
4755 * ---------------------------------------------------------------------
4758 * indent-tabs-mode: t
4762 * vim:noexpandtab:sw=4:ts=4: