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 5762 2006-10-13 10:33:20Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/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 if (b->flags >= BBFINISHED)
846 b->flags = BBTYPECHECK_REACHED;
847 sd->repeat = true; /* This is very rare, so just repeat */
853 #if defined(STACK_VERBOSE)
854 printf("------> using L%03d\n", b->nr);
858 } while ((b = b->copied_to) != NULL);
860 b = stack_clone_block(sd, orig);
864 stack_create_invars(sd, b, curstack, stackdepth);
869 /* stack_check_invars_from_outvars *********************************************
871 Check the outvars of the current block against the invars of the given block.
872 Depth and types must match.
875 sd...........stack analysis data
876 b............block which invars to check against
880 NULL.........a VerifyError has been thrown
882 *******************************************************************************/
884 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
892 #if defined(STACK_VERBOSE)
893 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
896 /* find original of b */
901 #if defined(STACK_VERBOSE)
902 printf("original is L%03d\n", orig->nr);
906 n = sd->bptr->outdepth;
908 #if defined(ENABLE_VERIFIER)
910 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
918 #if defined(STACK_VERBOSE)
919 printf("checking against ");
920 stack_verbose_show_block(sd, b); printf("\n");
924 dv = sd->var + b->invars[0];
926 for (i=0; i<n; ++i, ++dv) {
927 sv = sd->var + sd->bptr->outvars[i];
929 #if defined(ENABLE_VERIFIER)
930 if (sv->type != dv->type) {
931 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
936 if (dv->type == TYPE_RET) {
937 #if defined(ENABLE_VERIFIER)
938 if (sv->SBRSTART != dv->SBRSTART) {
939 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
943 if (sv->vv.retaddr != dv->vv.retaddr) {
945 /* don't break! have to check the remaining stackslots */
952 for (i=0; i<sd->localcount; ++i) {
953 dv = b->inlocals + i;
956 #if defined(ENABLE_VERIFIER)
957 (sv->SBRSTART == dv->SBRSTART) &&
959 (sv->type == TYPE_RET && dv->type == TYPE_RET))
961 if (sv->vv.retaddr != dv->vv.retaddr) {
970 /* XXX mark mixed type variables void */
971 /* XXX cascading collapse? */
972 #if defined(ENABLE_VERIFIER)
974 for (i=0; i<sd->localcount; ++i) {
975 dv = b->inlocals + i;
977 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
978 && (sv->SBRSTART != dv->SBRSTART))
980 dv->type = TYPE_VOID;
981 if (b->flags >= BBFINISHED)
982 b->flags = BBTYPECHECK_REACHED;
983 sd->repeat = true; /* This is very rare, so just repeat */
989 #if defined(STACK_VERBOSE)
990 printf("------> using L%03d\n", b->nr);
994 } while ((b = b->copied_to) != NULL);
996 b = stack_clone_block(sd, orig);
1000 stack_create_invars_from_outvars(sd, b);
1005 /* stack_create_instack ********************************************************
1007 Create the instack of the current basic block.
1010 sd...........stack analysis data
1013 the current stack top at the start of the basic block.
1015 *******************************************************************************/
1017 static stackptr stack_create_instack(stackdata_t *sd)
1023 if ((depth = sd->bptr->indepth) == 0)
1026 sp = (sd->new += depth);
1030 index = sd->bptr->invars[depth];
1032 sp->type = sd->var[index].type;
1036 sp->varkind = STACKVAR;
1040 /* return the top of the created stack */
1045 /* stack_mark_reached **********************************************************
1047 Mark the given block reached and propagate the current stack and locals to
1048 it. This function specializes the target block, if necessary, and returns
1049 a pointer to the specialized target.
1052 sd...........stack analysis data
1053 b............the block to reach
1054 curstack.....the current stack top
1055 stackdepth...the current stack depth
1058 a pointer to (a specialized version of) the target
1059 NULL.........a VerifyError has been thrown
1061 *******************************************************************************/
1063 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1065 #if defined(STACK_VERBOSE)
1066 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1068 /* mark targets of backward branches */
1070 b->bitflags |= BBFLAG_REPLACEMENT;
1072 if (b->flags < BBREACHED) {
1073 /* b is reached for the first time. Create its invars. */
1075 #if defined(STACK_VERBOSE)
1076 printf("reached L%03d for the first time\n", b->nr);
1079 stack_create_invars(sd, b, curstack, stackdepth);
1081 b->flags = BBREACHED;
1086 /* b has been reached before. Check that its invars match. */
1088 return stack_check_invars(sd, b, curstack, stackdepth);
1093 /* stack_mark_reached_from_outvars *********************************************
1095 Mark the given block reached and propagate the outvars of the current block
1096 and the current locals to it. This function specializes the target block,
1097 if necessary, and returns a pointer to the specialized target.
1100 sd...........stack analysis data
1101 b............the block to reach
1104 a pointer to (a specialized version of) the target
1105 NULL.........a VerifyError has been thrown
1107 *******************************************************************************/
1109 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1111 #if defined(STACK_VERBOSE)
1112 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1114 /* mark targets of backward branches */
1116 b->bitflags |= BBFLAG_REPLACEMENT;
1118 if (b->flags < BBREACHED) {
1119 /* b is reached for the first time. Create its invars. */
1121 #if defined(STACK_VERBOSE)
1122 printf("reached L%03d for the first time\n", b->nr);
1125 stack_create_invars_from_outvars(sd, b);
1127 b->flags = BBREACHED;
1132 /* b has been reached before. Check that its invars match. */
1134 return stack_check_invars_from_outvars(sd, b);
1139 /* stack_reach_next_block ******************************************************
1141 Mark the following block reached and propagate the outvars of the current block
1142 and the current locals to it. This function specializes the target block,
1143 if necessary, and returns a pointer to the specialized target.
1146 sd...........stack analysis data
1149 a pointer to (a specialized version of) the following block
1150 NULL.........a VerifyError has been thrown
1152 *******************************************************************************/
1154 static bool stack_reach_next_block(stackdata_t *sd)
1159 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1160 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1164 if (tbptr != sd->bptr->next) {
1165 #if defined(STACK_VERBOSE)
1166 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1168 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1169 assert(iptr->opc == ICMD_NOP);
1170 iptr->opc = ICMD_GOTO;
1171 iptr->dst.block = tbptr;
1173 if (tbptr->flags < BBFINISHED)
1174 sd->repeat = true; /* XXX check if we really need to repeat */
1181 /* stack_reach_handlers ********************************************************
1183 Reach the exception handlers for the current block.
1186 sd...........stack analysis data
1189 true.........everything ok
1190 false........a VerifyError has been thrown
1192 *******************************************************************************/
1194 static bool stack_reach_handlers(stackdata_t *sd)
1199 #if defined(STACK_VERBOSE)
1200 printf("reaching exception handlers...\n");
1203 for (i=0; sd->handlers[i]; ++i) {
1204 tbptr = sd->handlers[i]->handler;
1206 tbptr->type = BBTYPE_EXH;
1207 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1209 /* reach (and specialize) the handler block */
1211 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1216 sd->handlers[i]->handler = tbptr;
1223 /* stack_reanalyse_block ******************************************************
1225 Re-analyse the current block. This is called if either the block itself
1226 has already been analysed before, or the current block is a clone of an
1227 already analysed block, and this clone is reached for the first time.
1228 In the latter case, this function does all that is necessary for fully
1229 cloning the block (cloning the instruction list and variables, etc.).
1232 sd...........stack analysis data
1235 true.........everything ok
1236 false........a VerifyError has been thrown
1238 *******************************************************************************/
1240 #define RELOCATE(index) \
1242 if ((index) >= blockvarstart) \
1243 (index) += blockvarshift; \
1244 else if ((index) >= invarstart) \
1245 (index) += invarshift; \
1248 bool stack_reanalyse_block(stackdata_t *sd)
1260 branch_target_t *table;
1261 lookup_target_t *lookup;
1264 bool cloneinstructions;
1267 #if defined(STACK_VERBOSE)
1268 stack_verbose_block_enter(sd, true);
1275 assert(orig != NULL);
1277 /* clone the instruction list */
1279 cloneinstructions = true;
1281 assert(orig->iinstr);
1283 iptr = DMNEW(instruction, len + 1);
1285 MCOPY(iptr, orig->iinstr, instruction, len);
1286 iptr[len].opc = ICMD_NOP;
1290 /* allocate space for the clone's block variables */
1292 stack_grow_variable_array(sd, orig->varcount);
1294 /* we already have the invars set */
1296 assert(b->indepth == orig->indepth);
1298 /* calculate relocation shifts for invars and block variables */
1300 if (orig->indepth) {
1301 invarstart = orig->invars[0];
1302 invarshift = b->invars[0] - invarstart;
1305 invarstart = INT_MAX;
1308 blockvarstart = orig->varstart;
1309 blockvarshift = sd->vartop - blockvarstart;
1311 /* copy block variables */
1313 b->varstart = sd->vartop;
1314 b->varcount = orig->varcount;
1315 sd->vartop += b->varcount;
1316 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1320 b->outdepth = orig->outdepth;
1321 b->outvars = DMNEW(s4, orig->outdepth);
1322 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1324 /* clone exception handlers */
1326 for (i=0; sd->handlers[i]; ++i) {
1327 ex = DNEW(exceptiontable);
1328 ex->handler = sd->handlers[i]->handler;
1330 ex->end = b; /* XXX hack, see end of stack_analyse */
1331 ex->catchtype = sd->handlers[i]->catchtype;
1334 assert(sd->extableend->down == NULL);
1335 sd->extableend->down = ex;
1336 sd->extableend = ex;
1337 sd->jd->cd->exceptiontablelength++;
1339 sd->handlers[i] = ex;
1343 cloneinstructions = false;
1346 invarstart = sd->vartop;
1347 blockvarstart = sd->vartop;
1352 /* find exception handlers for the cloned block */
1354 ex = sd->jd->cd->exceptiontable;
1355 for (; ex != NULL; ex = ex->down) {
1356 /* XXX the cloned exception handlers have identical */
1357 /* start end end blocks. */
1358 if ((ex->start == b) && (ex->end == b)) {
1359 sd->handlers[len++] = ex;
1362 sd->handlers[len] = NULL;
1365 #if defined(STACK_VERBOSE)
1366 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1367 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1370 /* mark block as finished */
1372 b->flags = BBFINISHED;
1374 /* initialize locals at the start of this block */
1377 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1379 /* reach exception handlers for this block */
1381 if (!stack_reach_handlers(sd))
1384 superblockend = false;
1386 for (len = b->icount; len--; iptr++) {
1387 #if defined(STACK_VERBOSE)
1388 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1394 switch (iptr->opc) {
1396 j = iptr->s1.varindex;
1398 #if defined(ENABLE_VERIFIER)
1399 if (sd->var[j].type != TYPE_RET) {
1400 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1405 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1406 superblockend = true;
1410 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1411 superblockend = true;
1415 superblockend = true;
1418 case ICMD_CHECKNULL:
1419 case ICMD_PUTSTATICCONST:
1425 case ICMD_INLINE_START:
1426 case ICMD_INLINE_END:
1427 case ICMD_INLINE_GOTO:
1431 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1432 superblockend = true;
1435 /* pop 0 push 1 const */
1444 /* pop 0 push 1 load */
1451 RELOCATE(iptr->dst.varindex);
1464 RELOCATE(iptr->sx.s23.s2.varindex);
1465 RELOCATE(iptr->s1.varindex);
1466 RELOCATE(iptr->dst.varindex);
1480 RELOCATE(iptr->sx.s23.s3.varindex);
1481 RELOCATE(iptr->sx.s23.s2.varindex);
1482 RELOCATE(iptr->s1.varindex);
1486 /* pop 1 push 0 store */
1493 RELOCATE(iptr->s1.varindex);
1495 j = iptr->dst.varindex;
1496 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1508 RELOCATE(iptr->s1.varindex);
1509 superblockend = true;
1512 case ICMD_PUTSTATIC:
1513 case ICMD_PUTFIELDCONST:
1516 RELOCATE(iptr->s1.varindex);
1519 /* pop 1 push 0 branch */
1522 case ICMD_IFNONNULL:
1537 RELOCATE(iptr->s1.varindex);
1538 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1541 /* pop 1 push 0 table branch */
1543 case ICMD_TABLESWITCH:
1544 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1546 if (cloneinstructions) {
1547 table = DMNEW(branch_target_t, i);
1548 MCOPY(table, iptr->dst.table, branch_target_t, i);
1549 iptr->dst.table = table;
1552 table = iptr->dst.table;
1555 RELOCATE(iptr->s1.varindex);
1557 table->block = stack_mark_reached_from_outvars(sd, table->block);
1560 superblockend = true;
1563 case ICMD_LOOKUPSWITCH:
1564 i = iptr->sx.s23.s2.lookupcount;
1565 if (cloneinstructions) {
1566 lookup = DMNEW(lookup_target_t, i);
1567 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1568 iptr->dst.lookup = lookup;
1571 lookup = iptr->dst.lookup;
1573 RELOCATE(iptr->s1.varindex);
1575 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1578 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1579 superblockend = true;
1582 case ICMD_MONITORENTER:
1583 case ICMD_MONITOREXIT:
1584 RELOCATE(iptr->s1.varindex);
1588 /* pop 2 push 0 branch */
1590 case ICMD_IF_ICMPEQ:
1591 case ICMD_IF_ICMPNE:
1592 case ICMD_IF_ICMPLT:
1593 case ICMD_IF_ICMPGE:
1594 case ICMD_IF_ICMPGT:
1595 case ICMD_IF_ICMPLE:
1597 case ICMD_IF_LCMPEQ:
1598 case ICMD_IF_LCMPNE:
1599 case ICMD_IF_LCMPLT:
1600 case ICMD_IF_LCMPGE:
1601 case ICMD_IF_LCMPGT:
1602 case ICMD_IF_LCMPLE:
1604 case ICMD_IF_FCMPEQ:
1605 case ICMD_IF_FCMPNE:
1607 case ICMD_IF_FCMPL_LT:
1608 case ICMD_IF_FCMPL_GE:
1609 case ICMD_IF_FCMPL_GT:
1610 case ICMD_IF_FCMPL_LE:
1612 case ICMD_IF_FCMPG_LT:
1613 case ICMD_IF_FCMPG_GE:
1614 case ICMD_IF_FCMPG_GT:
1615 case ICMD_IF_FCMPG_LE:
1617 case ICMD_IF_DCMPEQ:
1618 case ICMD_IF_DCMPNE:
1620 case ICMD_IF_DCMPL_LT:
1621 case ICMD_IF_DCMPL_GE:
1622 case ICMD_IF_DCMPL_GT:
1623 case ICMD_IF_DCMPL_LE:
1625 case ICMD_IF_DCMPG_LT:
1626 case ICMD_IF_DCMPG_GE:
1627 case ICMD_IF_DCMPG_GT:
1628 case ICMD_IF_DCMPG_LE:
1630 case ICMD_IF_ACMPEQ:
1631 case ICMD_IF_ACMPNE:
1632 RELOCATE(iptr->sx.s23.s2.varindex);
1633 RELOCATE(iptr->s1.varindex);
1634 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1640 case ICMD_IASTORECONST:
1641 case ICMD_LASTORECONST:
1642 case ICMD_AASTORECONST:
1643 case ICMD_BASTORECONST:
1644 case ICMD_CASTORECONST:
1645 case ICMD_SASTORECONST:
1648 RELOCATE(iptr->sx.s23.s2.varindex);
1649 RELOCATE(iptr->s1.varindex);
1652 /* pop 0 push 1 copy */
1656 RELOCATE(iptr->dst.varindex);
1657 RELOCATE(iptr->s1.varindex);
1658 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1701 RELOCATE(iptr->sx.s23.s2.varindex);
1702 RELOCATE(iptr->s1.varindex);
1703 RELOCATE(iptr->dst.varindex);
1708 case ICMD_CHECKCAST:
1709 case ICMD_ARRAYLENGTH:
1710 case ICMD_INSTANCEOF:
1712 case ICMD_ANEWARRAY:
1715 case ICMD_IADDCONST:
1716 case ICMD_ISUBCONST:
1717 case ICMD_IMULCONST:
1721 case ICMD_IANDCONST:
1723 case ICMD_IXORCONST:
1724 case ICMD_ISHLCONST:
1725 case ICMD_ISHRCONST:
1726 case ICMD_IUSHRCONST:
1727 case ICMD_LADDCONST:
1728 case ICMD_LSUBCONST:
1729 case ICMD_LMULCONST:
1733 case ICMD_LANDCONST:
1735 case ICMD_LXORCONST:
1736 case ICMD_LSHLCONST:
1737 case ICMD_LSHRCONST:
1738 case ICMD_LUSHRCONST:
1742 case ICMD_INT2SHORT:
1758 RELOCATE(iptr->s1.varindex);
1759 RELOCATE(iptr->dst.varindex);
1764 case ICMD_GETSTATIC:
1767 RELOCATE(iptr->dst.varindex);
1770 /* pop many push any */
1772 case ICMD_INVOKESTATIC:
1773 case ICMD_INVOKESPECIAL:
1774 case ICMD_INVOKEVIRTUAL:
1775 case ICMD_INVOKEINTERFACE:
1777 case ICMD_MULTIANEWARRAY:
1778 i = iptr->s1.argcount;
1779 if (cloneinstructions) {
1780 argp = DMNEW(s4, i);
1781 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1782 iptr->sx.s23.s2.args = argp;
1785 argp = iptr->sx.s23.s2.args;
1793 RELOCATE(iptr->dst.varindex);
1798 new_internalerror("Unknown ICMD %d during stack re-analysis",
1803 #if defined(STACK_VERBOSE)
1804 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1809 /* relocate outvars */
1811 for (i=0; i<b->outdepth; ++i) {
1812 RELOCATE(b->outvars[i]);
1815 #if defined(STACK_VERBOSE)
1816 stack_verbose_block_exit(sd, superblockend);
1819 /* propagate to the next block */
1822 if (!stack_reach_next_block(sd))
1829 /* stack_change_to_tempvar *****************************************************
1831 Change the given stackslot to a TEMPVAR. This includes creating a new
1832 temporary variable and changing the dst.varindex of the creator of the
1833 stacklot to the new variable index. If this stackslot has been passed
1834 through ICMDs between the point of its creation and the current point,
1835 then the variable index is also changed in these ICMDs.
1838 sd...........stack analysis data
1839 sp...........stackslot to change
1840 ilimit.......instruction up to which to look for ICMDs passing-through
1841 the stackslot (exclusive). This may point exactly after the
1842 last instruction, in which case the search is done to the
1845 *******************************************************************************/
1847 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1848 instruction *ilimit)
1855 oldindex = sp->varnum;
1857 /* create a new temporary variable */
1859 GET_NEW_VAR(*sd, newindex, sp->type);
1861 sd->var[newindex].flags = sp->flags;
1863 /* change the stackslot */
1865 sp->varnum = newindex;
1866 sp->varkind = TEMPVAR;
1868 /* change the dst.varindex of the stackslot's creator */
1871 sp->creator->dst.varindex = newindex;
1873 /* handle ICMDs this stackslot passed through, if any */
1875 if (sp->flags & PASSTHROUGH) {
1876 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1878 /* asser that the limit point to an ICMD, or after the last one */
1879 assert(ilimit >= sd->bptr->iinstr);
1880 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1882 for (; iptr < ilimit; ++iptr) {
1883 switch (iptr->opc) {
1884 case ICMD_INVOKESTATIC:
1885 case ICMD_INVOKESPECIAL:
1886 case ICMD_INVOKEVIRTUAL:
1887 case ICMD_INVOKEINTERFACE:
1890 for (i=0; i<iptr->s1.argcount; ++i)
1891 if (iptr->sx.s23.s2.args[i] == oldindex) {
1892 iptr->sx.s23.s2.args[i] = newindex;
1895 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1896 /* stackslot, it must be added in this switch! */
1903 /* stack_analyse ***************************************************************
1905 Analyse_stack uses the intermediate code created by parse.c to
1906 build a model of the JVM operand stack for the current method.
1908 The following checks are performed:
1909 - check for operand stack underflow (before each instruction)
1910 - check for operand stack overflow (after[1] each instruction)
1911 - check for matching stack depth at merging points
1912 - check for matching basic types[2] at merging points
1913 - check basic types for instruction input (except for BUILTIN*
1914 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1916 [1]) Checking this after the instruction should be ok. parse.c
1917 counts the number of required stack slots in such a way that it is
1918 only vital that we don't exceed `maxstack` at basic block
1921 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1922 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1923 types are not discerned.
1925 *******************************************************************************/
1927 bool stack_analyse(jitdata *jd)
1929 methodinfo *m; /* method being analyzed */
1934 #if defined(ENABLE_SSA)
1937 int b_index; /* basic block index */
1939 stackptr curstack; /* current stack top */
1941 int opcode; /* opcode of current instruction */
1944 int len; /* # of instructions after the current one */
1945 bool superblockend; /* if true, no fallthrough to next block */
1946 bool deadcode; /* true if no live code has been reached */
1947 instruction *iptr; /* the current instruction */
1949 basicblock *original;
1952 stackptr *last_store_boundary;
1953 stackptr coalescing_boundary;
1955 stackptr src1, src2, src3, src4, dst1, dst2;
1957 branch_target_t *table;
1958 lookup_target_t *lookup;
1959 #if defined(ENABLE_VERIFIER)
1960 int expectedtype; /* used by CHECK_BASIC_TYPE */
1962 builtintable_entry *bte;
1964 constant_FMIref *fmiref;
1965 #if defined(ENABLE_STATISTICS)
1966 int iteration_count; /* number of iterations of analysis */
1968 int new_index; /* used to get a new var index with GET_NEW_INDEX*/
1970 #if defined(STACK_VERBOSE)
1971 show_method(jd, SHOW_PARSE);
1974 /* get required compiler data - initialization */
1980 #if defined(ENABLE_SSA)
1984 /* initialize the stackdata_t struct */
1988 sd.varcount = jd->varcount;
1989 sd.vartop = jd->vartop;
1990 sd.localcount = jd->localcount;
1992 sd.handlers = DMNEW(exceptiontable *, cd->exceptiontablelength + 1);
1994 /* prepare the variable for exception handler stacks */
1995 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
1997 sd.exstack.type = TYPE_ADR;
1998 sd.exstack.prev = NULL;
1999 sd.exstack.varnum = sd.localcount;
2000 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2002 #if defined(ENABLE_LSRA)
2003 m->maxlifetimes = 0;
2006 #if defined(ENABLE_STATISTICS)
2007 iteration_count = 0;
2010 /* find the last real basic block */
2012 sd.last_real_block = NULL;
2013 tbptr = jd->basicblocks;
2014 while (tbptr->next) {
2015 sd.last_real_block = tbptr;
2016 tbptr = tbptr->next;
2018 assert(sd.last_real_block);
2020 /* find the last exception handler */
2022 if (cd->exceptiontablelength)
2023 sd.extableend = cd->exceptiontable + cd->exceptiontablelength - 1;
2025 sd.extableend = NULL;
2027 /* init jd->interface_map */
2029 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2030 for (i = 0; i < m->maxstack * 5; i++)
2031 jd->interface_map[i].flags = UNUSED;
2033 last_store_boundary = DMNEW(stackptr, cd->maxlocals);
2035 /* initialize flags and invars (none) of first block */
2037 jd->basicblocks[0].flags = BBREACHED;
2038 jd->basicblocks[0].invars = NULL;
2039 jd->basicblocks[0].indepth = 0;
2040 jd->basicblocks[0].inlocals =
2041 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2042 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2043 jd->localcount + VERIFIER_EXTRA_LOCALS);
2045 /* stack analysis loop (until fixpoint reached) **************************/
2048 #if defined(ENABLE_STATISTICS)
2052 /* initialize loop over basic blocks */
2054 sd.bptr = jd->basicblocks;
2055 superblockend = true;
2057 curstack = NULL; stackdepth = 0;
2060 /* iterate over basic blocks *****************************************/
2062 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2064 if (sd.bptr->flags == BBDELETED) {
2065 /* This block has been deleted - do nothing. */
2070 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2071 /* re-analyse a block because its input changed */
2072 if (!stack_reanalyse_block(&sd))
2074 superblockend = true; /* XXX */
2078 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2079 /* This block has not been reached so far, and we */
2080 /* don't fall into it, so we'll have to iterate again. */
2086 if (sd.bptr->flags > BBREACHED) {
2087 /* This block is already finished. */
2089 superblockend = true;
2093 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2094 /* This block is a clone and the original has not been */
2095 /* analysed, yet. Analyse it on the next iteration. */
2098 /* XXX superblockend? */
2102 /* This block has to be analysed now. */
2104 /* XXX The rest of this block is still indented one level too */
2105 /* much in order to avoid a giant diff by changing that. */
2107 /* We know that sd.bptr->flags == BBREACHED. */
2108 /* This block has been reached before. */
2110 assert(sd.bptr->flags == BBREACHED);
2111 stackdepth = sd.bptr->indepth;
2113 /* find exception handlers for this block */
2115 /* determine the active exception handlers for this block */
2116 /* XXX could use a faster algorithm with sorted lists or */
2119 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2122 ex = cd->exceptiontable;
2123 for (; ex != NULL; ex = ex->down) {
2124 if ((ex->start <= original) && (ex->end > original)) {
2125 sd.handlers[len++] = ex;
2128 sd.handlers[len] = NULL;
2131 /* reanalyse cloned block */
2133 if (sd.bptr->original) {
2134 if (!stack_reanalyse_block(&sd))
2139 /* reset the new pointer for allocating stackslots */
2143 /* create the instack of this block */
2145 curstack = stack_create_instack(&sd);
2147 /* initialize locals at the start of this block */
2149 if (sd.bptr->inlocals)
2150 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2152 /* set up local variables for analyzing this block */
2155 superblockend = false;
2156 len = sd.bptr->icount;
2157 iptr = sd.bptr->iinstr;
2158 b_index = sd.bptr - jd->basicblocks;
2160 /* mark the block as analysed */
2162 sd.bptr->flags = BBFINISHED;
2164 /* reset variables for dependency checking */
2166 coalescing_boundary = sd.new;
2167 for( i = 0; i < cd->maxlocals; i++)
2168 last_store_boundary[i] = sd.new;
2170 /* remember the start of this block's variables */
2172 sd.bptr->varstart = sd.vartop;
2174 #if defined(STACK_VERBOSE)
2175 stack_verbose_block_enter(&sd, false);
2178 /* reach exception handlers for this block */
2180 if (!stack_reach_handlers(&sd))
2183 /* iterate over ICMDs ****************************************/
2185 while (--len >= 0) {
2187 #if defined(STACK_VERBOSE)
2188 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2189 for( copy = curstack; copy; copy = copy->prev ) {
2190 printf("%2d(%d", copy->varnum, copy->type);
2193 if (IS_PREALLOC(copy))
2200 /* fetch the current opcode */
2204 /* automatically replace some ICMDs with builtins */
2206 #if defined(USEBUILTINTABLE)
2207 bte = builtintable_get_automatic(opcode);
2209 if (bte && bte->opcode == opcode) {
2210 iptr->opc = ICMD_BUILTIN;
2211 iptr->flags.bits = 0;
2212 iptr->sx.s23.s3.bte = bte;
2213 /* iptr->line is already set */
2214 jd->isleafmethod = false;
2217 #endif /* defined(USEBUILTINTABLE) */
2219 /* main opcode switch *************************************/
2231 case ICMD_CHECKNULL:
2232 coalescing_boundary = sd.new;
2233 COUNT(count_check_null);
2236 iptr->dst.varindex = iptr->s1.varindex;
2240 j = iptr->s1.varindex =
2241 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2243 #if defined(ENABLE_VERIFIER)
2244 if (sd.var[j].type != TYPE_RET) {
2245 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2252 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2253 superblockend = true;
2257 COUNT(count_pcmd_return);
2260 superblockend = true;
2264 /* pop 0 push 1 const */
2266 /************************** ICONST OPTIMIZATIONS **************************/
2269 COUNT(count_pcmd_load);
2273 switch (iptr[1].opc) {
2275 iptr->opc = ICMD_IADDCONST;
2279 iptr[1].opc = ICMD_NOP;
2280 OP1_1(TYPE_INT, TYPE_INT);
2281 COUNT(count_pcmd_op);
2285 iptr->opc = ICMD_ISUBCONST;
2286 goto icmd_iconst_tail;
2287 #if SUPPORT_CONST_MUL
2289 iptr->opc = ICMD_IMULCONST;
2290 goto icmd_iconst_tail;
2291 #else /* SUPPORT_CONST_MUL */
2293 if (iptr->sx.val.i == 0x00000002)
2295 else if (iptr->sx.val.i == 0x00000004)
2297 else if (iptr->sx.val.i == 0x00000008)
2299 else if (iptr->sx.val.i == 0x00000010)
2301 else if (iptr->sx.val.i == 0x00000020)
2303 else if (iptr->sx.val.i == 0x00000040)
2305 else if (iptr->sx.val.i == 0x00000080)
2307 else if (iptr->sx.val.i == 0x00000100)
2309 else if (iptr->sx.val.i == 0x00000200)
2311 else if (iptr->sx.val.i == 0x00000400)
2312 iptr->sx.val.i = 10;
2313 else if (iptr->sx.val.i == 0x00000800)
2314 iptr->sx.val.i = 11;
2315 else if (iptr->sx.val.i == 0x00001000)
2316 iptr->sx.val.i = 12;
2317 else if (iptr->sx.val.i == 0x00002000)
2318 iptr->sx.val.i = 13;
2319 else if (iptr->sx.val.i == 0x00004000)
2320 iptr->sx.val.i = 14;
2321 else if (iptr->sx.val.i == 0x00008000)
2322 iptr->sx.val.i = 15;
2323 else if (iptr->sx.val.i == 0x00010000)
2324 iptr->sx.val.i = 16;
2325 else if (iptr->sx.val.i == 0x00020000)
2326 iptr->sx.val.i = 17;
2327 else if (iptr->sx.val.i == 0x00040000)
2328 iptr->sx.val.i = 18;
2329 else if (iptr->sx.val.i == 0x00080000)
2330 iptr->sx.val.i = 19;
2331 else if (iptr->sx.val.i == 0x00100000)
2332 iptr->sx.val.i = 20;
2333 else if (iptr->sx.val.i == 0x00200000)
2334 iptr->sx.val.i = 21;
2335 else if (iptr->sx.val.i == 0x00400000)
2336 iptr->sx.val.i = 22;
2337 else if (iptr->sx.val.i == 0x00800000)
2338 iptr->sx.val.i = 23;
2339 else if (iptr->sx.val.i == 0x01000000)
2340 iptr->sx.val.i = 24;
2341 else if (iptr->sx.val.i == 0x02000000)
2342 iptr->sx.val.i = 25;
2343 else if (iptr->sx.val.i == 0x04000000)
2344 iptr->sx.val.i = 26;
2345 else if (iptr->sx.val.i == 0x08000000)
2346 iptr->sx.val.i = 27;
2347 else if (iptr->sx.val.i == 0x10000000)
2348 iptr->sx.val.i = 28;
2349 else if (iptr->sx.val.i == 0x20000000)
2350 iptr->sx.val.i = 29;
2351 else if (iptr->sx.val.i == 0x40000000)
2352 iptr->sx.val.i = 30;
2353 else if (iptr->sx.val.i == 0x80000000)
2354 iptr->sx.val.i = 31;
2358 iptr->opc = ICMD_IMULPOW2;
2359 goto icmd_iconst_tail;
2360 #endif /* SUPPORT_CONST_MUL */
2362 if (iptr->sx.val.i == 0x00000002)
2364 else if (iptr->sx.val.i == 0x00000004)
2366 else if (iptr->sx.val.i == 0x00000008)
2368 else if (iptr->sx.val.i == 0x00000010)
2370 else if (iptr->sx.val.i == 0x00000020)
2372 else if (iptr->sx.val.i == 0x00000040)
2374 else if (iptr->sx.val.i == 0x00000080)
2376 else if (iptr->sx.val.i == 0x00000100)
2378 else if (iptr->sx.val.i == 0x00000200)
2380 else if (iptr->sx.val.i == 0x00000400)
2381 iptr->sx.val.i = 10;
2382 else if (iptr->sx.val.i == 0x00000800)
2383 iptr->sx.val.i = 11;
2384 else if (iptr->sx.val.i == 0x00001000)
2385 iptr->sx.val.i = 12;
2386 else if (iptr->sx.val.i == 0x00002000)
2387 iptr->sx.val.i = 13;
2388 else if (iptr->sx.val.i == 0x00004000)
2389 iptr->sx.val.i = 14;
2390 else if (iptr->sx.val.i == 0x00008000)
2391 iptr->sx.val.i = 15;
2392 else if (iptr->sx.val.i == 0x00010000)
2393 iptr->sx.val.i = 16;
2394 else if (iptr->sx.val.i == 0x00020000)
2395 iptr->sx.val.i = 17;
2396 else if (iptr->sx.val.i == 0x00040000)
2397 iptr->sx.val.i = 18;
2398 else if (iptr->sx.val.i == 0x00080000)
2399 iptr->sx.val.i = 19;
2400 else if (iptr->sx.val.i == 0x00100000)
2401 iptr->sx.val.i = 20;
2402 else if (iptr->sx.val.i == 0x00200000)
2403 iptr->sx.val.i = 21;
2404 else if (iptr->sx.val.i == 0x00400000)
2405 iptr->sx.val.i = 22;
2406 else if (iptr->sx.val.i == 0x00800000)
2407 iptr->sx.val.i = 23;
2408 else if (iptr->sx.val.i == 0x01000000)
2409 iptr->sx.val.i = 24;
2410 else if (iptr->sx.val.i == 0x02000000)
2411 iptr->sx.val.i = 25;
2412 else if (iptr->sx.val.i == 0x04000000)
2413 iptr->sx.val.i = 26;
2414 else if (iptr->sx.val.i == 0x08000000)
2415 iptr->sx.val.i = 27;
2416 else if (iptr->sx.val.i == 0x10000000)
2417 iptr->sx.val.i = 28;
2418 else if (iptr->sx.val.i == 0x20000000)
2419 iptr->sx.val.i = 29;
2420 else if (iptr->sx.val.i == 0x40000000)
2421 iptr->sx.val.i = 30;
2422 else if (iptr->sx.val.i == 0x80000000)
2423 iptr->sx.val.i = 31;
2427 iptr->opc = ICMD_IDIVPOW2;
2428 goto icmd_iconst_tail;
2431 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2432 if ((iptr->sx.val.i == 0x00000002) ||
2433 (iptr->sx.val.i == 0x00000004) ||
2434 (iptr->sx.val.i == 0x00000008) ||
2435 (iptr->sx.val.i == 0x00000010) ||
2436 (iptr->sx.val.i == 0x00000020) ||
2437 (iptr->sx.val.i == 0x00000040) ||
2438 (iptr->sx.val.i == 0x00000080) ||
2439 (iptr->sx.val.i == 0x00000100) ||
2440 (iptr->sx.val.i == 0x00000200) ||
2441 (iptr->sx.val.i == 0x00000400) ||
2442 (iptr->sx.val.i == 0x00000800) ||
2443 (iptr->sx.val.i == 0x00001000) ||
2444 (iptr->sx.val.i == 0x00002000) ||
2445 (iptr->sx.val.i == 0x00004000) ||
2446 (iptr->sx.val.i == 0x00008000) ||
2447 (iptr->sx.val.i == 0x00010000) ||
2448 (iptr->sx.val.i == 0x00020000) ||
2449 (iptr->sx.val.i == 0x00040000) ||
2450 (iptr->sx.val.i == 0x00080000) ||
2451 (iptr->sx.val.i == 0x00100000) ||
2452 (iptr->sx.val.i == 0x00200000) ||
2453 (iptr->sx.val.i == 0x00400000) ||
2454 (iptr->sx.val.i == 0x00800000) ||
2455 (iptr->sx.val.i == 0x01000000) ||
2456 (iptr->sx.val.i == 0x02000000) ||
2457 (iptr->sx.val.i == 0x04000000) ||
2458 (iptr->sx.val.i == 0x08000000) ||
2459 (iptr->sx.val.i == 0x10000000) ||
2460 (iptr->sx.val.i == 0x20000000) ||
2461 (iptr->sx.val.i == 0x40000000) ||
2462 (iptr->sx.val.i == 0x80000000))
2464 iptr->opc = ICMD_IREMPOW2;
2465 iptr->sx.val.i -= 1;
2466 goto icmd_iconst_tail;
2469 #if SUPPORT_CONST_LOGICAL
2471 iptr->opc = ICMD_IANDCONST;
2472 goto icmd_iconst_tail;
2475 iptr->opc = ICMD_IORCONST;
2476 goto icmd_iconst_tail;
2479 iptr->opc = ICMD_IXORCONST;
2480 goto icmd_iconst_tail;
2482 #endif /* SUPPORT_CONST_LOGICAL */
2484 iptr->opc = ICMD_ISHLCONST;
2485 goto icmd_iconst_tail;
2488 iptr->opc = ICMD_ISHRCONST;
2489 goto icmd_iconst_tail;
2492 iptr->opc = ICMD_IUSHRCONST;
2493 goto icmd_iconst_tail;
2494 #if SUPPORT_LONG_SHIFT
2496 iptr->opc = ICMD_LSHLCONST;
2497 goto icmd_lconst_tail;
2500 iptr->opc = ICMD_LSHRCONST;
2501 goto icmd_lconst_tail;
2504 iptr->opc = ICMD_LUSHRCONST;
2505 goto icmd_lconst_tail;
2506 #endif /* SUPPORT_LONG_SHIFT */
2507 case ICMD_IF_ICMPEQ:
2508 iptr[1].opc = ICMD_IFEQ;
2512 /* set the constant for the following icmd */
2513 iptr[1].sx.val.i = iptr->sx.val.i;
2515 /* this instruction becomes a nop */
2516 iptr->opc = ICMD_NOP;
2519 case ICMD_IF_ICMPLT:
2520 iptr[1].opc = ICMD_IFLT;
2521 goto icmd_if_icmp_tail;
2523 case ICMD_IF_ICMPLE:
2524 iptr[1].opc = ICMD_IFLE;
2525 goto icmd_if_icmp_tail;
2527 case ICMD_IF_ICMPNE:
2528 iptr[1].opc = ICMD_IFNE;
2529 goto icmd_if_icmp_tail;
2531 case ICMD_IF_ICMPGT:
2532 iptr[1].opc = ICMD_IFGT;
2533 goto icmd_if_icmp_tail;
2535 case ICMD_IF_ICMPGE:
2536 iptr[1].opc = ICMD_IFGE;
2537 goto icmd_if_icmp_tail;
2539 #if SUPPORT_CONST_STORE
2544 # if SUPPORT_CONST_STORE_ZERO_ONLY
2545 if (iptr->sx.val.i != 0)
2548 switch (iptr[1].opc) {
2550 iptr->opc = ICMD_IASTORECONST;
2551 iptr->flags.bits |= INS_FLAG_CHECK;
2554 iptr->opc = ICMD_BASTORECONST;
2555 iptr->flags.bits |= INS_FLAG_CHECK;
2558 iptr->opc = ICMD_CASTORECONST;
2559 iptr->flags.bits |= INS_FLAG_CHECK;
2562 iptr->opc = ICMD_SASTORECONST;
2563 iptr->flags.bits |= INS_FLAG_CHECK;
2567 iptr[1].opc = ICMD_NOP;
2569 /* copy the constant to s3 */
2570 /* XXX constval -> astoreconstval? */
2571 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2572 OP2_0(TYPE_ADR, TYPE_INT);
2573 COUNT(count_pcmd_op);
2576 case ICMD_PUTSTATIC:
2578 # if SUPPORT_CONST_STORE_ZERO_ONLY
2579 if (iptr->sx.val.i != 0)
2582 /* XXX check field type? */
2584 /* copy the constant to s2 */
2585 /* XXX constval -> fieldconstval? */
2586 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2589 /* set the field reference (s3) */
2590 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2591 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2592 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2595 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2598 switch (iptr[1].opc) {
2599 case ICMD_PUTSTATIC:
2600 iptr->opc = ICMD_PUTSTATICCONST;
2604 iptr->opc = ICMD_PUTFIELDCONST;
2609 iptr[1].opc = ICMD_NOP;
2610 COUNT(count_pcmd_op);
2612 #endif /* SUPPORT_CONST_STORE */
2618 /* if we get here, the ICONST has been optimized */
2622 /* normal case of an unoptimized ICONST */
2626 /************************** LCONST OPTIMIZATIONS **************************/
2629 COUNT(count_pcmd_load);
2633 /* switch depending on the following instruction */
2635 switch (iptr[1].opc) {
2636 #if SUPPORT_LONG_ADD
2638 iptr->opc = ICMD_LADDCONST;
2642 /* instruction of type LONG -> LONG */
2643 iptr[1].opc = ICMD_NOP;
2644 OP1_1(TYPE_LNG, TYPE_LNG);
2645 COUNT(count_pcmd_op);
2649 iptr->opc = ICMD_LSUBCONST;
2650 goto icmd_lconst_tail;
2652 #endif /* SUPPORT_LONG_ADD */
2653 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2655 iptr->opc = ICMD_LMULCONST;
2656 goto icmd_lconst_tail;
2657 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2658 # if SUPPORT_LONG_SHIFT
2660 if (iptr->sx.val.l == 0x00000002)
2662 else if (iptr->sx.val.l == 0x00000004)
2664 else if (iptr->sx.val.l == 0x00000008)
2666 else if (iptr->sx.val.l == 0x00000010)
2668 else if (iptr->sx.val.l == 0x00000020)
2670 else if (iptr->sx.val.l == 0x00000040)
2672 else if (iptr->sx.val.l == 0x00000080)
2674 else if (iptr->sx.val.l == 0x00000100)
2676 else if (iptr->sx.val.l == 0x00000200)
2678 else if (iptr->sx.val.l == 0x00000400)
2679 iptr->sx.val.i = 10;
2680 else if (iptr->sx.val.l == 0x00000800)
2681 iptr->sx.val.i = 11;
2682 else if (iptr->sx.val.l == 0x00001000)
2683 iptr->sx.val.i = 12;
2684 else if (iptr->sx.val.l == 0x00002000)
2685 iptr->sx.val.i = 13;
2686 else if (iptr->sx.val.l == 0x00004000)
2687 iptr->sx.val.i = 14;
2688 else if (iptr->sx.val.l == 0x00008000)
2689 iptr->sx.val.i = 15;
2690 else if (iptr->sx.val.l == 0x00010000)
2691 iptr->sx.val.i = 16;
2692 else if (iptr->sx.val.l == 0x00020000)
2693 iptr->sx.val.i = 17;
2694 else if (iptr->sx.val.l == 0x00040000)
2695 iptr->sx.val.i = 18;
2696 else if (iptr->sx.val.l == 0x00080000)
2697 iptr->sx.val.i = 19;
2698 else if (iptr->sx.val.l == 0x00100000)
2699 iptr->sx.val.i = 20;
2700 else if (iptr->sx.val.l == 0x00200000)
2701 iptr->sx.val.i = 21;
2702 else if (iptr->sx.val.l == 0x00400000)
2703 iptr->sx.val.i = 22;
2704 else if (iptr->sx.val.l == 0x00800000)
2705 iptr->sx.val.i = 23;
2706 else if (iptr->sx.val.l == 0x01000000)
2707 iptr->sx.val.i = 24;
2708 else if (iptr->sx.val.l == 0x02000000)
2709 iptr->sx.val.i = 25;
2710 else if (iptr->sx.val.l == 0x04000000)
2711 iptr->sx.val.i = 26;
2712 else if (iptr->sx.val.l == 0x08000000)
2713 iptr->sx.val.i = 27;
2714 else if (iptr->sx.val.l == 0x10000000)
2715 iptr->sx.val.i = 28;
2716 else if (iptr->sx.val.l == 0x20000000)
2717 iptr->sx.val.i = 29;
2718 else if (iptr->sx.val.l == 0x40000000)
2719 iptr->sx.val.i = 30;
2720 else if (iptr->sx.val.l == 0x80000000)
2721 iptr->sx.val.i = 31;
2725 iptr->opc = ICMD_LMULPOW2;
2726 goto icmd_lconst_tail;
2727 # endif /* SUPPORT_LONG_SHIFT */
2728 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2729 #if SUPPORT_LONG_DIV_POW2
2731 if (iptr->sx.val.l == 0x00000002)
2733 else if (iptr->sx.val.l == 0x00000004)
2735 else if (iptr->sx.val.l == 0x00000008)
2737 else if (iptr->sx.val.l == 0x00000010)
2739 else if (iptr->sx.val.l == 0x00000020)
2741 else if (iptr->sx.val.l == 0x00000040)
2743 else if (iptr->sx.val.l == 0x00000080)
2745 else if (iptr->sx.val.l == 0x00000100)
2747 else if (iptr->sx.val.l == 0x00000200)
2749 else if (iptr->sx.val.l == 0x00000400)
2750 iptr->sx.val.i = 10;
2751 else if (iptr->sx.val.l == 0x00000800)
2752 iptr->sx.val.i = 11;
2753 else if (iptr->sx.val.l == 0x00001000)
2754 iptr->sx.val.i = 12;
2755 else if (iptr->sx.val.l == 0x00002000)
2756 iptr->sx.val.i = 13;
2757 else if (iptr->sx.val.l == 0x00004000)
2758 iptr->sx.val.i = 14;
2759 else if (iptr->sx.val.l == 0x00008000)
2760 iptr->sx.val.i = 15;
2761 else if (iptr->sx.val.l == 0x00010000)
2762 iptr->sx.val.i = 16;
2763 else if (iptr->sx.val.l == 0x00020000)
2764 iptr->sx.val.i = 17;
2765 else if (iptr->sx.val.l == 0x00040000)
2766 iptr->sx.val.i = 18;
2767 else if (iptr->sx.val.l == 0x00080000)
2768 iptr->sx.val.i = 19;
2769 else if (iptr->sx.val.l == 0x00100000)
2770 iptr->sx.val.i = 20;
2771 else if (iptr->sx.val.l == 0x00200000)
2772 iptr->sx.val.i = 21;
2773 else if (iptr->sx.val.l == 0x00400000)
2774 iptr->sx.val.i = 22;
2775 else if (iptr->sx.val.l == 0x00800000)
2776 iptr->sx.val.i = 23;
2777 else if (iptr->sx.val.l == 0x01000000)
2778 iptr->sx.val.i = 24;
2779 else if (iptr->sx.val.l == 0x02000000)
2780 iptr->sx.val.i = 25;
2781 else if (iptr->sx.val.l == 0x04000000)
2782 iptr->sx.val.i = 26;
2783 else if (iptr->sx.val.l == 0x08000000)
2784 iptr->sx.val.i = 27;
2785 else if (iptr->sx.val.l == 0x10000000)
2786 iptr->sx.val.i = 28;
2787 else if (iptr->sx.val.l == 0x20000000)
2788 iptr->sx.val.i = 29;
2789 else if (iptr->sx.val.l == 0x40000000)
2790 iptr->sx.val.i = 30;
2791 else if (iptr->sx.val.l == 0x80000000)
2792 iptr->sx.val.i = 31;
2796 iptr->opc = ICMD_LDIVPOW2;
2797 goto icmd_lconst_tail;
2798 #endif /* SUPPORT_LONG_DIV_POW2 */
2800 #if SUPPORT_LONG_REM_POW2
2802 if ((iptr->sx.val.l == 0x00000002) ||
2803 (iptr->sx.val.l == 0x00000004) ||
2804 (iptr->sx.val.l == 0x00000008) ||
2805 (iptr->sx.val.l == 0x00000010) ||
2806 (iptr->sx.val.l == 0x00000020) ||
2807 (iptr->sx.val.l == 0x00000040) ||
2808 (iptr->sx.val.l == 0x00000080) ||
2809 (iptr->sx.val.l == 0x00000100) ||
2810 (iptr->sx.val.l == 0x00000200) ||
2811 (iptr->sx.val.l == 0x00000400) ||
2812 (iptr->sx.val.l == 0x00000800) ||
2813 (iptr->sx.val.l == 0x00001000) ||
2814 (iptr->sx.val.l == 0x00002000) ||
2815 (iptr->sx.val.l == 0x00004000) ||
2816 (iptr->sx.val.l == 0x00008000) ||
2817 (iptr->sx.val.l == 0x00010000) ||
2818 (iptr->sx.val.l == 0x00020000) ||
2819 (iptr->sx.val.l == 0x00040000) ||
2820 (iptr->sx.val.l == 0x00080000) ||
2821 (iptr->sx.val.l == 0x00100000) ||
2822 (iptr->sx.val.l == 0x00200000) ||
2823 (iptr->sx.val.l == 0x00400000) ||
2824 (iptr->sx.val.l == 0x00800000) ||
2825 (iptr->sx.val.l == 0x01000000) ||
2826 (iptr->sx.val.l == 0x02000000) ||
2827 (iptr->sx.val.l == 0x04000000) ||
2828 (iptr->sx.val.l == 0x08000000) ||
2829 (iptr->sx.val.l == 0x10000000) ||
2830 (iptr->sx.val.l == 0x20000000) ||
2831 (iptr->sx.val.l == 0x40000000) ||
2832 (iptr->sx.val.l == 0x80000000))
2834 iptr->opc = ICMD_LREMPOW2;
2835 iptr->sx.val.l -= 1;
2836 goto icmd_lconst_tail;
2839 #endif /* SUPPORT_LONG_REM_POW2 */
2841 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2844 iptr->opc = ICMD_LANDCONST;
2845 goto icmd_lconst_tail;
2848 iptr->opc = ICMD_LORCONST;
2849 goto icmd_lconst_tail;
2852 iptr->opc = ICMD_LXORCONST;
2853 goto icmd_lconst_tail;
2854 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2856 #if SUPPORT_LONG_CMP_CONST
2858 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2861 /* switch on the instruction after LCONST - LCMP */
2863 switch (iptr[2].opc) {
2865 iptr->opc = ICMD_IF_LEQ;
2868 icmd_lconst_lcmp_tail:
2869 /* convert LCONST, LCMP, IFXX to IF_LXX */
2870 iptr->dst.insindex = iptr[2].dst.insindex;
2871 iptr[1].opc = ICMD_NOP;
2872 iptr[2].opc = ICMD_NOP;
2874 OP1_BRANCH(TYPE_LNG);
2876 COUNT(count_pcmd_bra);
2877 COUNT(count_pcmd_op);
2881 iptr->opc = ICMD_IF_LNE;
2882 goto icmd_lconst_lcmp_tail;
2885 iptr->opc = ICMD_IF_LLT;
2886 goto icmd_lconst_lcmp_tail;
2889 iptr->opc = ICMD_IF_LGT;
2890 goto icmd_lconst_lcmp_tail;
2893 iptr->opc = ICMD_IF_LLE;
2894 goto icmd_lconst_lcmp_tail;
2897 iptr->opc = ICMD_IF_LGE;
2898 goto icmd_lconst_lcmp_tail;
2902 } /* end switch on opcode after LCONST - LCMP */
2904 #endif /* SUPPORT_LONG_CMP_CONST */
2906 #if SUPPORT_CONST_STORE
2908 # if SUPPORT_CONST_STORE_ZERO_ONLY
2909 if (iptr->sx.val.l != 0)
2912 #if SIZEOF_VOID_P == 4
2913 /* the constant must fit into a ptrint */
2914 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2917 /* move the constant to s3 */
2918 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2920 iptr->opc = ICMD_LASTORECONST;
2921 iptr->flags.bits |= INS_FLAG_CHECK;
2922 OP2_0(TYPE_ADR, TYPE_INT);
2924 iptr[1].opc = ICMD_NOP;
2925 COUNT(count_pcmd_op);
2928 case ICMD_PUTSTATIC:
2930 # if SUPPORT_CONST_STORE_ZERO_ONLY
2931 if (iptr->sx.val.l != 0)
2934 #if SIZEOF_VOID_P == 4
2935 /* the constant must fit into a ptrint */
2936 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2939 /* XXX check field type? */
2941 /* copy the constant to s2 */
2942 /* XXX constval -> fieldconstval? */
2943 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2947 #endif /* SUPPORT_CONST_STORE */
2951 } /* end switch opcode after LCONST */
2953 /* if we get here, the LCONST has been optimized */
2957 /* the normal case of an unoptimized LCONST */
2961 /************************ END OF LCONST OPTIMIZATIONS *********************/
2964 COUNT(count_pcmd_load);
2969 COUNT(count_pcmd_load);
2973 /************************** ACONST OPTIMIZATIONS **************************/
2976 coalescing_boundary = sd.new;
2977 COUNT(count_pcmd_load);
2978 #if SUPPORT_CONST_STORE
2979 /* We can only optimize if the ACONST is resolved
2980 * and there is an instruction after it. */
2982 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2985 switch (iptr[1].opc) {
2987 /* We can only optimize for NULL values
2988 * here because otherwise a checkcast is
2990 if (iptr->sx.val.anyptr != NULL)
2993 /* copy the constant (NULL) to s3 */
2994 iptr->sx.s23.s3.constval = 0;
2995 iptr->opc = ICMD_AASTORECONST;
2996 iptr->flags.bits |= INS_FLAG_CHECK;
2997 OP2_0(TYPE_ADR, TYPE_INT);
2999 iptr[1].opc = ICMD_NOP;
3000 COUNT(count_pcmd_op);
3003 case ICMD_PUTSTATIC:
3005 # if SUPPORT_CONST_STORE_ZERO_ONLY
3006 if (iptr->sx.val.anyptr != NULL)
3009 /* XXX check field type? */
3010 /* copy the constant to s2 */
3011 /* XXX constval -> fieldconstval? */
3012 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3020 /* if we get here the ACONST has been optimized */
3024 #endif /* SUPPORT_CONST_STORE */
3029 /* pop 0 push 1 load */
3036 COUNT(count_load_instruction);
3037 i = opcode - ICMD_ILOAD; /* type */
3039 j = iptr->s1.varindex =
3040 jd->local_map[iptr->s1.varindex * 5 + i];
3042 #if defined(ENABLE_VERIFIER)
3043 if (sd.var[j].type == TYPE_RET) {
3044 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3049 #if defined(ENABLE_SSA)
3051 GET_NEW_VAR(sd, new_index, i);
3068 coalescing_boundary = sd.new;
3069 iptr->flags.bits |= INS_FLAG_CHECK;
3070 COUNT(count_check_null);
3071 COUNT(count_check_bound);
3072 COUNT(count_pcmd_mem);
3073 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3080 coalescing_boundary = sd.new;
3081 iptr->flags.bits |= INS_FLAG_CHECK;
3082 COUNT(count_check_null);
3083 COUNT(count_check_bound);
3084 COUNT(count_pcmd_mem);
3085 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3088 /* pop 0 push 0 iinc */
3091 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3092 #if defined(ENABLE_SSA)
3095 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3099 last_store_boundary[iptr->s1.varindex] = sd.new;
3102 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3107 if ((copy->varkind == LOCALVAR) &&
3108 (copy->varnum == iptr->s1.varindex))
3110 assert(IS_LOCALVAR(copy));
3116 #if defined(ENABLE_SSA)
3120 iptr->dst.varindex = iptr->s1.varindex;
3123 /* pop 1 push 0 store */
3132 i = opcode - ICMD_ISTORE; /* type */
3133 javaindex = iptr->dst.varindex;
3134 j = iptr->dst.varindex =
3135 jd->local_map[javaindex * 5 + i];
3137 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3139 #if defined(ENABLE_STATISTICS)
3142 i = sd.new - curstack;
3144 count_store_length[20]++;
3146 count_store_length[i]++;
3149 count_store_depth[10]++;
3151 count_store_depth[i]++;
3155 #if defined(ENABLE_SSA)
3158 /* check for conflicts as described in Figure 5.2 */
3160 copy = curstack->prev;
3163 if ((copy->varkind == LOCALVAR) &&
3164 (copy->varnum == j))
3166 copy->varkind = TEMPVAR;
3167 assert(IS_LOCALVAR(copy));
3174 /* if the variable is already coalesced, don't bother */
3176 /* We do not need to check against INOUT, as invars */
3177 /* are always before the coalescing boundary. */
3179 if (curstack->varkind == LOCALVAR)
3182 /* there is no STORE Lj while curstack is live */
3184 if (curstack < last_store_boundary[javaindex])
3185 goto assume_conflict;
3187 /* curstack must be after the coalescing boundary */
3189 if (curstack < coalescing_boundary)
3190 goto assume_conflict;
3192 /* there is no DEF LOCALVAR(j) while curstack is live */
3194 copy = sd.new; /* most recent stackslot created + 1 */
3195 while (--copy > curstack) {
3196 if (copy->varkind == LOCALVAR && copy->varnum == j)
3197 goto assume_conflict;
3200 /* coalesce the temporary variable with Lj */
3201 assert((curstack->varkind == TEMPVAR)
3202 || (curstack->varkind == UNDEFVAR));
3203 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3204 assert(!IS_INOUT(curstack));
3205 assert(!IS_PREALLOC(curstack));
3207 assert(curstack->creator);
3208 assert(curstack->creator->dst.varindex == curstack->varnum);
3209 assert(!(curstack->flags & PASSTHROUGH));
3210 RELEASE_INDEX(sd, curstack);
3211 curstack->varkind = LOCALVAR;
3212 curstack->varnum = j;
3213 curstack->creator->dst.varindex = j;
3216 /* revert the coalescing, if it has been done earlier */
3218 if ((curstack->varkind == LOCALVAR)
3219 && (curstack->varnum == j))
3221 assert(IS_LOCALVAR(curstack));
3222 SET_TEMPVAR(curstack);
3225 /* remember the stack boundary at this store */
3227 last_store_boundary[javaindex] = sd.new;
3228 #if defined(ENABLE_SSA)
3229 } /* if (ls != NULL) */
3232 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3235 STORE(opcode - ICMD_ISTORE, j);
3241 coalescing_boundary = sd.new;
3242 iptr->flags.bits |= INS_FLAG_CHECK;
3243 COUNT(count_check_null);
3244 COUNT(count_check_bound);
3245 COUNT(count_pcmd_mem);
3247 bte = builtintable_get_internal(BUILTIN_canstore);
3250 if (md->memuse > rd->memuse)
3251 rd->memuse = md->memuse;
3252 if (md->argintreguse > rd->argintreguse)
3253 rd->argintreguse = md->argintreguse;
3254 /* XXX non-leaf method? */
3256 /* make all stack variables saved */
3260 sd.var[copy->varnum].flags |= SAVEDVAR;
3261 /* in case copy->varnum is/will be a LOCALVAR */
3262 /* once and set back to a non LOCALVAR */
3263 /* the correct SAVEDVAR flag has to be */
3264 /* remembered in copy->flags, too */
3265 copy->flags |= SAVEDVAR;
3269 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3276 coalescing_boundary = sd.new;
3277 iptr->flags.bits |= INS_FLAG_CHECK;
3278 COUNT(count_check_null);
3279 COUNT(count_check_bound);
3280 COUNT(count_pcmd_mem);
3281 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3288 coalescing_boundary = sd.new;
3289 iptr->flags.bits |= INS_FLAG_CHECK;
3290 COUNT(count_check_null);
3291 COUNT(count_check_bound);
3292 COUNT(count_pcmd_mem);
3293 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3299 #ifdef ENABLE_VERIFIER
3302 if (IS_2_WORD_TYPE(curstack->type))
3303 goto throw_stack_category_error;
3314 coalescing_boundary = sd.new;
3315 /* Assert here that no LOCAL or INOUTS get */
3316 /* preallocated, since tha macros are not */
3317 /* available in md-abi.c! */
3318 if (IS_TEMPVAR(curstack))
3319 md_return_alloc(jd, curstack);
3320 COUNT(count_pcmd_return);
3321 OP1_0(opcode - ICMD_IRETURN);
3322 superblockend = true;
3326 coalescing_boundary = sd.new;
3327 COUNT(count_check_null);
3329 curstack = NULL; stackdepth = 0;
3330 superblockend = true;
3333 case ICMD_PUTSTATIC:
3334 coalescing_boundary = sd.new;
3335 COUNT(count_pcmd_mem);
3336 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3337 OP1_0(fmiref->parseddesc.fd->type);
3340 /* pop 1 push 0 branch */
3343 case ICMD_IFNONNULL:
3344 COUNT(count_pcmd_bra);
3345 OP1_BRANCH(TYPE_ADR);
3355 COUNT(count_pcmd_bra);
3356 /* iptr->sx.val.i is set implicitly in parse by
3357 clearing the memory or from IF_ICMPxx
3360 OP1_BRANCH(TYPE_INT);
3361 /* iptr->sx.val.i = 0; */
3365 /* pop 0 push 0 branch */
3368 COUNT(count_pcmd_bra);
3371 superblockend = true;
3374 /* pop 1 push 0 table branch */
3376 case ICMD_TABLESWITCH:
3377 COUNT(count_pcmd_table);
3378 OP1_BRANCH(TYPE_INT);
3380 table = iptr->dst.table;
3381 BRANCH_TARGET(*table, tbptr);
3384 i = iptr->sx.s23.s3.tablehigh
3385 - iptr->sx.s23.s2.tablelow + 1;
3388 BRANCH_TARGET(*table, tbptr);
3391 superblockend = true;
3394 /* pop 1 push 0 table branch */
3396 case ICMD_LOOKUPSWITCH:
3397 COUNT(count_pcmd_table);
3398 OP1_BRANCH(TYPE_INT);
3400 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3402 lookup = iptr->dst.lookup;
3404 i = iptr->sx.s23.s2.lookupcount;
3407 BRANCH_TARGET(lookup->target, tbptr);
3410 superblockend = true;
3413 case ICMD_MONITORENTER:
3414 case ICMD_MONITOREXIT:
3415 coalescing_boundary = sd.new;
3416 COUNT(count_check_null);
3420 /* pop 2 push 0 branch */
3422 case ICMD_IF_ICMPEQ:
3423 case ICMD_IF_ICMPNE:
3424 case ICMD_IF_ICMPLT:
3425 case ICMD_IF_ICMPGE:
3426 case ICMD_IF_ICMPGT:
3427 case ICMD_IF_ICMPLE:
3428 COUNT(count_pcmd_bra);
3429 OP2_BRANCH(TYPE_INT, TYPE_INT);
3433 case ICMD_IF_ACMPEQ:
3434 case ICMD_IF_ACMPNE:
3435 COUNT(count_pcmd_bra);
3436 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3443 coalescing_boundary = sd.new;
3444 COUNT(count_check_null);
3445 COUNT(count_pcmd_mem);
3446 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3447 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3452 if (!IS_2_WORD_TYPE(curstack->type)) {
3454 #ifdef ENABLE_VERIFIER
3457 if (IS_2_WORD_TYPE(curstack->prev->type))
3458 goto throw_stack_category_error;
3461 OP2_0_ANY_ANY; /* pop two slots */
3464 iptr->opc = ICMD_POP;
3465 OP1_0_ANY; /* pop one (two-word) slot */
3469 /* pop 0 push 1 dup */
3472 #ifdef ENABLE_VERIFIER
3475 if (IS_2_WORD_TYPE(curstack->type))
3476 goto throw_stack_category_error;
3479 COUNT(count_dup_instruction);
3485 coalescing_boundary = sd.new - 1;
3490 if (IS_2_WORD_TYPE(curstack->type)) {
3492 iptr->opc = ICMD_DUP;
3497 /* ..., ????, cat1 */
3498 #ifdef ENABLE_VERIFIER
3500 if (IS_2_WORD_TYPE(curstack->prev->type))
3501 goto throw_stack_category_error;
3504 src1 = curstack->prev;
3507 COPY_UP(src1); iptr++; len--;
3510 coalescing_boundary = sd.new;
3514 /* pop 2 push 3 dup */
3517 #ifdef ENABLE_VERIFIER
3520 if (IS_2_WORD_TYPE(curstack->type) ||
3521 IS_2_WORD_TYPE(curstack->prev->type))
3522 goto throw_stack_category_error;
3527 src1 = curstack->prev;
3532 /* move non-temporary sources out of the way */
3533 if (!IS_TEMPVAR(src2)) {
3534 MOVE_TO_TEMP(src2); iptr++; len--;
3537 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3539 MOVE_UP(src1); iptr++; len--;
3540 MOVE_UP(src2); iptr++; len--;
3542 COPY_DOWN(curstack, dst1);
3544 coalescing_boundary = sd.new;
3549 if (IS_2_WORD_TYPE(curstack->type)) {
3550 /* ..., ????, cat2 */
3551 #ifdef ENABLE_VERIFIER
3553 if (IS_2_WORD_TYPE(curstack->prev->type))
3554 goto throw_stack_category_error;
3557 iptr->opc = ICMD_DUP_X1;
3561 /* ..., ????, cat1 */
3562 #ifdef ENABLE_VERIFIER
3565 if (IS_2_WORD_TYPE(curstack->prev->type)
3566 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3567 goto throw_stack_category_error;
3572 src1 = curstack->prev->prev;
3573 src2 = curstack->prev;
3575 POPANY; POPANY; POPANY;
3578 /* move non-temporary sources out of the way */
3579 if (!IS_TEMPVAR(src2)) {
3580 MOVE_TO_TEMP(src2); iptr++; len--;
3582 if (!IS_TEMPVAR(src3)) {
3583 MOVE_TO_TEMP(src3); iptr++; len--;
3586 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3587 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3589 MOVE_UP(src1); iptr++; len--;
3590 MOVE_UP(src2); iptr++; len--;
3591 MOVE_UP(src3); iptr++; len--;
3593 COPY_DOWN(curstack, dst2); iptr++; len--;
3594 COPY_DOWN(curstack->prev, dst1);
3596 coalescing_boundary = sd.new;
3600 /* pop 3 push 4 dup */
3604 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3605 /* ..., cat2, ???? */
3606 #ifdef ENABLE_VERIFIER
3608 if (IS_2_WORD_TYPE(curstack->type))
3609 goto throw_stack_category_error;
3612 iptr->opc = ICMD_DUP_X1;
3616 /* ..., cat1, ???? */
3617 #ifdef ENABLE_VERIFIER
3620 if (IS_2_WORD_TYPE(curstack->type)
3621 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3622 goto throw_stack_category_error;
3626 src1 = curstack->prev->prev;
3627 src2 = curstack->prev;
3629 POPANY; POPANY; POPANY;
3632 /* move non-temporary sources out of the way */
3633 if (!IS_TEMPVAR(src2)) {
3634 MOVE_TO_TEMP(src2); iptr++; len--;
3636 if (!IS_TEMPVAR(src3)) {
3637 MOVE_TO_TEMP(src3); iptr++; len--;
3640 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3642 MOVE_UP(src1); iptr++; len--;
3643 MOVE_UP(src2); iptr++; len--;
3644 MOVE_UP(src3); iptr++; len--;
3646 COPY_DOWN(curstack, dst1);
3648 coalescing_boundary = sd.new;
3654 if (IS_2_WORD_TYPE(curstack->type)) {
3655 /* ..., ????, cat2 */
3656 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3657 /* ..., cat2, cat2 */
3658 iptr->opc = ICMD_DUP_X1;
3662 /* ..., cat1, cat2 */
3663 #ifdef ENABLE_VERIFIER
3666 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3667 goto throw_stack_category_error;
3670 iptr->opc = ICMD_DUP_X2;
3676 /* ..., ????, ????, cat1 */
3678 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3679 /* ..., cat2, ????, cat1 */
3680 #ifdef ENABLE_VERIFIER
3682 if (IS_2_WORD_TYPE(curstack->prev->type))
3683 goto throw_stack_category_error;
3686 iptr->opc = ICMD_DUP2_X1;
3690 /* ..., cat1, ????, cat1 */
3691 #ifdef ENABLE_VERIFIER
3694 if (IS_2_WORD_TYPE(curstack->prev->type)
3695 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3696 goto throw_stack_category_error;
3700 src1 = curstack->prev->prev->prev;
3701 src2 = curstack->prev->prev;
3702 src3 = curstack->prev;
3704 POPANY; POPANY; POPANY; POPANY;
3707 /* move non-temporary sources out of the way */
3708 if (!IS_TEMPVAR(src2)) {
3709 MOVE_TO_TEMP(src2); iptr++; len--;
3711 if (!IS_TEMPVAR(src3)) {
3712 MOVE_TO_TEMP(src3); iptr++; len--;
3714 if (!IS_TEMPVAR(src4)) {
3715 MOVE_TO_TEMP(src4); iptr++; len--;
3718 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3719 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3721 MOVE_UP(src1); iptr++; len--;
3722 MOVE_UP(src2); iptr++; len--;
3723 MOVE_UP(src3); iptr++; len--;
3724 MOVE_UP(src4); iptr++; len--;
3726 COPY_DOWN(curstack, dst2); iptr++; len--;
3727 COPY_DOWN(curstack->prev, dst1);
3729 coalescing_boundary = sd.new;
3733 /* pop 2 push 2 swap */
3736 #ifdef ENABLE_VERIFIER
3739 if (IS_2_WORD_TYPE(curstack->type)
3740 || IS_2_WORD_TYPE(curstack->prev->type))
3741 goto throw_stack_category_error;
3745 src1 = curstack->prev;
3750 /* move non-temporary sources out of the way */
3751 if (!IS_TEMPVAR(src1)) {
3752 MOVE_TO_TEMP(src1); iptr++; len--;
3755 MOVE_UP(src2); iptr++; len--;
3758 coalescing_boundary = sd.new;
3765 coalescing_boundary = sd.new;
3766 #if !SUPPORT_DIVISION
3767 bte = iptr->sx.s23.s3.bte;
3770 if (md->memuse > rd->memuse)
3771 rd->memuse = md->memuse;
3772 if (md->argintreguse > rd->argintreguse)
3773 rd->argintreguse = md->argintreguse;
3775 /* make all stack variables saved */
3779 sd.var[copy->varnum].flags |= SAVEDVAR;
3780 copy->flags |= SAVEDVAR;
3785 #endif /* !SUPPORT_DIVISION */
3796 COUNT(count_pcmd_op);
3797 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3802 coalescing_boundary = sd.new;
3803 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3804 bte = iptr->sx.s23.s3.bte;
3807 if (md->memuse > rd->memuse)
3808 rd->memuse = md->memuse;
3809 if (md->argintreguse > rd->argintreguse)
3810 rd->argintreguse = md->argintreguse;
3811 /* XXX non-leaf method? */
3813 /* make all stack variables saved */
3817 sd.var[copy->varnum].flags |= SAVEDVAR;
3818 copy->flags |= SAVEDVAR;
3823 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3828 #if SUPPORT_LONG_LOGICAL
3832 #endif /* SUPPORT_LONG_LOGICAL */
3833 COUNT(count_pcmd_op);
3834 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3840 COUNT(count_pcmd_op);
3841 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3849 COUNT(count_pcmd_op);
3850 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3858 COUNT(count_pcmd_op);
3859 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3863 COUNT(count_pcmd_op);
3864 #if SUPPORT_LONG_CMP_CONST
3865 if ((len == 0) || (iptr[1].sx.val.i != 0))
3868 switch (iptr[1].opc) {
3870 iptr->opc = ICMD_IF_LCMPEQ;
3872 iptr->dst.insindex = iptr[1].dst.insindex;
3873 iptr[1].opc = ICMD_NOP;
3875 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3878 COUNT(count_pcmd_bra);
3881 iptr->opc = ICMD_IF_LCMPNE;
3882 goto icmd_lcmp_if_tail;
3884 iptr->opc = ICMD_IF_LCMPLT;
3885 goto icmd_lcmp_if_tail;
3887 iptr->opc = ICMD_IF_LCMPGT;
3888 goto icmd_lcmp_if_tail;
3890 iptr->opc = ICMD_IF_LCMPLE;
3891 goto icmd_lcmp_if_tail;
3893 iptr->opc = ICMD_IF_LCMPGE;
3894 goto icmd_lcmp_if_tail;
3900 #endif /* SUPPORT_LONG_CMP_CONST */
3901 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3904 /* XXX why is this deactivated? */
3907 COUNT(count_pcmd_op);
3908 if ((len == 0) || (iptr[1].sx.val.i != 0))
3911 switch (iptr[1].opc) {
3913 iptr->opc = ICMD_IF_FCMPEQ;
3915 iptr->dst.insindex = iptr[1].dst.insindex;
3916 iptr[1].opc = ICMD_NOP;
3918 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3921 COUNT(count_pcmd_bra);
3924 iptr->opc = ICMD_IF_FCMPNE;
3925 goto icmd_if_fcmpl_tail;
3927 iptr->opc = ICMD_IF_FCMPL_LT;
3928 goto icmd_if_fcmpl_tail;
3930 iptr->opc = ICMD_IF_FCMPL_GT;
3931 goto icmd_if_fcmpl_tail;
3933 iptr->opc = ICMD_IF_FCMPL_LE;
3934 goto icmd_if_fcmpl_tail;
3936 iptr->opc = ICMD_IF_FCMPL_GE;
3937 goto icmd_if_fcmpl_tail;
3944 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3948 COUNT(count_pcmd_op);
3949 if ((len == 0) || (iptr[1].sx.val.i != 0))
3952 switch (iptr[1].opc) {
3954 iptr->opc = ICMD_IF_FCMPEQ;
3956 iptr->dst.insindex = iptr[1].dst.insindex;
3957 iptr[1].opc = ICMD_NOP;
3959 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3962 COUNT(count_pcmd_bra);
3965 iptr->opc = ICMD_IF_FCMPNE;
3966 goto icmd_if_fcmpg_tail;
3968 iptr->opc = ICMD_IF_FCMPG_LT;
3969 goto icmd_if_fcmpg_tail;
3971 iptr->opc = ICMD_IF_FCMPG_GT;
3972 goto icmd_if_fcmpg_tail;
3974 iptr->opc = ICMD_IF_FCMPG_LE;
3975 goto icmd_if_fcmpg_tail;
3977 iptr->opc = ICMD_IF_FCMPG_GE;
3978 goto icmd_if_fcmpg_tail;
3985 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3989 COUNT(count_pcmd_op);
3990 if ((len == 0) || (iptr[1].sx.val.i != 0))
3993 switch (iptr[1].opc) {
3995 iptr->opc = ICMD_IF_DCMPEQ;
3997 iptr->dst.insindex = iptr[1].dst.insindex;
3998 iptr[1].opc = ICMD_NOP;
4000 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4003 COUNT(count_pcmd_bra);
4006 iptr->opc = ICMD_IF_DCMPNE;
4007 goto icmd_if_dcmpl_tail;
4009 iptr->opc = ICMD_IF_DCMPL_LT;
4010 goto icmd_if_dcmpl_tail;
4012 iptr->opc = ICMD_IF_DCMPL_GT;
4013 goto icmd_if_dcmpl_tail;
4015 iptr->opc = ICMD_IF_DCMPL_LE;
4016 goto icmd_if_dcmpl_tail;
4018 iptr->opc = ICMD_IF_DCMPL_GE;
4019 goto icmd_if_dcmpl_tail;
4026 OPTT2_1(TYPE_DBL, TYPE_INT);
4030 COUNT(count_pcmd_op);
4031 if ((len == 0) || (iptr[1].sx.val.i != 0))
4034 switch (iptr[1].opc) {
4036 iptr->opc = ICMD_IF_DCMPEQ;
4038 iptr->dst.insindex = iptr[1].dst.insindex;
4039 iptr[1].opc = ICMD_NOP;
4041 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4044 COUNT(count_pcmd_bra);
4047 iptr->opc = ICMD_IF_DCMPNE;
4048 goto icmd_if_dcmpg_tail;
4050 iptr->opc = ICMD_IF_DCMPG_LT;
4051 goto icmd_if_dcmpg_tail;
4053 iptr->opc = ICMD_IF_DCMPG_GT;
4054 goto icmd_if_dcmpg_tail;
4056 iptr->opc = ICMD_IF_DCMPG_LE;
4057 goto icmd_if_dcmpg_tail;
4059 iptr->opc = ICMD_IF_DCMPG_GE;
4060 goto icmd_if_dcmpg_tail;
4067 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4072 COUNT(count_pcmd_op);
4073 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4078 COUNT(count_pcmd_op);
4079 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4088 case ICMD_INT2SHORT:
4089 COUNT(count_pcmd_op);
4090 OP1_1(TYPE_INT, TYPE_INT);
4093 COUNT(count_pcmd_op);
4094 OP1_1(TYPE_LNG, TYPE_LNG);
4097 COUNT(count_pcmd_op);
4098 OP1_1(TYPE_FLT, TYPE_FLT);
4101 COUNT(count_pcmd_op);
4102 OP1_1(TYPE_DBL, TYPE_DBL);
4106 COUNT(count_pcmd_op);
4107 OP1_1(TYPE_INT, TYPE_LNG);
4110 COUNT(count_pcmd_op);
4111 OP1_1(TYPE_INT, TYPE_FLT);
4114 COUNT(count_pcmd_op);
4115 OP1_1(TYPE_INT, TYPE_DBL);
4118 COUNT(count_pcmd_op);
4119 OP1_1(TYPE_LNG, TYPE_INT);
4122 COUNT(count_pcmd_op);
4123 OP1_1(TYPE_LNG, TYPE_FLT);
4126 COUNT(count_pcmd_op);
4127 OP1_1(TYPE_LNG, TYPE_DBL);
4130 COUNT(count_pcmd_op);
4131 OP1_1(TYPE_FLT, TYPE_INT);
4134 COUNT(count_pcmd_op);
4135 OP1_1(TYPE_FLT, TYPE_LNG);
4138 COUNT(count_pcmd_op);
4139 OP1_1(TYPE_FLT, TYPE_DBL);
4142 COUNT(count_pcmd_op);
4143 OP1_1(TYPE_DBL, TYPE_INT);
4146 COUNT(count_pcmd_op);
4147 OP1_1(TYPE_DBL, TYPE_LNG);
4150 COUNT(count_pcmd_op);
4151 OP1_1(TYPE_DBL, TYPE_FLT);
4154 case ICMD_CHECKCAST:
4155 coalescing_boundary = sd.new;
4156 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4157 /* array type cast-check */
4159 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4162 if (md->memuse > rd->memuse)
4163 rd->memuse = md->memuse;
4164 if (md->argintreguse > rd->argintreguse)
4165 rd->argintreguse = md->argintreguse;
4167 /* make all stack variables saved */
4171 sd.var[copy->varnum].flags |= SAVEDVAR;
4172 copy->flags |= SAVEDVAR;
4176 OP1_1(TYPE_ADR, TYPE_ADR);
4179 case ICMD_INSTANCEOF:
4180 case ICMD_ARRAYLENGTH:
4181 coalescing_boundary = sd.new;
4182 OP1_1(TYPE_ADR, TYPE_INT);
4186 case ICMD_ANEWARRAY:
4187 coalescing_boundary = sd.new;
4188 OP1_1(TYPE_INT, TYPE_ADR);
4192 coalescing_boundary = sd.new;
4193 COUNT(count_check_null);
4194 COUNT(count_pcmd_mem);
4195 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4196 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4201 case ICMD_GETSTATIC:
4202 coalescing_boundary = sd.new;
4203 COUNT(count_pcmd_mem);
4204 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4205 OP0_1(fmiref->parseddesc.fd->type);
4209 coalescing_boundary = sd.new;
4216 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4217 tbptr->type = BBTYPE_SBR;
4219 assert(sd.bptr->next); /* XXX exception */
4220 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4221 #if defined(ENABLE_VERIFIER)
4222 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4225 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4229 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4231 /* We need to check for overflow right here because
4232 * the pushed value is poped afterwards */
4235 superblockend = true;
4236 /* XXX should not be marked as interface, as it does not need to be */
4237 /* allocated. Same for the invar of the target. */
4240 /* pop many push any */
4244 bte = iptr->sx.s23.s3.bte;
4248 case ICMD_INVOKESTATIC:
4249 case ICMD_INVOKESPECIAL:
4250 case ICMD_INVOKEVIRTUAL:
4251 case ICMD_INVOKEINTERFACE:
4252 COUNT(count_pcmd_met);
4254 /* Check for functions to replace with builtin
4257 if (builtintable_replace_function(iptr))
4260 INSTRUCTION_GET_METHODDESC(iptr, md);
4261 /* XXX resurrect this COUNT? */
4262 /* if (lm->flags & ACC_STATIC) */
4263 /* {COUNT(count_check_null);} */
4267 coalescing_boundary = sd.new;
4271 if (md->memuse > rd->memuse)
4272 rd->memuse = md->memuse;
4273 if (md->argintreguse > rd->argintreguse)
4274 rd->argintreguse = md->argintreguse;
4275 if (md->argfltreguse > rd->argfltreguse)
4276 rd->argfltreguse = md->argfltreguse;
4280 iptr->s1.argcount = stackdepth;
4281 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4284 for (i-- ; i >= 0; i--) {
4285 iptr->sx.s23.s2.args[i] = copy->varnum;
4287 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4288 /* -> won't help anyway */
4289 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4291 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4292 /* If we pass float arguments in integer argument registers, we
4293 * are not allowed to precolor them here. Floats have to be moved
4294 * to this regs explicitly in codegen().
4295 * Only arguments that are passed by stack anyway can be precolored
4296 * (michi 2005/07/24) */
4297 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4298 (!IS_FLT_DBL_TYPE(copy->type)
4299 || md->params[i].inmemory)) {
4301 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4306 if (md->params[i].inmemory) {
4307 sd.var[copy->varnum].vv.regoff =
4308 md->params[i].regoff;
4309 sd.var[copy->varnum].flags |=
4313 if (IS_FLT_DBL_TYPE(copy->type)) {
4314 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4315 assert(0); /* XXX is this assert ok? */
4317 sd.var[copy->varnum].vv.regoff =
4318 rd->argfltregs[md->params[i].regoff];
4319 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4322 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4323 if (IS_2_WORD_TYPE(copy->type))
4324 sd.var[copy->varnum].vv.regoff =
4325 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4326 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4329 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4330 sd.var[copy->varnum].vv.regoff =
4331 rd->argintregs[md->params[i].regoff];
4339 /* deal with live-through stack slots "under" the */
4345 iptr->sx.s23.s2.args[i++] = copy->varnum;
4346 sd.var[copy->varnum].flags |= SAVEDVAR;
4347 copy->flags |= SAVEDVAR | PASSTHROUGH;
4351 /* pop the arguments */
4360 /* push the return value */
4362 if (md->returntype.type != TYPE_VOID) {
4363 GET_NEW_VAR(sd, new_index, md->returntype.type);
4364 DST(md->returntype.type, new_index);
4369 case ICMD_INLINE_START:
4370 case ICMD_INLINE_END:
4375 case ICMD_MULTIANEWARRAY:
4376 coalescing_boundary = sd.new;
4377 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4378 rd->argintreguse = MIN(3, INT_ARG_CNT);
4380 i = iptr->s1.argcount;
4384 iptr->sx.s23.s2.args = DMNEW(s4, i);
4386 #if defined(SPECIALMEMUSE)
4387 # if defined(__DARWIN__)
4388 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4389 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4391 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4392 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4395 # if defined(__I386__)
4396 if (rd->memuse < i + 3)
4397 rd->memuse = i + 3; /* n integer args spilled on stack */
4398 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4399 if (rd->memuse < i + 2)
4400 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4403 rd->memuse = i; /* n integer args spilled on stack */
4404 # endif /* defined(__I386__) */
4408 /* check INT type here? Currently typecheck does this. */
4409 iptr->sx.s23.s2.args[i] = copy->varnum;
4410 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4411 && (!IS_INOUT(copy))
4412 && (!IS_LOCALVAR(copy)) ) {
4413 copy->varkind = ARGVAR;
4414 sd.var[copy->varnum].flags |=
4415 INMEMORY & PREALLOC;
4416 #if defined(SPECIALMEMUSE)
4417 # if defined(__DARWIN__)
4418 sd.var[copy->varnum].vv.regoff = i +
4419 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4421 sd.var[copy->varnum].vv.regoff = i +
4422 LA_SIZE_IN_POINTERS + 3;
4425 # if defined(__I386__)
4426 sd.var[copy->varnum].vv.regoff = i + 3;
4427 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4428 sd.var[copy->varnum].vv.regoff = i + 2;
4430 sd.var[copy->varnum].vv.regoff = i;
4431 # endif /* defined(__I386__) */
4432 #endif /* defined(SPECIALMEMUSE) */
4437 sd.var[copy->varnum].flags |= SAVEDVAR;
4438 copy->flags |= SAVEDVAR;
4442 i = iptr->s1.argcount;
4447 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4448 DST(TYPE_ADR, new_index);
4454 new_internalerror("Unknown ICMD %d", opcode);
4460 } /* while instructions */
4462 /* stack slots at basic block end become interfaces */
4464 sd.bptr->outdepth = stackdepth;
4465 sd.bptr->outvars = DMNEW(s4, stackdepth);
4468 for (copy = curstack; copy; i--, copy = copy->prev) {
4472 /* with the new vars rd->interfaces will be removed */
4473 /* and all in and outvars have to be STACKVARS! */
4474 /* in the moment i.e. SWAP with in and out vars can */
4475 /* create an unresolvable conflict */
4482 v = sd.var + copy->varnum;
4485 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4486 /* no interface var until now for this depth and */
4488 jd->interface_map[i*5 + t].flags = v->flags;
4491 jd->interface_map[i*5 + t].flags |= v->flags;
4494 sd.bptr->outvars[i] = copy->varnum;
4497 /* check if interface slots at basic block begin must be saved */
4499 for (i=0; i<sd.bptr->indepth; ++i) {
4500 varinfo *v = sd.var + sd.bptr->invars[i];
4507 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4508 /* no interface var until now for this depth and */
4510 jd->interface_map[i*5 + t].flags = v->flags;
4513 jd->interface_map[i*5 + t].flags |= v->flags;
4517 /* store the number of this block's variables */
4519 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4521 #if defined(STACK_VERBOSE)
4522 stack_verbose_block_exit(&sd, superblockend);
4525 /* reach the following block, if any */
4528 if (!stack_reach_next_block(&sd))
4533 } while (sd.repeat && !deadcode);
4535 /* XXX reset TYPE_RET to TYPE_ADR */
4537 for (i=0; i<sd.vartop; ++i) {
4538 if (sd.var[i].type == TYPE_RET)
4539 sd.var[i].type = TYPE_ADR;
4542 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4544 ex = cd->exceptiontable;
4545 for (; ex != NULL; ex = ex->down) {
4546 if (ex->start == ex->end) {
4547 assert(ex->end->next);
4548 ex->end = ex->end->next;
4552 /* gather statistics *****************************************************/
4554 #if defined(ENABLE_STATISTICS)
4556 if (jd->basicblockcount > count_max_basic_blocks)
4557 count_max_basic_blocks = jd->basicblockcount;
4558 count_basic_blocks += jd->basicblockcount;
4559 if (jd->instructioncount > count_max_javainstr)
4560 count_max_javainstr = jd->instructioncount;
4561 count_javainstr += jd->instructioncount;
4562 if (jd->stackcount > count_upper_bound_new_stack)
4563 count_upper_bound_new_stack = jd->stackcount;
4564 if ((sd.new - jd->stack) > count_max_new_stack)
4565 count_max_new_stack = (sd.new - jd->stack);
4567 sd.bptr = jd->basicblocks;
4568 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4569 if (sd.bptr->flags > BBREACHED) {
4570 if (sd.bptr->indepth >= 10)
4571 count_block_stack[10]++;
4573 count_block_stack[sd.bptr->indepth]++;
4574 len = sd.bptr->icount;
4576 count_block_size_distribution[len]++;
4578 count_block_size_distribution[10]++;
4580 count_block_size_distribution[11]++;
4582 count_block_size_distribution[12]++;
4584 count_block_size_distribution[13]++;
4586 count_block_size_distribution[14]++;
4588 count_block_size_distribution[15]++;
4590 count_block_size_distribution[16]++;
4592 count_block_size_distribution[17]++;
4596 if (iteration_count == 1)
4597 count_analyse_iterations[0]++;
4598 else if (iteration_count == 2)
4599 count_analyse_iterations[1]++;
4600 else if (iteration_count == 3)
4601 count_analyse_iterations[2]++;
4602 else if (iteration_count == 4)
4603 count_analyse_iterations[3]++;
4605 count_analyse_iterations[4]++;
4607 if (jd->basicblockcount <= 5)
4608 count_method_bb_distribution[0]++;
4609 else if (jd->basicblockcount <= 10)
4610 count_method_bb_distribution[1]++;
4611 else if (jd->basicblockcount <= 15)
4612 count_method_bb_distribution[2]++;
4613 else if (jd->basicblockcount <= 20)
4614 count_method_bb_distribution[3]++;
4615 else if (jd->basicblockcount <= 30)
4616 count_method_bb_distribution[4]++;
4617 else if (jd->basicblockcount <= 40)
4618 count_method_bb_distribution[5]++;
4619 else if (jd->basicblockcount <= 50)
4620 count_method_bb_distribution[6]++;
4621 else if (jd->basicblockcount <= 75)
4622 count_method_bb_distribution[7]++;
4624 count_method_bb_distribution[8]++;
4626 #endif /* defined(ENABLE_STATISTICS) */
4628 /* everything's ok *******************************************************/
4632 /* goto labels for throwing verifier exceptions **************************/
4634 #if defined(ENABLE_VERIFIER)
4636 throw_stack_underflow:
4637 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4640 throw_stack_overflow:
4641 exceptions_throw_verifyerror(m, "Stack size too large");
4644 throw_stack_type_error:
4645 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4648 throw_stack_category_error:
4649 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4656 /* functions for verbose stack analysis output ********************************/
4658 #if defined(STACK_VERBOSE)
4659 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4661 printf("%c", show_jit_type_letters[v->type]);
4662 if (v->type == TYPE_RET)
4663 printf("{L%03d}", v->vv.retaddr->nr);
4667 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4669 assert(index >= 0 && index < sd->vartop);
4670 stack_verbose_show_varinfo(sd, sd->var + index);
4674 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4678 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4680 for (i=0; i<bptr->indepth; ++i) {
4683 stack_verbose_show_variable(sd, bptr->invars[i]);
4688 printf("] inlocals [");
4689 if (bptr->inlocals) {
4690 for (i=0; i<sd->localcount; ++i) {
4693 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4698 printf("] out:%d [", bptr->outdepth);
4699 if (bptr->outvars) {
4700 for (i=0; i<bptr->outdepth; ++i) {
4703 stack_verbose_show_variable(sd, bptr->outvars[i]);
4711 printf(" (clone of L%03d)", bptr->original->nr);
4713 basicblock *b = bptr->copied_to;
4715 printf(" (copied to ");
4716 for (; b; b = b->copied_to)
4717 printf("L%03d ", b->nr);
4724 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4728 printf("======================================== STACK %sANALYSE BLOCK ",
4729 (reanalyse) ? "RE-" : "");
4730 stack_verbose_show_block(sd, sd->bptr);
4733 if (sd->handlers[0]) {
4734 printf("HANDLERS: ");
4735 for (i=0; sd->handlers[i]; ++i) {
4736 printf("L%03d ", sd->handlers[i]->handler->nr);
4744 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4746 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4747 stack_verbose_show_block(sd, sd->bptr);
4754 * These are local overrides for various environment variables in Emacs.
4755 * Please do not remove this and leave it at the end of the file, where
4756 * Emacs will automagically detect them.
4757 * ---------------------------------------------------------------------
4760 * indent-tabs-mode: t
4764 * vim:noexpandtab:sw=4:ts=4: