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 5790 2006-10-16 09:59:52Z edwin $
48 #include "mm/memory.h"
50 #include "native/native.h"
52 #include "toolbox/logging.h"
54 #include "vm/global.h"
55 #include "vm/builtin.h"
56 #include "vm/options.h"
57 #include "vm/resolve.h"
58 #include "vm/statistics.h"
59 #include "vm/stringlocal.h"
62 #include "vm/jit/abi.h"
63 #include "vm/jit/cfg.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/show.h"
68 #if defined(ENABLE_DISASSEMBLER)
69 # include "vm/jit/disass.h"
72 #include "vm/jit/jit.h"
73 #include "vm/jit/stack.h"
75 #if defined(ENABLE_SSA)
76 # include "vm/jit/optimizing/lsra.h"
77 # include "vm/jit/optimizing/ssa.h"
78 #elif defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
82 /*#define STACK_VERBOSE*/
85 /* macro for saving #ifdefs ***************************************************/
87 #if defined(ENABLE_STATISTICS)
88 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr) \
91 if (stackdepth >= 10) \
92 count_store_depth[10]++; \
94 count_store_depth[stackdepth]++; \
97 #else /* !defined(ENABLE_STATISTICS) */
98 #define STATISTICS_STACKDEPTH_DISTRIBUTION(distr)
102 #define MIN(a,b) (((a) < (b)) ? (a) : (b))
105 /* For returnAddresses we use a field of the typeinfo to store from which */
106 /* subroutine the returnAddress will return, if used. */
107 /* XXX It would be nicer to use typeinfo.typeclass, but the verifier seems */
108 /* to need it initialised to NULL. This should be investigated. */
110 #if defined(ENABLE_VERIFIER)
111 #define SBRSTART typeinfo.elementclass.any
115 /* stackdata_t *****************************************************************
117 This struct holds internal data during stack analysis.
119 *******************************************************************************/
121 typedef struct stackdata_t stackdata_t;
124 basicblock *bptr; /* the current basic block being analysed */
125 stackptr new; /* next free stackelement */
126 s4 vartop; /* next free variable index */
127 s4 localcount; /* number of locals (at the start of var) */
128 s4 varcount; /* total number of variables allocated */
129 varinfo *var; /* variable array (same as jd->var) */
130 methodinfo *m; /* the method being analysed */
131 jitdata *jd; /* current jitdata */
132 basicblock *last_real_block; /* the last block before the empty one */
133 bool repeat; /* if true, iterate the analysis again */
134 exception_entry **handlers; /* exception handlers for the current block */
135 exception_entry *extableend; /* points to the last exception entry */
136 stackelement exstack; /* instack for exception handlers */
140 /* macros for allocating/releasing variable indices *****************/
142 #define GET_NEW_INDEX(sd, new_varindex) \
144 assert((sd).vartop < (sd).varcount); \
145 (new_varindex) = ((sd).vartop)++; \
148 /* Not implemented now - could be used to reuse varindices. */
149 /* Pay attention to not release a localvar once implementing it! */
150 #define RELEASE_INDEX(sd, varindex)
152 #define GET_NEW_VAR(sd, newvarindex, newtype) \
154 GET_NEW_INDEX((sd), (newvarindex)); \
155 (sd).var[newvarindex].type = (newtype); \
159 /* macros for querying variable properties **************************/
161 #define IS_INOUT(sp) \
162 (sd.var[(sp)->varnum].flags & INOUT)
164 #define IS_PREALLOC(sp) \
165 (sd.var[(sp)->varnum].flags & PREALLOC)
167 #define IS_TEMPVAR(sp) \
168 ( ((sp)->varnum >= sd.localcount) \
169 && !(sd.var[(sp)->varnum].flags & (INOUT | PREALLOC)) )
172 #define IS_LOCALVAR_SD(sd, sp) \
173 ((sp)->varnum < (sd).localcount)
175 #define IS_LOCALVAR(sp) \
176 IS_LOCALVAR_SD(sd, (sp))
179 /* macros for setting variable properties ****************************/
181 #define SET_TEMPVAR(sp) \
183 if (IS_LOCALVAR((sp))) { \
184 stack_change_to_tempvar(&sd, (sp), iptr); \
186 sd.var[(sp)->varnum].flags &= ~(INOUT | PREALLOC); \
189 #define SET_PREALLOC(sp) \
191 assert(!IS_LOCALVAR((sp))); \
192 sd.var[(sp)->varnum].flags |= PREALLOC; \
196 /* macros for source operands ***************************************/
199 (iptr->s1.varindex = -1)
201 #define USE_S1(type1) \
204 CHECK_BASIC_TYPE(type1, curstack->type); \
205 iptr->s1.varindex = curstack->varnum; \
211 iptr->s1.varindex = curstack->varnum; \
214 #define USE_S1_S2(type1, type2) \
217 CHECK_BASIC_TYPE(type1, curstack->prev->type); \
218 CHECK_BASIC_TYPE(type2, curstack->type); \
219 iptr->sx.s23.s2.varindex = curstack->varnum; \
220 iptr->s1.varindex = curstack->prev->varnum; \
223 #define USE_S1_S2_ANY_ANY \
226 iptr->sx.s23.s2.varindex = curstack->varnum; \
227 iptr->s1.varindex = curstack->prev->varnum; \
230 #define USE_S1_S2_S3(type1, type2, type3) \
233 CHECK_BASIC_TYPE(type1, curstack->prev->prev->type); \
234 CHECK_BASIC_TYPE(type2, curstack->prev->type); \
235 CHECK_BASIC_TYPE(type3, curstack->type); \
236 iptr->sx.s23.s3.varindex = curstack->varnum; \
237 iptr->sx.s23.s2.varindex = curstack->prev->varnum; \
238 iptr->s1.varindex = curstack->prev->prev->varnum; \
241 /* The POPANY macro does NOT check stackdepth, or set stackdepth! */
244 if (curstack->varkind == UNDEFVAR) \
245 curstack->varkind = TEMPVAR; \
246 curstack = curstack->prev; \
249 #define POP_S1(type1) \
252 if (curstack->varkind == UNDEFVAR) \
253 curstack->varkind = TEMPVAR; \
254 curstack = curstack->prev; \
260 if (curstack->varkind == UNDEFVAR) \
261 curstack->varkind = TEMPVAR; \
262 curstack = curstack->prev; \
265 #define POP_S1_S2(type1, type2) \
267 USE_S1_S2(type1, type2); \
268 if (curstack->varkind == UNDEFVAR) \
269 curstack->varkind = TEMPVAR; \
270 if (curstack->prev->varkind == UNDEFVAR) \
271 curstack->prev->varkind = TEMPVAR; \
272 curstack = curstack->prev->prev; \
275 #define POP_S1_S2_ANY_ANY \
278 if (curstack->varkind == UNDEFVAR) \
279 curstack->varkind = TEMPVAR; \
280 if (curstack->prev->varkind == UNDEFVAR) \
281 curstack->prev->varkind = TEMPVAR; \
282 curstack = curstack->prev->prev; \
285 #define POP_S1_S2_S3(type1, type2, type3) \
287 USE_S1_S2_S3(type1, type2, type3); \
288 if (curstack->varkind == UNDEFVAR) \
289 curstack->varkind = TEMPVAR; \
290 if (curstack->prev->varkind == UNDEFVAR) \
291 curstack->prev->varkind = TEMPVAR; \
292 if (curstack->prev->prev->varkind == UNDEFVAR) \
293 curstack->prev->prev->varkind = TEMPVAR; \
294 curstack = curstack->prev->prev->prev; \
301 /* macros for setting the destination operand ***********************/
304 (iptr->dst.varindex = -1)
306 #define DST(typed, index) \
308 NEWSTACKn((typed),(index)); \
309 curstack->creator = iptr; \
310 iptr->dst.varindex = (index); \
313 #define DST_LOCALVAR(typed, index) \
315 NEWSTACK((typed), LOCALVAR, (index)); \
316 curstack->creator = iptr; \
317 iptr->dst.varindex = (index); \
321 /* macro for propagating constant values ****************************/
323 #if defined(ENABLE_VERIFIER)
324 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
326 (dv)->type = (sv)->type; \
327 (dv)->vv = (sv)->vv; \
328 (dv)->SBRSTART = (sv)->SBRSTART; \
331 #define COPY_VAL_AND_TYPE_VAR(sv, dv) \
333 (dv)->type = (sv)->type; \
334 (dv)->vv = (sv)->vv; \
338 #define COPY_VAL_AND_TYPE(sd, sindex, dindex) \
339 COPY_VAL_AND_TYPE_VAR((sd).var + (sindex), (sd).var + (dindex))
342 /* stack modelling macros *******************************************/
344 #define OP0_1(typed) \
347 GET_NEW_VAR(sd, new_index, (typed)); \
348 DST((typed), new_index); \
359 #define OP1_BRANCH(type1) \
365 #define OP1_1(type1, typed) \
368 GET_NEW_VAR(sd, new_index, (typed)); \
369 DST(typed, new_index); \
372 #define OP2_1(type1, type2, typed) \
374 POP_S1_S2(type1, type2); \
375 GET_NEW_VAR(sd, new_index, (typed)); \
376 DST(typed, new_index); \
391 #define OP1_0(type1) \
398 #define OP2_0(type1, type2) \
400 POP_S1_S2(type1, type2); \
405 #define OP2_BRANCH(type1, type2) \
407 POP_S1_S2(type1, type2); \
411 #define OP2_0_ANY_ANY \
418 #define OP3_0(type1, type2, type3) \
420 POP_S1_S2_S3(type1, type2, type3); \
425 #define LOAD(type1, index) \
427 DST_LOCALVAR(type1, index); \
431 #define STORE(type1, index) \
438 /* macros for DUP elimination ***************************************/
440 /* XXX replace NEW_VAR with NEW_INDEX */
441 #define DUP_SLOT(sp) \
443 GET_NEW_VAR(sd, new_index, (sp)->type); \
444 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
445 NEWSTACK((sp)->type, TEMPVAR, new_index); \
448 /* does not check input stackdepth */
449 #define MOVE_UP(sp) \
451 iptr->opc = ICMD_MOVE; \
452 iptr->s1.varindex = (sp)->varnum; \
454 curstack->creator = iptr; \
455 iptr->dst.varindex = curstack->varnum; \
459 /* does not check input stackdepth */
460 #define COPY_UP(sp) \
463 iptr->opc = ICMD_COPY; \
464 iptr->s1.varindex = (sp)->varnum; \
466 curstack->creator = iptr; \
467 iptr->dst.varindex = curstack->varnum; \
471 #define COPY_DOWN(s, d) \
474 iptr->opc = ICMD_COPY; \
475 iptr->s1.varindex = (s)->varnum; \
476 iptr->dst.varindex = (d)->varnum; \
477 (d)->creator = iptr; \
480 #define MOVE_TO_TEMP(sp) \
482 GET_NEW_INDEX(sd, new_index); \
483 iptr->opc = ICMD_MOVE; \
484 iptr->s1.varindex = (sp)->varnum; \
485 iptr->dst.varindex = new_index; \
486 COPY_VAL_AND_TYPE(sd, (sp)->varnum, new_index); \
487 (sp)->varnum = new_index; \
488 (sp)->varkind = TEMPVAR; \
491 /* macros for branching / reaching basic blocks *********************/
493 #define BRANCH_TARGET(bt, tempbptr) \
495 tempbptr = BLOCK_OF((bt).insindex); \
496 tempbptr = stack_mark_reached(&sd, tempbptr, curstack, \
498 if (tempbptr == NULL) \
500 (bt).block = tempbptr; \
503 #define BRANCH(tempbptr) \
504 BRANCH_TARGET(iptr->dst, tempbptr)
507 /* forward declarations *******************************************************/
509 static void stack_create_invars(stackdata_t *sd, basicblock *b,
510 stackptr curstack, int stackdepth);
511 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b);
513 #if defined(STACK_VERBOSE)
514 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v);
515 static void stack_verbose_show_variable(stackdata_t *sd, s4 index);
516 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr);
517 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse);
518 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend);
522 /* stack_init ******************************************************************
524 Initialized the stack analysis subsystem (called by jit_init).
526 *******************************************************************************/
528 bool stack_init(void)
534 /* stack_grow_variable_array ***************************************************
536 Grow the variable array so the given number of additional variables fits in.
539 sd...........stack analysis data
540 num..........number of additional variables
542 *******************************************************************************/
544 static void stack_grow_variable_array(stackdata_t *sd, s4 num)
553 /* XXX avoid too many reallocations */
554 newcount = sd->varcount + num;
556 sd->var = DMREALLOC(sd->var, varinfo, sd->varcount, newcount);
557 sd->varcount = newcount;
558 sd->jd->var = sd->var;
559 sd->jd->varcount = newcount;
563 /* stack_append_block **********************************************************
565 Append the given block after the last real block of the method (before
566 the pseudo-block at the end).
569 sd...........stack analysis data
570 b............the block to append
572 *******************************************************************************/
574 static void stack_append_block(stackdata_t *sd, basicblock *b)
576 #if defined(STACK_VERBOSE)
577 printf("APPENDING BLOCK L%0d\n", b->nr);
580 b->next = sd->last_real_block->next;
581 sd->last_real_block->next = b;
582 sd->last_real_block = b;
583 b->nr = sd->jd->basicblockcount++;
584 b->next->nr = b->nr + 1;
588 /* stack_clone_block ***********************************************************
590 Create a copy of the given block and insert it at the end of the method.
592 CAUTION: This function does not copy the any variables or the instruction
593 list. It _does_, however, reserve space for the block's invars in the
597 sd...........stack analysis data
598 b............the block to clone
601 a pointer to the copy
603 *******************************************************************************/
605 static basicblock * stack_clone_block(stackdata_t *sd, basicblock *b)
609 clone = DNEW(basicblock);
612 clone->iinstr = NULL;
613 clone->inlocals = NULL;
614 clone->invars = NULL;
616 clone->original = (b->original) ? b->original : b;
617 clone->copied_to = clone->original->copied_to;
618 clone->original->copied_to = clone;
620 clone->flags = BBREACHED;
622 stack_append_block(sd, clone);
624 /* allocate space for the invars of the clone */
626 stack_grow_variable_array(sd, b->indepth);
628 #if defined(STACK_VERBOSE)
629 printf("cloning block L%03d ------> L%03d\n", b->nr, clone->nr);
636 /* stack_create_invars *********************************************************
638 Create the invars for the given basic block. Also make a copy of the locals.
641 sd...........stack analysis data
642 b............block to create the invars for
643 curstack.....current stack top
644 stackdepth...current stack depth
646 This function creates STACKDEPTH invars and sets their types to the
647 types to the types of the corresponding slot in the current stack.
649 *******************************************************************************/
651 static void stack_create_invars(stackdata_t *sd, basicblock *b,
652 stackptr curstack, int stackdepth)
660 assert(sd->vartop + stackdepth <= sd->varcount);
662 b->indepth = stackdepth;
663 b->invars = DMNEW(s4, stackdepth);
665 /* allocate the variable indices */
666 index = (sd->vartop += stackdepth);
669 for (sp = curstack; i--; sp = sp->prev) {
670 b->invars[i] = --index;
671 dv = sd->var + index;
672 sv = sd->var + sp->varnum;
674 COPY_VAL_AND_TYPE_VAR(sv, dv);
677 /* copy the current state of the local variables */
678 /* (one extra local is needed by the verifier) */
680 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
682 for (i=0; i<sd->localcount; ++i)
687 /* stack_create_invars_from_outvars ********************************************
689 Create the invars for the given basic block. Also make a copy of the locals.
690 Types are propagated from the outvars of the current block.
693 sd...........stack analysis data
694 b............block to create the invars for
696 *******************************************************************************/
698 static void stack_create_invars_from_outvars(stackdata_t *sd, basicblock *b)
704 n = sd->bptr->outdepth;
705 assert(sd->vartop + n <= sd->varcount);
708 b->invars = DMNEW(s4, n);
711 dv = sd->var + sd->vartop;
713 /* allocate the invars */
715 for (i=0; i<n; ++i, ++dv) {
716 sv = sd->var + sd->bptr->outvars[i];
717 b->invars[i] = sd->vartop++;
719 COPY_VAL_AND_TYPE_VAR(sv, dv);
723 /* copy the current state of the local variables */
724 /* (one extra local is needed by the verifier) */
726 dv = DMNEW(varinfo, sd->localcount + VERIFIER_EXTRA_LOCALS);
728 for (i=0; i<sd->localcount; ++i)
733 /* stack_check_invars **********************************************************
735 Check the current stack against the invars of the given basic block.
736 Depth and types must match.
739 sd...........stack analysis data
740 b............block which invars to check against
741 curstack.....current stack top
742 stackdepth...current stack depth
746 NULL.........a VerifyError has been thrown
748 *******************************************************************************/
750 static basicblock * stack_check_invars(stackdata_t *sd, basicblock *b,
751 stackptr curstack, int stackdepth)
760 #if defined(STACK_VERBOSE)
761 printf("stack_check_invars(L%03d)\n", b->nr);
764 /* find original of b */
769 #if defined(STACK_VERBOSE)
770 printf("original is L%03d\n", orig->nr);
775 #if defined(ENABLE_VERIFIER)
776 if (i != stackdepth) {
777 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
785 #if defined(STACK_VERBOSE)
786 printf("checking against ");
787 stack_verbose_show_block(sd, b); printf("\n");
791 for (i = orig->indepth; i--; sp = sp->prev) {
792 dv = sd->var + b->invars[i];
793 sv = sd->var + sp->varnum;
795 #if defined(ENABLE_VERIFIER)
796 if (dv->type != sp->type) {
797 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
802 if (sp->type == TYPE_RET) {
803 #if defined(ENABLE_VERIFIER)
804 if (dv->SBRSTART != sv->SBRSTART) {
805 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
809 if (dv->vv.retaddr != sv->vv.retaddr) {
811 /* don't break! have to check the remaining stackslots */
817 for (i=0; i<sd->localcount; ++i) {
818 dv = b->inlocals + i;
820 if (sv->type == TYPE_RET && dv->type == TYPE_RET) {
822 #if defined(ENABLE_VERIFIER)
823 (sv->SBRSTART == dv->SBRSTART) &&
825 (sv->vv.retaddr != dv->vv.retaddr))
835 /* XXX mark mixed type variables void */
836 /* XXX cascading collapse? */
837 #if defined(ENABLE_VERIFIER)
839 for (i=0; i<sd->localcount; ++i) {
840 dv = b->inlocals + i;
842 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
843 && (sv->SBRSTART != dv->SBRSTART))
845 dv->type = TYPE_VOID;
846 if (b->flags >= BBFINISHED)
847 b->flags = BBTYPECHECK_REACHED;
848 sd->repeat = true; /* This is very rare, so just repeat */
854 #if defined(STACK_VERBOSE)
855 printf("------> using L%03d\n", b->nr);
859 } while ((b = b->copied_to) != NULL);
861 b = stack_clone_block(sd, orig);
865 stack_create_invars(sd, b, curstack, stackdepth);
870 /* stack_check_invars_from_outvars *********************************************
872 Check the outvars of the current block against the invars of the given block.
873 Depth and types must match.
876 sd...........stack analysis data
877 b............block which invars to check against
881 NULL.........a VerifyError has been thrown
883 *******************************************************************************/
885 static basicblock * stack_check_invars_from_outvars(stackdata_t *sd, basicblock *b)
893 #if defined(STACK_VERBOSE)
894 printf("stack_check_invars_from_outvars(L%03d)\n", b->nr);
897 /* find original of b */
902 #if defined(STACK_VERBOSE)
903 printf("original is L%03d\n", orig->nr);
907 n = sd->bptr->outdepth;
909 #if defined(ENABLE_VERIFIER)
911 exceptions_throw_verifyerror(sd->m, "Stack depth mismatch");
919 #if defined(STACK_VERBOSE)
920 printf("checking against ");
921 stack_verbose_show_block(sd, b); printf("\n");
925 dv = sd->var + b->invars[0];
927 for (i=0; i<n; ++i, ++dv) {
928 sv = sd->var + sd->bptr->outvars[i];
930 #if defined(ENABLE_VERIFIER)
931 if (sv->type != dv->type) {
932 exceptions_throw_verifyerror_for_stack(sd->m, dv->type);
937 if (dv->type == TYPE_RET) {
938 #if defined(ENABLE_VERIFIER)
939 if (sv->SBRSTART != dv->SBRSTART) {
940 exceptions_throw_verifyerror(sd->m, "Mismatched stack types");
944 if (sv->vv.retaddr != dv->vv.retaddr) {
946 /* don't break! have to check the remaining stackslots */
953 for (i=0; i<sd->localcount; ++i) {
954 dv = b->inlocals + i;
957 #if defined(ENABLE_VERIFIER)
958 (sv->SBRSTART == dv->SBRSTART) &&
960 (sv->type == TYPE_RET && dv->type == TYPE_RET))
962 if (sv->vv.retaddr != dv->vv.retaddr) {
971 /* XXX mark mixed type variables void */
972 /* XXX cascading collapse? */
973 #if defined(ENABLE_VERIFIER)
975 for (i=0; i<sd->localcount; ++i) {
976 dv = b->inlocals + i;
978 if ((sv->type == TYPE_RET && dv->type == TYPE_RET)
979 && (sv->SBRSTART != dv->SBRSTART))
981 dv->type = TYPE_VOID;
982 if (b->flags >= BBFINISHED)
983 b->flags = BBTYPECHECK_REACHED;
984 sd->repeat = true; /* This is very rare, so just repeat */
990 #if defined(STACK_VERBOSE)
991 printf("------> using L%03d\n", b->nr);
995 } while ((b = b->copied_to) != NULL);
997 b = stack_clone_block(sd, orig);
1001 stack_create_invars_from_outvars(sd, b);
1006 /* stack_create_instack ********************************************************
1008 Create the instack of the current basic block.
1011 sd...........stack analysis data
1014 the current stack top at the start of the basic block.
1016 *******************************************************************************/
1018 static stackptr stack_create_instack(stackdata_t *sd)
1024 if ((depth = sd->bptr->indepth) == 0)
1027 sp = (sd->new += depth);
1031 index = sd->bptr->invars[depth];
1033 sp->type = sd->var[index].type;
1037 sp->varkind = STACKVAR;
1041 /* return the top of the created stack */
1046 /* stack_mark_reached **********************************************************
1048 Mark the given block reached and propagate the current stack and locals to
1049 it. This function specializes the target block, if necessary, and returns
1050 a pointer to the specialized target.
1053 sd...........stack analysis data
1054 b............the block to reach
1055 curstack.....the current stack top
1056 stackdepth...the current stack depth
1059 a pointer to (a specialized version of) the target
1060 NULL.........a VerifyError has been thrown
1062 *******************************************************************************/
1064 static basicblock *stack_mark_reached(stackdata_t *sd, basicblock *b, stackptr curstack, int stackdepth)
1066 #if defined(STACK_VERBOSE)
1067 printf("stack_mark_reached(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1069 /* mark targets of backward branches */
1071 b->bitflags |= BBFLAG_REPLACEMENT;
1073 if (b->flags < BBREACHED) {
1074 /* b is reached for the first time. Create its invars. */
1076 #if defined(STACK_VERBOSE)
1077 printf("reached L%03d for the first time\n", b->nr);
1080 stack_create_invars(sd, b, curstack, stackdepth);
1082 b->flags = BBREACHED;
1087 /* b has been reached before. Check that its invars match. */
1089 return stack_check_invars(sd, b, curstack, stackdepth);
1094 /* stack_mark_reached_from_outvars *********************************************
1096 Mark the given block reached and propagate the outvars of the current block
1097 and the current locals to it. This function specializes the target block,
1098 if necessary, and returns a pointer to the specialized target.
1101 sd...........stack analysis data
1102 b............the block to reach
1105 a pointer to (a specialized version of) the target
1106 NULL.........a VerifyError has been thrown
1108 *******************************************************************************/
1110 static basicblock *stack_mark_reached_from_outvars(stackdata_t *sd, basicblock *b)
1112 #if defined(STACK_VERBOSE)
1113 printf("stack_mark_reached_from_outvars(L%03d from L%03d)\n", b->nr, sd->bptr->nr);
1115 /* mark targets of backward branches */
1117 b->bitflags |= BBFLAG_REPLACEMENT;
1119 if (b->flags < BBREACHED) {
1120 /* b is reached for the first time. Create its invars. */
1122 #if defined(STACK_VERBOSE)
1123 printf("reached L%03d for the first time\n", b->nr);
1126 stack_create_invars_from_outvars(sd, b);
1128 b->flags = BBREACHED;
1133 /* b has been reached before. Check that its invars match. */
1135 return stack_check_invars_from_outvars(sd, b);
1140 /* stack_reach_next_block ******************************************************
1142 Mark the following block reached and propagate the outvars of the current block
1143 and the current locals to it. This function specializes the target block,
1144 if necessary, and returns a pointer to the specialized target.
1147 sd...........stack analysis data
1150 a pointer to (a specialized version of) the following block
1151 NULL.........a VerifyError has been thrown
1153 *******************************************************************************/
1155 static bool stack_reach_next_block(stackdata_t *sd)
1160 tbptr = (sd->bptr->original) ? sd->bptr->original : sd->bptr;
1161 tbptr = stack_mark_reached_from_outvars(sd, tbptr->next);
1165 if (tbptr != sd->bptr->next) {
1166 #if defined(STACK_VERBOSE)
1167 printf("NEXT IS NON-CONSEQUITIVE L%03d\n", tbptr->nr);
1169 iptr = sd->bptr->iinstr + sd->bptr->icount - 1;
1170 assert(iptr->opc == ICMD_NOP);
1171 iptr->opc = ICMD_GOTO;
1172 iptr->dst.block = tbptr;
1174 if (tbptr->flags < BBFINISHED)
1175 sd->repeat = true; /* XXX check if we really need to repeat */
1182 /* stack_reach_handlers ********************************************************
1184 Reach the exception handlers for the current block.
1187 sd...........stack analysis data
1190 true.........everything ok
1191 false........a VerifyError has been thrown
1193 *******************************************************************************/
1195 static bool stack_reach_handlers(stackdata_t *sd)
1200 #if defined(STACK_VERBOSE)
1201 printf("reaching exception handlers...\n");
1204 for (i=0; sd->handlers[i]; ++i) {
1205 tbptr = sd->handlers[i]->handler;
1207 tbptr->type = BBTYPE_EXH;
1208 tbptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
1210 /* reach (and specialize) the handler block */
1212 tbptr = stack_mark_reached(sd, tbptr, &(sd->exstack), 1);
1217 sd->handlers[i]->handler = tbptr;
1224 /* stack_reanalyse_block ******************************************************
1226 Re-analyse the current block. This is called if either the block itself
1227 has already been analysed before, or the current block is a clone of an
1228 already analysed block, and this clone is reached for the first time.
1229 In the latter case, this function does all that is necessary for fully
1230 cloning the block (cloning the instruction list and variables, etc.).
1233 sd...........stack analysis data
1236 true.........everything ok
1237 false........a VerifyError has been thrown
1239 *******************************************************************************/
1241 #define RELOCATE(index) \
1243 if ((index) >= blockvarstart) \
1244 (index) += blockvarshift; \
1245 else if ((index) >= invarstart) \
1246 (index) += invarshift; \
1249 bool stack_reanalyse_block(stackdata_t *sd)
1261 branch_target_t *table;
1262 lookup_target_t *lookup;
1265 bool cloneinstructions;
1266 exception_entry *ex;
1268 #if defined(STACK_VERBOSE)
1269 stack_verbose_block_enter(sd, true);
1276 assert(orig != NULL);
1278 /* clone the instruction list */
1280 cloneinstructions = true;
1282 assert(orig->iinstr);
1284 iptr = DMNEW(instruction, len + 1);
1286 MCOPY(iptr, orig->iinstr, instruction, len);
1287 iptr[len].opc = ICMD_NOP;
1291 /* allocate space for the clone's block variables */
1293 stack_grow_variable_array(sd, orig->varcount);
1295 /* we already have the invars set */
1297 assert(b->indepth == orig->indepth);
1299 /* calculate relocation shifts for invars and block variables */
1301 if (orig->indepth) {
1302 invarstart = orig->invars[0];
1303 invarshift = b->invars[0] - invarstart;
1306 invarstart = INT_MAX;
1309 blockvarstart = orig->varstart;
1310 blockvarshift = sd->vartop - blockvarstart;
1312 /* copy block variables */
1314 b->varstart = sd->vartop;
1315 b->varcount = orig->varcount;
1316 sd->vartop += b->varcount;
1317 MCOPY(sd->var + b->varstart, sd->var + orig->varstart, varinfo, b->varcount);
1321 b->outdepth = orig->outdepth;
1322 b->outvars = DMNEW(s4, orig->outdepth);
1323 MCOPY(b->outvars, orig->outvars, s4, orig->outdepth);
1325 /* clone exception handlers */
1327 for (i=0; sd->handlers[i]; ++i) {
1328 ex = DNEW(exception_entry);
1329 ex->handler = sd->handlers[i]->handler;
1331 ex->end = b; /* XXX hack, see end of stack_analyse */
1332 ex->catchtype = sd->handlers[i]->catchtype;
1335 assert(sd->extableend->down == NULL);
1336 sd->extableend->down = ex;
1337 sd->extableend = ex;
1338 sd->jd->exceptiontablelength++;
1340 sd->handlers[i] = ex;
1344 cloneinstructions = false;
1347 invarstart = sd->vartop;
1348 blockvarstart = sd->vartop;
1353 /* find exception handlers for the cloned block */
1355 ex = sd->jd->exceptiontable;
1356 for (; ex != NULL; ex = ex->down) {
1357 /* XXX the cloned exception handlers have identical */
1358 /* start end end blocks. */
1359 if ((ex->start == b) && (ex->end == b)) {
1360 sd->handlers[len++] = ex;
1363 sd->handlers[len] = NULL;
1366 #if defined(STACK_VERBOSE)
1367 printf("invarstart = %d, blockvarstart = %d\n", invarstart, blockvarstart);
1368 printf("invarshift = %d, blockvarshift = %d\n", invarshift, blockvarshift);
1371 /* mark block as finished */
1373 b->flags = BBFINISHED;
1375 /* initialize locals at the start of this block */
1378 MCOPY(sd->var, b->inlocals, varinfo, sd->localcount);
1380 /* reach exception handlers for this block */
1382 if (!stack_reach_handlers(sd))
1385 superblockend = false;
1387 for (len = b->icount; len--; iptr++) {
1388 #if defined(STACK_VERBOSE)
1389 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1395 switch (iptr->opc) {
1397 j = iptr->s1.varindex;
1399 #if defined(ENABLE_VERIFIER)
1400 if (sd->var[j].type != TYPE_RET) {
1401 exceptions_throw_verifyerror(sd->m, "RET with non-returnAddress value");
1406 iptr->dst.block = stack_mark_reached_from_outvars(sd, sd->var[j].vv.retaddr);
1407 superblockend = true;
1411 iptr->sx.s23.s3.jsrtarget.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.jsrtarget.block);
1412 superblockend = true;
1416 superblockend = true;
1419 case ICMD_CHECKNULL:
1420 case ICMD_PUTSTATICCONST:
1426 case ICMD_INLINE_START:
1427 case ICMD_INLINE_END:
1428 case ICMD_INLINE_GOTO:
1432 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1433 superblockend = true;
1436 /* pop 0 push 1 const */
1445 /* pop 0 push 1 load */
1452 RELOCATE(iptr->dst.varindex);
1465 RELOCATE(iptr->sx.s23.s2.varindex);
1466 RELOCATE(iptr->s1.varindex);
1467 RELOCATE(iptr->dst.varindex);
1481 RELOCATE(iptr->sx.s23.s3.varindex);
1482 RELOCATE(iptr->sx.s23.s2.varindex);
1483 RELOCATE(iptr->s1.varindex);
1487 /* pop 1 push 0 store */
1494 RELOCATE(iptr->s1.varindex);
1496 j = iptr->dst.varindex;
1497 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, j);
1509 RELOCATE(iptr->s1.varindex);
1510 superblockend = true;
1513 case ICMD_PUTSTATIC:
1514 case ICMD_PUTFIELDCONST:
1517 RELOCATE(iptr->s1.varindex);
1520 /* pop 1 push 0 branch */
1523 case ICMD_IFNONNULL:
1538 RELOCATE(iptr->s1.varindex);
1539 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1542 /* pop 1 push 0 table branch */
1544 case ICMD_TABLESWITCH:
1545 i = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1 + 1;
1547 if (cloneinstructions) {
1548 table = DMNEW(branch_target_t, i);
1549 MCOPY(table, iptr->dst.table, branch_target_t, i);
1550 iptr->dst.table = table;
1553 table = iptr->dst.table;
1556 RELOCATE(iptr->s1.varindex);
1558 table->block = stack_mark_reached_from_outvars(sd, table->block);
1561 superblockend = true;
1564 case ICMD_LOOKUPSWITCH:
1565 i = iptr->sx.s23.s2.lookupcount;
1566 if (cloneinstructions) {
1567 lookup = DMNEW(lookup_target_t, i);
1568 MCOPY(lookup, iptr->dst.lookup, lookup_target_t, i);
1569 iptr->dst.lookup = lookup;
1572 lookup = iptr->dst.lookup;
1574 RELOCATE(iptr->s1.varindex);
1576 lookup->target.block = stack_mark_reached_from_outvars(sd, lookup->target.block);
1579 iptr->sx.s23.s3.lookupdefault.block = stack_mark_reached_from_outvars(sd, iptr->sx.s23.s3.lookupdefault.block);
1580 superblockend = true;
1583 case ICMD_MONITORENTER:
1584 case ICMD_MONITOREXIT:
1585 RELOCATE(iptr->s1.varindex);
1589 /* pop 2 push 0 branch */
1591 case ICMD_IF_ICMPEQ:
1592 case ICMD_IF_ICMPNE:
1593 case ICMD_IF_ICMPLT:
1594 case ICMD_IF_ICMPGE:
1595 case ICMD_IF_ICMPGT:
1596 case ICMD_IF_ICMPLE:
1598 case ICMD_IF_LCMPEQ:
1599 case ICMD_IF_LCMPNE:
1600 case ICMD_IF_LCMPLT:
1601 case ICMD_IF_LCMPGE:
1602 case ICMD_IF_LCMPGT:
1603 case ICMD_IF_LCMPLE:
1605 case ICMD_IF_FCMPEQ:
1606 case ICMD_IF_FCMPNE:
1608 case ICMD_IF_FCMPL_LT:
1609 case ICMD_IF_FCMPL_GE:
1610 case ICMD_IF_FCMPL_GT:
1611 case ICMD_IF_FCMPL_LE:
1613 case ICMD_IF_FCMPG_LT:
1614 case ICMD_IF_FCMPG_GE:
1615 case ICMD_IF_FCMPG_GT:
1616 case ICMD_IF_FCMPG_LE:
1618 case ICMD_IF_DCMPEQ:
1619 case ICMD_IF_DCMPNE:
1621 case ICMD_IF_DCMPL_LT:
1622 case ICMD_IF_DCMPL_GE:
1623 case ICMD_IF_DCMPL_GT:
1624 case ICMD_IF_DCMPL_LE:
1626 case ICMD_IF_DCMPG_LT:
1627 case ICMD_IF_DCMPG_GE:
1628 case ICMD_IF_DCMPG_GT:
1629 case ICMD_IF_DCMPG_LE:
1631 case ICMD_IF_ACMPEQ:
1632 case ICMD_IF_ACMPNE:
1633 RELOCATE(iptr->sx.s23.s2.varindex);
1634 RELOCATE(iptr->s1.varindex);
1635 iptr->dst.block = stack_mark_reached_from_outvars(sd, iptr->dst.block);
1641 case ICMD_IASTORECONST:
1642 case ICMD_LASTORECONST:
1643 case ICMD_AASTORECONST:
1644 case ICMD_BASTORECONST:
1645 case ICMD_CASTORECONST:
1646 case ICMD_SASTORECONST:
1649 RELOCATE(iptr->sx.s23.s2.varindex);
1650 RELOCATE(iptr->s1.varindex);
1653 /* pop 0 push 1 copy */
1657 RELOCATE(iptr->dst.varindex);
1658 RELOCATE(iptr->s1.varindex);
1659 COPY_VAL_AND_TYPE(*sd, iptr->s1.varindex, iptr->dst.varindex);
1702 RELOCATE(iptr->sx.s23.s2.varindex);
1703 RELOCATE(iptr->s1.varindex);
1704 RELOCATE(iptr->dst.varindex);
1709 case ICMD_CHECKCAST:
1710 case ICMD_ARRAYLENGTH:
1711 case ICMD_INSTANCEOF:
1713 case ICMD_ANEWARRAY:
1716 case ICMD_IADDCONST:
1717 case ICMD_ISUBCONST:
1718 case ICMD_IMULCONST:
1722 case ICMD_IANDCONST:
1724 case ICMD_IXORCONST:
1725 case ICMD_ISHLCONST:
1726 case ICMD_ISHRCONST:
1727 case ICMD_IUSHRCONST:
1728 case ICMD_LADDCONST:
1729 case ICMD_LSUBCONST:
1730 case ICMD_LMULCONST:
1734 case ICMD_LANDCONST:
1736 case ICMD_LXORCONST:
1737 case ICMD_LSHLCONST:
1738 case ICMD_LSHRCONST:
1739 case ICMD_LUSHRCONST:
1743 case ICMD_INT2SHORT:
1759 RELOCATE(iptr->s1.varindex);
1760 RELOCATE(iptr->dst.varindex);
1765 case ICMD_GETSTATIC:
1768 RELOCATE(iptr->dst.varindex);
1771 /* pop many push any */
1773 case ICMD_INVOKESTATIC:
1774 case ICMD_INVOKESPECIAL:
1775 case ICMD_INVOKEVIRTUAL:
1776 case ICMD_INVOKEINTERFACE:
1778 case ICMD_MULTIANEWARRAY:
1779 i = iptr->s1.argcount;
1780 if (cloneinstructions) {
1781 argp = DMNEW(s4, i);
1782 MCOPY(argp, iptr->sx.s23.s2.args, s4, i);
1783 iptr->sx.s23.s2.args = argp;
1786 argp = iptr->sx.s23.s2.args;
1794 RELOCATE(iptr->dst.varindex);
1799 new_internalerror("Unknown ICMD %d during stack re-analysis",
1804 #if defined(STACK_VERBOSE)
1805 show_icmd(sd->jd, iptr, false, SHOW_STACK);
1810 /* relocate outvars */
1812 for (i=0; i<b->outdepth; ++i) {
1813 RELOCATE(b->outvars[i]);
1816 #if defined(STACK_VERBOSE)
1817 stack_verbose_block_exit(sd, superblockend);
1820 /* propagate to the next block */
1823 if (!stack_reach_next_block(sd))
1830 /* stack_change_to_tempvar *****************************************************
1832 Change the given stackslot to a TEMPVAR. This includes creating a new
1833 temporary variable and changing the dst.varindex of the creator of the
1834 stacklot to the new variable index. If this stackslot has been passed
1835 through ICMDs between the point of its creation and the current point,
1836 then the variable index is also changed in these ICMDs.
1839 sd...........stack analysis data
1840 sp...........stackslot to change
1841 ilimit.......instruction up to which to look for ICMDs passing-through
1842 the stackslot (exclusive). This may point exactly after the
1843 last instruction, in which case the search is done to the
1846 *******************************************************************************/
1848 static void stack_change_to_tempvar(stackdata_t *sd, stackptr sp,
1849 instruction *ilimit)
1856 oldindex = sp->varnum;
1858 /* create a new temporary variable */
1860 GET_NEW_VAR(*sd, newindex, sp->type);
1862 sd->var[newindex].flags = sp->flags;
1864 /* change the stackslot */
1866 sp->varnum = newindex;
1867 sp->varkind = TEMPVAR;
1869 /* change the dst.varindex of the stackslot's creator */
1872 sp->creator->dst.varindex = newindex;
1874 /* handle ICMDs this stackslot passed through, if any */
1876 if (sp->flags & PASSTHROUGH) {
1877 iptr = (sp->creator) ? (sp->creator + 1) : sd->bptr->iinstr;
1879 /* asser that the limit point to an ICMD, or after the last one */
1880 assert(ilimit >= sd->bptr->iinstr);
1881 assert(ilimit <= sd->bptr->iinstr + sd->bptr->icount);
1883 for (; iptr < ilimit; ++iptr) {
1884 switch (iptr->opc) {
1885 case ICMD_INVOKESTATIC:
1886 case ICMD_INVOKESPECIAL:
1887 case ICMD_INVOKEVIRTUAL:
1888 case ICMD_INVOKEINTERFACE:
1891 for (i=0; i<iptr->s1.argcount; ++i)
1892 if (iptr->sx.s23.s2.args[i] == oldindex) {
1893 iptr->sx.s23.s2.args[i] = newindex;
1896 /* IMPORTANT: If any ICMD sets the PASSTHROUGH flag of a */
1897 /* stackslot, it must be added in this switch! */
1904 /* stack_analyse ***************************************************************
1906 Analyse_stack uses the intermediate code created by parse.c to
1907 build a model of the JVM operand stack for the current method.
1909 The following checks are performed:
1910 - check for operand stack underflow (before each instruction)
1911 - check for operand stack overflow (after[1] each instruction)
1912 - check for matching stack depth at merging points
1913 - check for matching basic types[2] at merging points
1914 - check basic types for instruction input (except for BUILTIN*
1915 opcodes, INVOKE* opcodes and MULTIANEWARRAY)
1917 [1]) Checking this after the instruction should be ok. parse.c
1918 counts the number of required stack slots in such a way that it is
1919 only vital that we don't exceed `maxstack` at basic block
1922 [2]) 'basic types' means the distinction between INT, LONG, FLOAT,
1923 DOUBLE and ADDRESS types. Subtypes of INT and different ADDRESS
1924 types are not discerned.
1926 *******************************************************************************/
1928 bool stack_analyse(jitdata *jd)
1930 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;
1950 exception_entry *ex;
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 */
1979 #if defined(ENABLE_SSA)
1983 /* initialize the stackdata_t struct */
1987 sd.varcount = jd->varcount;
1988 sd.vartop = jd->vartop;
1989 sd.localcount = jd->localcount;
1991 sd.handlers = DMNEW(exception_entry *, jd->exceptiontablelength + 1);
1993 /* prepare the variable for exception handler stacks */
1994 /* (has been reserved by STACK_EXTRA_VARS, or VERIFIER_EXTRA_VARS) */
1996 sd.exstack.type = TYPE_ADR;
1997 sd.exstack.prev = NULL;
1998 sd.exstack.varnum = sd.localcount;
1999 sd.var[sd.exstack.varnum].type = TYPE_ADR;
2001 #if defined(ENABLE_LSRA)
2002 m->maxlifetimes = 0;
2005 #if defined(ENABLE_STATISTICS)
2006 iteration_count = 0;
2009 /* find the last real basic block */
2011 sd.last_real_block = NULL;
2012 tbptr = jd->basicblocks;
2013 while (tbptr->next) {
2014 sd.last_real_block = tbptr;
2015 tbptr = tbptr->next;
2017 assert(sd.last_real_block);
2019 /* find the last exception handler */
2021 if (jd->exceptiontablelength)
2022 sd.extableend = jd->exceptiontable + jd->exceptiontablelength - 1;
2024 sd.extableend = NULL;
2026 /* init jd->interface_map */
2028 jd->interface_map = DMNEW(interface_info, m->maxstack * 5);
2029 for (i = 0; i < m->maxstack * 5; i++)
2030 jd->interface_map[i].flags = UNUSED;
2032 last_store_boundary = DMNEW(stackptr, m->maxlocals);
2034 /* initialize flags and invars (none) of first block */
2036 jd->basicblocks[0].flags = BBREACHED;
2037 jd->basicblocks[0].invars = NULL;
2038 jd->basicblocks[0].indepth = 0;
2039 jd->basicblocks[0].inlocals =
2040 DMNEW(varinfo, jd->localcount + VERIFIER_EXTRA_LOCALS);
2041 MCOPY(jd->basicblocks[0].inlocals, jd->var, varinfo,
2042 jd->localcount + VERIFIER_EXTRA_LOCALS);
2044 /* stack analysis loop (until fixpoint reached) **************************/
2047 #if defined(ENABLE_STATISTICS)
2051 /* initialize loop over basic blocks */
2053 sd.bptr = jd->basicblocks;
2054 superblockend = true;
2056 curstack = NULL; stackdepth = 0;
2059 /* iterate over basic blocks *****************************************/
2061 for (; sd.bptr; sd.bptr = sd.bptr->next) {
2063 if (sd.bptr->flags == BBDELETED) {
2064 /* This block has been deleted - do nothing. */
2069 if (sd.bptr->flags == BBTYPECHECK_REACHED) {
2070 /* re-analyse a block because its input changed */
2071 if (!stack_reanalyse_block(&sd))
2073 superblockend = true; /* XXX */
2077 if (superblockend && (sd.bptr->flags < BBREACHED)) {
2078 /* This block has not been reached so far, and we */
2079 /* don't fall into it, so we'll have to iterate again. */
2085 if (sd.bptr->flags > BBREACHED) {
2086 /* This block is already finished. */
2088 superblockend = true;
2092 if (sd.bptr->original && sd.bptr->original->flags < BBFINISHED) {
2093 /* This block is a clone and the original has not been */
2094 /* analysed, yet. Analyse it on the next iteration. */
2097 /* XXX superblockend? */
2101 /* This block has to be analysed now. */
2103 /* XXX The rest of this block is still indented one level too */
2104 /* much in order to avoid a giant diff by changing that. */
2106 /* We know that sd.bptr->flags == BBREACHED. */
2107 /* This block has been reached before. */
2109 assert(sd.bptr->flags == BBREACHED);
2110 stackdepth = sd.bptr->indepth;
2112 /* find exception handlers for this block */
2114 /* determine the active exception handlers for this block */
2115 /* XXX could use a faster algorithm with sorted lists or */
2118 original = (sd.bptr->original) ? sd.bptr->original : sd.bptr;
2121 ex = jd->exceptiontable;
2122 for (; ex != NULL; ex = ex->down) {
2123 if ((ex->start <= original) && (ex->end > original)) {
2124 sd.handlers[len++] = ex;
2127 sd.handlers[len] = NULL;
2130 /* reanalyse cloned block */
2132 if (sd.bptr->original) {
2133 if (!stack_reanalyse_block(&sd))
2138 /* reset the new pointer for allocating stackslots */
2142 /* create the instack of this block */
2144 curstack = stack_create_instack(&sd);
2146 /* initialize locals at the start of this block */
2148 if (sd.bptr->inlocals)
2149 MCOPY(sd.var, sd.bptr->inlocals, varinfo, sd.localcount);
2151 /* set up local variables for analyzing this block */
2154 superblockend = false;
2155 len = sd.bptr->icount;
2156 iptr = sd.bptr->iinstr;
2157 b_index = sd.bptr - jd->basicblocks;
2159 /* mark the block as analysed */
2161 sd.bptr->flags = BBFINISHED;
2163 /* reset variables for dependency checking */
2165 coalescing_boundary = sd.new;
2166 for( i = 0; i < m->maxlocals; i++)
2167 last_store_boundary[i] = sd.new;
2169 /* remember the start of this block's variables */
2171 sd.bptr->varstart = sd.vartop;
2173 #if defined(STACK_VERBOSE)
2174 stack_verbose_block_enter(&sd, false);
2177 /* reach exception handlers for this block */
2179 if (!stack_reach_handlers(&sd))
2182 /* iterate over ICMDs ****************************************/
2184 while (--len >= 0) {
2186 #if defined(STACK_VERBOSE)
2187 show_icmd(jd, iptr, false, SHOW_PARSE); printf("\n");
2188 for( copy = curstack; copy; copy = copy->prev ) {
2189 printf("%2d(%d", copy->varnum, copy->type);
2192 if (IS_PREALLOC(copy))
2199 /* fetch the current opcode */
2203 /* automatically replace some ICMDs with builtins */
2205 #if defined(USEBUILTINTABLE)
2206 bte = builtintable_get_automatic(opcode);
2208 if (bte && bte->opcode == opcode) {
2209 iptr->opc = ICMD_BUILTIN;
2210 iptr->flags.bits = 0;
2211 iptr->sx.s23.s3.bte = bte;
2212 /* iptr->line is already set */
2213 jd->isleafmethod = false;
2216 #endif /* defined(USEBUILTINTABLE) */
2218 /* main opcode switch *************************************/
2230 case ICMD_CHECKNULL:
2231 coalescing_boundary = sd.new;
2232 COUNT(count_check_null);
2235 iptr->dst.varindex = iptr->s1.varindex;
2239 j = iptr->s1.varindex =
2240 jd->local_map[iptr->s1.varindex * 5 + TYPE_ADR];
2242 #if defined(ENABLE_VERIFIER)
2243 if (sd.var[j].type != TYPE_RET) {
2244 exceptions_throw_verifyerror(m, "RET with non-returnAddress value");
2251 iptr->dst.block = stack_mark_reached(&sd, sd.var[j].vv.retaddr, curstack, stackdepth);
2252 superblockend = true;
2256 COUNT(count_pcmd_return);
2259 superblockend = true;
2263 /* pop 0 push 1 const */
2265 /************************** ICONST OPTIMIZATIONS **************************/
2268 COUNT(count_pcmd_load);
2272 switch (iptr[1].opc) {
2274 iptr->opc = ICMD_IADDCONST;
2278 iptr[1].opc = ICMD_NOP;
2279 OP1_1(TYPE_INT, TYPE_INT);
2280 COUNT(count_pcmd_op);
2284 iptr->opc = ICMD_ISUBCONST;
2285 goto icmd_iconst_tail;
2286 #if SUPPORT_CONST_MUL
2288 iptr->opc = ICMD_IMULCONST;
2289 goto icmd_iconst_tail;
2290 #else /* SUPPORT_CONST_MUL */
2292 if (iptr->sx.val.i == 0x00000002)
2294 else if (iptr->sx.val.i == 0x00000004)
2296 else if (iptr->sx.val.i == 0x00000008)
2298 else if (iptr->sx.val.i == 0x00000010)
2300 else if (iptr->sx.val.i == 0x00000020)
2302 else if (iptr->sx.val.i == 0x00000040)
2304 else if (iptr->sx.val.i == 0x00000080)
2306 else if (iptr->sx.val.i == 0x00000100)
2308 else if (iptr->sx.val.i == 0x00000200)
2310 else if (iptr->sx.val.i == 0x00000400)
2311 iptr->sx.val.i = 10;
2312 else if (iptr->sx.val.i == 0x00000800)
2313 iptr->sx.val.i = 11;
2314 else if (iptr->sx.val.i == 0x00001000)
2315 iptr->sx.val.i = 12;
2316 else if (iptr->sx.val.i == 0x00002000)
2317 iptr->sx.val.i = 13;
2318 else if (iptr->sx.val.i == 0x00004000)
2319 iptr->sx.val.i = 14;
2320 else if (iptr->sx.val.i == 0x00008000)
2321 iptr->sx.val.i = 15;
2322 else if (iptr->sx.val.i == 0x00010000)
2323 iptr->sx.val.i = 16;
2324 else if (iptr->sx.val.i == 0x00020000)
2325 iptr->sx.val.i = 17;
2326 else if (iptr->sx.val.i == 0x00040000)
2327 iptr->sx.val.i = 18;
2328 else if (iptr->sx.val.i == 0x00080000)
2329 iptr->sx.val.i = 19;
2330 else if (iptr->sx.val.i == 0x00100000)
2331 iptr->sx.val.i = 20;
2332 else if (iptr->sx.val.i == 0x00200000)
2333 iptr->sx.val.i = 21;
2334 else if (iptr->sx.val.i == 0x00400000)
2335 iptr->sx.val.i = 22;
2336 else if (iptr->sx.val.i == 0x00800000)
2337 iptr->sx.val.i = 23;
2338 else if (iptr->sx.val.i == 0x01000000)
2339 iptr->sx.val.i = 24;
2340 else if (iptr->sx.val.i == 0x02000000)
2341 iptr->sx.val.i = 25;
2342 else if (iptr->sx.val.i == 0x04000000)
2343 iptr->sx.val.i = 26;
2344 else if (iptr->sx.val.i == 0x08000000)
2345 iptr->sx.val.i = 27;
2346 else if (iptr->sx.val.i == 0x10000000)
2347 iptr->sx.val.i = 28;
2348 else if (iptr->sx.val.i == 0x20000000)
2349 iptr->sx.val.i = 29;
2350 else if (iptr->sx.val.i == 0x40000000)
2351 iptr->sx.val.i = 30;
2352 else if (iptr->sx.val.i == 0x80000000)
2353 iptr->sx.val.i = 31;
2357 iptr->opc = ICMD_IMULPOW2;
2358 goto icmd_iconst_tail;
2359 #endif /* SUPPORT_CONST_MUL */
2361 if (iptr->sx.val.i == 0x00000002)
2363 else if (iptr->sx.val.i == 0x00000004)
2365 else if (iptr->sx.val.i == 0x00000008)
2367 else if (iptr->sx.val.i == 0x00000010)
2369 else if (iptr->sx.val.i == 0x00000020)
2371 else if (iptr->sx.val.i == 0x00000040)
2373 else if (iptr->sx.val.i == 0x00000080)
2375 else if (iptr->sx.val.i == 0x00000100)
2377 else if (iptr->sx.val.i == 0x00000200)
2379 else if (iptr->sx.val.i == 0x00000400)
2380 iptr->sx.val.i = 10;
2381 else if (iptr->sx.val.i == 0x00000800)
2382 iptr->sx.val.i = 11;
2383 else if (iptr->sx.val.i == 0x00001000)
2384 iptr->sx.val.i = 12;
2385 else if (iptr->sx.val.i == 0x00002000)
2386 iptr->sx.val.i = 13;
2387 else if (iptr->sx.val.i == 0x00004000)
2388 iptr->sx.val.i = 14;
2389 else if (iptr->sx.val.i == 0x00008000)
2390 iptr->sx.val.i = 15;
2391 else if (iptr->sx.val.i == 0x00010000)
2392 iptr->sx.val.i = 16;
2393 else if (iptr->sx.val.i == 0x00020000)
2394 iptr->sx.val.i = 17;
2395 else if (iptr->sx.val.i == 0x00040000)
2396 iptr->sx.val.i = 18;
2397 else if (iptr->sx.val.i == 0x00080000)
2398 iptr->sx.val.i = 19;
2399 else if (iptr->sx.val.i == 0x00100000)
2400 iptr->sx.val.i = 20;
2401 else if (iptr->sx.val.i == 0x00200000)
2402 iptr->sx.val.i = 21;
2403 else if (iptr->sx.val.i == 0x00400000)
2404 iptr->sx.val.i = 22;
2405 else if (iptr->sx.val.i == 0x00800000)
2406 iptr->sx.val.i = 23;
2407 else if (iptr->sx.val.i == 0x01000000)
2408 iptr->sx.val.i = 24;
2409 else if (iptr->sx.val.i == 0x02000000)
2410 iptr->sx.val.i = 25;
2411 else if (iptr->sx.val.i == 0x04000000)
2412 iptr->sx.val.i = 26;
2413 else if (iptr->sx.val.i == 0x08000000)
2414 iptr->sx.val.i = 27;
2415 else if (iptr->sx.val.i == 0x10000000)
2416 iptr->sx.val.i = 28;
2417 else if (iptr->sx.val.i == 0x20000000)
2418 iptr->sx.val.i = 29;
2419 else if (iptr->sx.val.i == 0x40000000)
2420 iptr->sx.val.i = 30;
2421 else if (iptr->sx.val.i == 0x80000000)
2422 iptr->sx.val.i = 31;
2426 iptr->opc = ICMD_IDIVPOW2;
2427 goto icmd_iconst_tail;
2430 /*log_text("stack.c: ICMD_ICONST/ICMD_IREM");*/
2431 if ((iptr->sx.val.i == 0x00000002) ||
2432 (iptr->sx.val.i == 0x00000004) ||
2433 (iptr->sx.val.i == 0x00000008) ||
2434 (iptr->sx.val.i == 0x00000010) ||
2435 (iptr->sx.val.i == 0x00000020) ||
2436 (iptr->sx.val.i == 0x00000040) ||
2437 (iptr->sx.val.i == 0x00000080) ||
2438 (iptr->sx.val.i == 0x00000100) ||
2439 (iptr->sx.val.i == 0x00000200) ||
2440 (iptr->sx.val.i == 0x00000400) ||
2441 (iptr->sx.val.i == 0x00000800) ||
2442 (iptr->sx.val.i == 0x00001000) ||
2443 (iptr->sx.val.i == 0x00002000) ||
2444 (iptr->sx.val.i == 0x00004000) ||
2445 (iptr->sx.val.i == 0x00008000) ||
2446 (iptr->sx.val.i == 0x00010000) ||
2447 (iptr->sx.val.i == 0x00020000) ||
2448 (iptr->sx.val.i == 0x00040000) ||
2449 (iptr->sx.val.i == 0x00080000) ||
2450 (iptr->sx.val.i == 0x00100000) ||
2451 (iptr->sx.val.i == 0x00200000) ||
2452 (iptr->sx.val.i == 0x00400000) ||
2453 (iptr->sx.val.i == 0x00800000) ||
2454 (iptr->sx.val.i == 0x01000000) ||
2455 (iptr->sx.val.i == 0x02000000) ||
2456 (iptr->sx.val.i == 0x04000000) ||
2457 (iptr->sx.val.i == 0x08000000) ||
2458 (iptr->sx.val.i == 0x10000000) ||
2459 (iptr->sx.val.i == 0x20000000) ||
2460 (iptr->sx.val.i == 0x40000000) ||
2461 (iptr->sx.val.i == 0x80000000))
2463 iptr->opc = ICMD_IREMPOW2;
2464 iptr->sx.val.i -= 1;
2465 goto icmd_iconst_tail;
2468 #if SUPPORT_CONST_LOGICAL
2470 iptr->opc = ICMD_IANDCONST;
2471 goto icmd_iconst_tail;
2474 iptr->opc = ICMD_IORCONST;
2475 goto icmd_iconst_tail;
2478 iptr->opc = ICMD_IXORCONST;
2479 goto icmd_iconst_tail;
2481 #endif /* SUPPORT_CONST_LOGICAL */
2483 iptr->opc = ICMD_ISHLCONST;
2484 goto icmd_iconst_tail;
2487 iptr->opc = ICMD_ISHRCONST;
2488 goto icmd_iconst_tail;
2491 iptr->opc = ICMD_IUSHRCONST;
2492 goto icmd_iconst_tail;
2493 #if SUPPORT_LONG_SHIFT
2495 iptr->opc = ICMD_LSHLCONST;
2496 goto icmd_lconst_tail;
2499 iptr->opc = ICMD_LSHRCONST;
2500 goto icmd_lconst_tail;
2503 iptr->opc = ICMD_LUSHRCONST;
2504 goto icmd_lconst_tail;
2505 #endif /* SUPPORT_LONG_SHIFT */
2506 case ICMD_IF_ICMPEQ:
2507 iptr[1].opc = ICMD_IFEQ;
2511 /* set the constant for the following icmd */
2512 iptr[1].sx.val.i = iptr->sx.val.i;
2514 /* this instruction becomes a nop */
2515 iptr->opc = ICMD_NOP;
2518 case ICMD_IF_ICMPLT:
2519 iptr[1].opc = ICMD_IFLT;
2520 goto icmd_if_icmp_tail;
2522 case ICMD_IF_ICMPLE:
2523 iptr[1].opc = ICMD_IFLE;
2524 goto icmd_if_icmp_tail;
2526 case ICMD_IF_ICMPNE:
2527 iptr[1].opc = ICMD_IFNE;
2528 goto icmd_if_icmp_tail;
2530 case ICMD_IF_ICMPGT:
2531 iptr[1].opc = ICMD_IFGT;
2532 goto icmd_if_icmp_tail;
2534 case ICMD_IF_ICMPGE:
2535 iptr[1].opc = ICMD_IFGE;
2536 goto icmd_if_icmp_tail;
2538 #if SUPPORT_CONST_STORE
2543 # if SUPPORT_CONST_STORE_ZERO_ONLY
2544 if (iptr->sx.val.i != 0)
2547 switch (iptr[1].opc) {
2549 iptr->opc = ICMD_IASTORECONST;
2550 iptr->flags.bits |= INS_FLAG_CHECK;
2553 iptr->opc = ICMD_BASTORECONST;
2554 iptr->flags.bits |= INS_FLAG_CHECK;
2557 iptr->opc = ICMD_CASTORECONST;
2558 iptr->flags.bits |= INS_FLAG_CHECK;
2561 iptr->opc = ICMD_SASTORECONST;
2562 iptr->flags.bits |= INS_FLAG_CHECK;
2566 iptr[1].opc = ICMD_NOP;
2568 /* copy the constant to s3 */
2569 /* XXX constval -> astoreconstval? */
2570 iptr->sx.s23.s3.constval = iptr->sx.val.i;
2571 OP2_0(TYPE_ADR, TYPE_INT);
2572 COUNT(count_pcmd_op);
2575 case ICMD_PUTSTATIC:
2577 # if SUPPORT_CONST_STORE_ZERO_ONLY
2578 if (iptr->sx.val.i != 0)
2581 /* XXX check field type? */
2583 /* copy the constant to s2 */
2584 /* XXX constval -> fieldconstval? */
2585 iptr->sx.s23.s2.constval = iptr->sx.val.i;
2588 /* set the field reference (s3) */
2589 if (iptr[1].flags.bits & INS_FLAG_UNRESOLVED) {
2590 iptr->sx.s23.s3.uf = iptr[1].sx.s23.s3.uf;
2591 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
2594 iptr->sx.s23.s3.fmiref = iptr[1].sx.s23.s3.fmiref;
2597 switch (iptr[1].opc) {
2598 case ICMD_PUTSTATIC:
2599 iptr->opc = ICMD_PUTSTATICCONST;
2603 iptr->opc = ICMD_PUTFIELDCONST;
2608 iptr[1].opc = ICMD_NOP;
2609 COUNT(count_pcmd_op);
2611 #endif /* SUPPORT_CONST_STORE */
2617 /* if we get here, the ICONST has been optimized */
2621 /* normal case of an unoptimized ICONST */
2625 /************************** LCONST OPTIMIZATIONS **************************/
2628 COUNT(count_pcmd_load);
2632 /* switch depending on the following instruction */
2634 switch (iptr[1].opc) {
2635 #if SUPPORT_LONG_ADD
2637 iptr->opc = ICMD_LADDCONST;
2641 /* instruction of type LONG -> LONG */
2642 iptr[1].opc = ICMD_NOP;
2643 OP1_1(TYPE_LNG, TYPE_LNG);
2644 COUNT(count_pcmd_op);
2648 iptr->opc = ICMD_LSUBCONST;
2649 goto icmd_lconst_tail;
2651 #endif /* SUPPORT_LONG_ADD */
2652 #if SUPPORT_LONG_MUL && SUPPORT_CONST_MUL
2654 iptr->opc = ICMD_LMULCONST;
2655 goto icmd_lconst_tail;
2656 #else /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2657 # if SUPPORT_LONG_SHIFT
2659 if (iptr->sx.val.l == 0x00000002)
2661 else if (iptr->sx.val.l == 0x00000004)
2663 else if (iptr->sx.val.l == 0x00000008)
2665 else if (iptr->sx.val.l == 0x00000010)
2667 else if (iptr->sx.val.l == 0x00000020)
2669 else if (iptr->sx.val.l == 0x00000040)
2671 else if (iptr->sx.val.l == 0x00000080)
2673 else if (iptr->sx.val.l == 0x00000100)
2675 else if (iptr->sx.val.l == 0x00000200)
2677 else if (iptr->sx.val.l == 0x00000400)
2678 iptr->sx.val.i = 10;
2679 else if (iptr->sx.val.l == 0x00000800)
2680 iptr->sx.val.i = 11;
2681 else if (iptr->sx.val.l == 0x00001000)
2682 iptr->sx.val.i = 12;
2683 else if (iptr->sx.val.l == 0x00002000)
2684 iptr->sx.val.i = 13;
2685 else if (iptr->sx.val.l == 0x00004000)
2686 iptr->sx.val.i = 14;
2687 else if (iptr->sx.val.l == 0x00008000)
2688 iptr->sx.val.i = 15;
2689 else if (iptr->sx.val.l == 0x00010000)
2690 iptr->sx.val.i = 16;
2691 else if (iptr->sx.val.l == 0x00020000)
2692 iptr->sx.val.i = 17;
2693 else if (iptr->sx.val.l == 0x00040000)
2694 iptr->sx.val.i = 18;
2695 else if (iptr->sx.val.l == 0x00080000)
2696 iptr->sx.val.i = 19;
2697 else if (iptr->sx.val.l == 0x00100000)
2698 iptr->sx.val.i = 20;
2699 else if (iptr->sx.val.l == 0x00200000)
2700 iptr->sx.val.i = 21;
2701 else if (iptr->sx.val.l == 0x00400000)
2702 iptr->sx.val.i = 22;
2703 else if (iptr->sx.val.l == 0x00800000)
2704 iptr->sx.val.i = 23;
2705 else if (iptr->sx.val.l == 0x01000000)
2706 iptr->sx.val.i = 24;
2707 else if (iptr->sx.val.l == 0x02000000)
2708 iptr->sx.val.i = 25;
2709 else if (iptr->sx.val.l == 0x04000000)
2710 iptr->sx.val.i = 26;
2711 else if (iptr->sx.val.l == 0x08000000)
2712 iptr->sx.val.i = 27;
2713 else if (iptr->sx.val.l == 0x10000000)
2714 iptr->sx.val.i = 28;
2715 else if (iptr->sx.val.l == 0x20000000)
2716 iptr->sx.val.i = 29;
2717 else if (iptr->sx.val.l == 0x40000000)
2718 iptr->sx.val.i = 30;
2719 else if (iptr->sx.val.l == 0x80000000)
2720 iptr->sx.val.i = 31;
2724 iptr->opc = ICMD_LMULPOW2;
2725 goto icmd_lconst_tail;
2726 # endif /* SUPPORT_LONG_SHIFT */
2727 #endif /* SUPPORT_LONG_MUL && SUPPORT_CONST_MUL */
2728 #if SUPPORT_LONG_DIV_POW2
2730 if (iptr->sx.val.l == 0x00000002)
2732 else if (iptr->sx.val.l == 0x00000004)
2734 else if (iptr->sx.val.l == 0x00000008)
2736 else if (iptr->sx.val.l == 0x00000010)
2738 else if (iptr->sx.val.l == 0x00000020)
2740 else if (iptr->sx.val.l == 0x00000040)
2742 else if (iptr->sx.val.l == 0x00000080)
2744 else if (iptr->sx.val.l == 0x00000100)
2746 else if (iptr->sx.val.l == 0x00000200)
2748 else if (iptr->sx.val.l == 0x00000400)
2749 iptr->sx.val.i = 10;
2750 else if (iptr->sx.val.l == 0x00000800)
2751 iptr->sx.val.i = 11;
2752 else if (iptr->sx.val.l == 0x00001000)
2753 iptr->sx.val.i = 12;
2754 else if (iptr->sx.val.l == 0x00002000)
2755 iptr->sx.val.i = 13;
2756 else if (iptr->sx.val.l == 0x00004000)
2757 iptr->sx.val.i = 14;
2758 else if (iptr->sx.val.l == 0x00008000)
2759 iptr->sx.val.i = 15;
2760 else if (iptr->sx.val.l == 0x00010000)
2761 iptr->sx.val.i = 16;
2762 else if (iptr->sx.val.l == 0x00020000)
2763 iptr->sx.val.i = 17;
2764 else if (iptr->sx.val.l == 0x00040000)
2765 iptr->sx.val.i = 18;
2766 else if (iptr->sx.val.l == 0x00080000)
2767 iptr->sx.val.i = 19;
2768 else if (iptr->sx.val.l == 0x00100000)
2769 iptr->sx.val.i = 20;
2770 else if (iptr->sx.val.l == 0x00200000)
2771 iptr->sx.val.i = 21;
2772 else if (iptr->sx.val.l == 0x00400000)
2773 iptr->sx.val.i = 22;
2774 else if (iptr->sx.val.l == 0x00800000)
2775 iptr->sx.val.i = 23;
2776 else if (iptr->sx.val.l == 0x01000000)
2777 iptr->sx.val.i = 24;
2778 else if (iptr->sx.val.l == 0x02000000)
2779 iptr->sx.val.i = 25;
2780 else if (iptr->sx.val.l == 0x04000000)
2781 iptr->sx.val.i = 26;
2782 else if (iptr->sx.val.l == 0x08000000)
2783 iptr->sx.val.i = 27;
2784 else if (iptr->sx.val.l == 0x10000000)
2785 iptr->sx.val.i = 28;
2786 else if (iptr->sx.val.l == 0x20000000)
2787 iptr->sx.val.i = 29;
2788 else if (iptr->sx.val.l == 0x40000000)
2789 iptr->sx.val.i = 30;
2790 else if (iptr->sx.val.l == 0x80000000)
2791 iptr->sx.val.i = 31;
2795 iptr->opc = ICMD_LDIVPOW2;
2796 goto icmd_lconst_tail;
2797 #endif /* SUPPORT_LONG_DIV_POW2 */
2799 #if SUPPORT_LONG_REM_POW2
2801 if ((iptr->sx.val.l == 0x00000002) ||
2802 (iptr->sx.val.l == 0x00000004) ||
2803 (iptr->sx.val.l == 0x00000008) ||
2804 (iptr->sx.val.l == 0x00000010) ||
2805 (iptr->sx.val.l == 0x00000020) ||
2806 (iptr->sx.val.l == 0x00000040) ||
2807 (iptr->sx.val.l == 0x00000080) ||
2808 (iptr->sx.val.l == 0x00000100) ||
2809 (iptr->sx.val.l == 0x00000200) ||
2810 (iptr->sx.val.l == 0x00000400) ||
2811 (iptr->sx.val.l == 0x00000800) ||
2812 (iptr->sx.val.l == 0x00001000) ||
2813 (iptr->sx.val.l == 0x00002000) ||
2814 (iptr->sx.val.l == 0x00004000) ||
2815 (iptr->sx.val.l == 0x00008000) ||
2816 (iptr->sx.val.l == 0x00010000) ||
2817 (iptr->sx.val.l == 0x00020000) ||
2818 (iptr->sx.val.l == 0x00040000) ||
2819 (iptr->sx.val.l == 0x00080000) ||
2820 (iptr->sx.val.l == 0x00100000) ||
2821 (iptr->sx.val.l == 0x00200000) ||
2822 (iptr->sx.val.l == 0x00400000) ||
2823 (iptr->sx.val.l == 0x00800000) ||
2824 (iptr->sx.val.l == 0x01000000) ||
2825 (iptr->sx.val.l == 0x02000000) ||
2826 (iptr->sx.val.l == 0x04000000) ||
2827 (iptr->sx.val.l == 0x08000000) ||
2828 (iptr->sx.val.l == 0x10000000) ||
2829 (iptr->sx.val.l == 0x20000000) ||
2830 (iptr->sx.val.l == 0x40000000) ||
2831 (iptr->sx.val.l == 0x80000000))
2833 iptr->opc = ICMD_LREMPOW2;
2834 iptr->sx.val.l -= 1;
2835 goto icmd_lconst_tail;
2838 #endif /* SUPPORT_LONG_REM_POW2 */
2840 #if SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL
2843 iptr->opc = ICMD_LANDCONST;
2844 goto icmd_lconst_tail;
2847 iptr->opc = ICMD_LORCONST;
2848 goto icmd_lconst_tail;
2851 iptr->opc = ICMD_LXORCONST;
2852 goto icmd_lconst_tail;
2853 #endif /* SUPPORT_LONG_LOGICAL && SUPPORT_CONST_LOGICAL */
2855 #if SUPPORT_LONG_CMP_CONST
2857 if ((len <= 1) || (iptr[2].sx.val.i != 0))
2860 /* switch on the instruction after LCONST - LCMP */
2862 switch (iptr[2].opc) {
2864 iptr->opc = ICMD_IF_LEQ;
2867 icmd_lconst_lcmp_tail:
2868 /* convert LCONST, LCMP, IFXX to IF_LXX */
2869 iptr->dst.insindex = iptr[2].dst.insindex;
2870 iptr[1].opc = ICMD_NOP;
2871 iptr[2].opc = ICMD_NOP;
2873 OP1_BRANCH(TYPE_LNG);
2875 COUNT(count_pcmd_bra);
2876 COUNT(count_pcmd_op);
2880 iptr->opc = ICMD_IF_LNE;
2881 goto icmd_lconst_lcmp_tail;
2884 iptr->opc = ICMD_IF_LLT;
2885 goto icmd_lconst_lcmp_tail;
2888 iptr->opc = ICMD_IF_LGT;
2889 goto icmd_lconst_lcmp_tail;
2892 iptr->opc = ICMD_IF_LLE;
2893 goto icmd_lconst_lcmp_tail;
2896 iptr->opc = ICMD_IF_LGE;
2897 goto icmd_lconst_lcmp_tail;
2901 } /* end switch on opcode after LCONST - LCMP */
2903 #endif /* SUPPORT_LONG_CMP_CONST */
2905 #if SUPPORT_CONST_STORE
2907 # if SUPPORT_CONST_STORE_ZERO_ONLY
2908 if (iptr->sx.val.l != 0)
2911 #if SIZEOF_VOID_P == 4
2912 /* the constant must fit into a ptrint */
2913 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2916 /* move the constant to s3 */
2917 iptr->sx.s23.s3.constval = iptr->sx.val.l;
2919 iptr->opc = ICMD_LASTORECONST;
2920 iptr->flags.bits |= INS_FLAG_CHECK;
2921 OP2_0(TYPE_ADR, TYPE_INT);
2923 iptr[1].opc = ICMD_NOP;
2924 COUNT(count_pcmd_op);
2927 case ICMD_PUTSTATIC:
2929 # if SUPPORT_CONST_STORE_ZERO_ONLY
2930 if (iptr->sx.val.l != 0)
2933 #if SIZEOF_VOID_P == 4
2934 /* the constant must fit into a ptrint */
2935 if (iptr->sx.val.l < -0x80000000L || iptr->sx.val.l >= 0x80000000L)
2938 /* XXX check field type? */
2940 /* copy the constant to s2 */
2941 /* XXX constval -> fieldconstval? */
2942 iptr->sx.s23.s2.constval = iptr->sx.val.l;
2946 #endif /* SUPPORT_CONST_STORE */
2950 } /* end switch opcode after LCONST */
2952 /* if we get here, the LCONST has been optimized */
2956 /* the normal case of an unoptimized LCONST */
2960 /************************ END OF LCONST OPTIMIZATIONS *********************/
2963 COUNT(count_pcmd_load);
2968 COUNT(count_pcmd_load);
2972 /************************** ACONST OPTIMIZATIONS **************************/
2975 coalescing_boundary = sd.new;
2976 COUNT(count_pcmd_load);
2977 #if SUPPORT_CONST_STORE
2978 /* We can only optimize if the ACONST is resolved
2979 * and there is an instruction after it. */
2981 if ((len == 0) || (iptr->flags.bits & INS_FLAG_UNRESOLVED))
2984 switch (iptr[1].opc) {
2986 /* We can only optimize for NULL values
2987 * here because otherwise a checkcast is
2989 if (iptr->sx.val.anyptr != NULL)
2992 /* copy the constant (NULL) to s3 */
2993 iptr->sx.s23.s3.constval = 0;
2994 iptr->opc = ICMD_AASTORECONST;
2995 iptr->flags.bits |= INS_FLAG_CHECK;
2996 OP2_0(TYPE_ADR, TYPE_INT);
2998 iptr[1].opc = ICMD_NOP;
2999 COUNT(count_pcmd_op);
3002 case ICMD_PUTSTATIC:
3004 # if SUPPORT_CONST_STORE_ZERO_ONLY
3005 if (iptr->sx.val.anyptr != NULL)
3008 /* XXX check field type? */
3009 /* copy the constant to s2 */
3010 /* XXX constval -> fieldconstval? */
3011 iptr->sx.s23.s2.constval = (ptrint) iptr->sx.val.anyptr;
3019 /* if we get here the ACONST has been optimized */
3023 #endif /* SUPPORT_CONST_STORE */
3028 /* pop 0 push 1 load */
3035 COUNT(count_load_instruction);
3036 i = opcode - ICMD_ILOAD; /* type */
3038 j = iptr->s1.varindex =
3039 jd->local_map[iptr->s1.varindex * 5 + i];
3041 #if defined(ENABLE_VERIFIER)
3042 if (sd.var[j].type == TYPE_RET) {
3043 exceptions_throw_verifyerror(m, "forbidden load of returnAddress");
3048 #if defined(ENABLE_SSA)
3050 GET_NEW_VAR(sd, new_index, i);
3067 coalescing_boundary = sd.new;
3068 iptr->flags.bits |= INS_FLAG_CHECK;
3069 COUNT(count_check_null);
3070 COUNT(count_check_bound);
3071 COUNT(count_pcmd_mem);
3072 OP2_1(TYPE_ADR, TYPE_INT, opcode - ICMD_IALOAD);
3079 coalescing_boundary = sd.new;
3080 iptr->flags.bits |= INS_FLAG_CHECK;
3081 COUNT(count_check_null);
3082 COUNT(count_check_bound);
3083 COUNT(count_pcmd_mem);
3084 OP2_1(TYPE_ADR, TYPE_INT, TYPE_INT);
3087 /* pop 0 push 0 iinc */
3090 STATISTICS_STACKDEPTH_DISTRIBUTION(count_store_depth);
3091 #if defined(ENABLE_SSA)
3094 jd->local_map[iptr->s1.varindex * 5 +TYPE_INT];
3098 last_store_boundary[iptr->s1.varindex] = sd.new;
3101 jd->local_map[iptr->s1.varindex * 5 + TYPE_INT];
3106 if ((copy->varkind == LOCALVAR) &&
3107 (copy->varnum == iptr->s1.varindex))
3109 assert(IS_LOCALVAR(copy));
3115 #if defined(ENABLE_SSA)
3119 iptr->dst.varindex = iptr->s1.varindex;
3122 /* pop 1 push 0 store */
3131 i = opcode - ICMD_ISTORE; /* type */
3132 javaindex = iptr->dst.varindex;
3133 j = iptr->dst.varindex =
3134 jd->local_map[javaindex * 5 + i];
3136 COPY_VAL_AND_TYPE(sd, curstack->varnum, j);
3138 #if defined(ENABLE_STATISTICS)
3141 i = sd.new - curstack;
3143 count_store_length[20]++;
3145 count_store_length[i]++;
3148 count_store_depth[10]++;
3150 count_store_depth[i]++;
3154 #if defined(ENABLE_SSA)
3157 /* check for conflicts as described in Figure 5.2 */
3159 copy = curstack->prev;
3162 if ((copy->varkind == LOCALVAR) &&
3163 (copy->varnum == j))
3165 copy->varkind = TEMPVAR;
3166 assert(IS_LOCALVAR(copy));
3173 /* if the variable is already coalesced, don't bother */
3175 /* We do not need to check against INOUT, as invars */
3176 /* are always before the coalescing boundary. */
3178 if (curstack->varkind == LOCALVAR)
3181 /* there is no STORE Lj while curstack is live */
3183 if (curstack < last_store_boundary[javaindex])
3184 goto assume_conflict;
3186 /* curstack must be after the coalescing boundary */
3188 if (curstack < coalescing_boundary)
3189 goto assume_conflict;
3191 /* there is no DEF LOCALVAR(j) while curstack is live */
3193 copy = sd.new; /* most recent stackslot created + 1 */
3194 while (--copy > curstack) {
3195 if (copy->varkind == LOCALVAR && copy->varnum == j)
3196 goto assume_conflict;
3199 /* coalesce the temporary variable with Lj */
3200 assert((curstack->varkind == TEMPVAR)
3201 || (curstack->varkind == UNDEFVAR));
3202 assert(!IS_LOCALVAR(curstack)); /* XXX correct? */
3203 assert(!IS_INOUT(curstack));
3204 assert(!IS_PREALLOC(curstack));
3206 assert(curstack->creator);
3207 assert(curstack->creator->dst.varindex == curstack->varnum);
3208 assert(!(curstack->flags & PASSTHROUGH));
3209 RELEASE_INDEX(sd, curstack);
3210 curstack->varkind = LOCALVAR;
3211 curstack->varnum = j;
3212 curstack->creator->dst.varindex = j;
3215 /* revert the coalescing, if it has been done earlier */
3217 if ((curstack->varkind == LOCALVAR)
3218 && (curstack->varnum == j))
3220 assert(IS_LOCALVAR(curstack));
3221 SET_TEMPVAR(curstack);
3224 /* remember the stack boundary at this store */
3226 last_store_boundary[javaindex] = sd.new;
3227 #if defined(ENABLE_SSA)
3228 } /* if (ls != NULL) */
3231 if (opcode == ICMD_ASTORE && curstack->type == TYPE_RET)
3234 STORE(opcode - ICMD_ISTORE, j);
3240 coalescing_boundary = sd.new;
3241 iptr->flags.bits |= INS_FLAG_CHECK;
3242 COUNT(count_check_null);
3243 COUNT(count_check_bound);
3244 COUNT(count_pcmd_mem);
3246 bte = builtintable_get_internal(BUILTIN_canstore);
3249 if (md->memuse > rd->memuse)
3250 rd->memuse = md->memuse;
3251 if (md->argintreguse > rd->argintreguse)
3252 rd->argintreguse = md->argintreguse;
3253 /* XXX non-leaf method? */
3255 /* make all stack variables saved */
3259 sd.var[copy->varnum].flags |= SAVEDVAR;
3260 /* in case copy->varnum is/will be a LOCALVAR */
3261 /* once and set back to a non LOCALVAR */
3262 /* the correct SAVEDVAR flag has to be */
3263 /* remembered in copy->flags, too */
3264 copy->flags |= SAVEDVAR;
3268 OP3_0(TYPE_ADR, TYPE_INT, TYPE_ADR);
3275 coalescing_boundary = sd.new;
3276 iptr->flags.bits |= INS_FLAG_CHECK;
3277 COUNT(count_check_null);
3278 COUNT(count_check_bound);
3279 COUNT(count_pcmd_mem);
3280 OP3_0(TYPE_ADR, TYPE_INT, opcode - ICMD_IASTORE);
3287 coalescing_boundary = sd.new;
3288 iptr->flags.bits |= INS_FLAG_CHECK;
3289 COUNT(count_check_null);
3290 COUNT(count_check_bound);
3291 COUNT(count_pcmd_mem);
3292 OP3_0(TYPE_ADR, TYPE_INT, TYPE_INT);
3298 #ifdef ENABLE_VERIFIER
3301 if (IS_2_WORD_TYPE(curstack->type))
3302 goto throw_stack_category_error;
3313 coalescing_boundary = sd.new;
3314 /* Assert here that no LOCAL or INOUTS get */
3315 /* preallocated, since tha macros are not */
3316 /* available in md-abi.c! */
3317 if (IS_TEMPVAR(curstack))
3318 md_return_alloc(jd, curstack);
3319 COUNT(count_pcmd_return);
3320 OP1_0(opcode - ICMD_IRETURN);
3321 superblockend = true;
3325 coalescing_boundary = sd.new;
3326 COUNT(count_check_null);
3328 curstack = NULL; stackdepth = 0;
3329 superblockend = true;
3332 case ICMD_PUTSTATIC:
3333 coalescing_boundary = sd.new;
3334 COUNT(count_pcmd_mem);
3335 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3336 OP1_0(fmiref->parseddesc.fd->type);
3339 /* pop 1 push 0 branch */
3342 case ICMD_IFNONNULL:
3343 COUNT(count_pcmd_bra);
3344 OP1_BRANCH(TYPE_ADR);
3354 COUNT(count_pcmd_bra);
3355 /* iptr->sx.val.i is set implicitly in parse by
3356 clearing the memory or from IF_ICMPxx
3359 OP1_BRANCH(TYPE_INT);
3360 /* iptr->sx.val.i = 0; */
3364 /* pop 0 push 0 branch */
3367 COUNT(count_pcmd_bra);
3370 superblockend = true;
3373 /* pop 1 push 0 table branch */
3375 case ICMD_TABLESWITCH:
3376 COUNT(count_pcmd_table);
3377 OP1_BRANCH(TYPE_INT);
3379 table = iptr->dst.table;
3380 BRANCH_TARGET(*table, tbptr);
3383 i = iptr->sx.s23.s3.tablehigh
3384 - iptr->sx.s23.s2.tablelow + 1;
3387 BRANCH_TARGET(*table, tbptr);
3390 superblockend = true;
3393 /* pop 1 push 0 table branch */
3395 case ICMD_LOOKUPSWITCH:
3396 COUNT(count_pcmd_table);
3397 OP1_BRANCH(TYPE_INT);
3399 BRANCH_TARGET(iptr->sx.s23.s3.lookupdefault, tbptr);
3401 lookup = iptr->dst.lookup;
3403 i = iptr->sx.s23.s2.lookupcount;
3406 BRANCH_TARGET(lookup->target, tbptr);
3409 superblockend = true;
3412 case ICMD_MONITORENTER:
3413 case ICMD_MONITOREXIT:
3414 coalescing_boundary = sd.new;
3415 COUNT(count_check_null);
3419 /* pop 2 push 0 branch */
3421 case ICMD_IF_ICMPEQ:
3422 case ICMD_IF_ICMPNE:
3423 case ICMD_IF_ICMPLT:
3424 case ICMD_IF_ICMPGE:
3425 case ICMD_IF_ICMPGT:
3426 case ICMD_IF_ICMPLE:
3427 COUNT(count_pcmd_bra);
3428 OP2_BRANCH(TYPE_INT, TYPE_INT);
3432 case ICMD_IF_ACMPEQ:
3433 case ICMD_IF_ACMPNE:
3434 COUNT(count_pcmd_bra);
3435 OP2_BRANCH(TYPE_ADR, TYPE_ADR);
3442 coalescing_boundary = sd.new;
3443 COUNT(count_check_null);
3444 COUNT(count_pcmd_mem);
3445 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
3446 OP2_0(TYPE_ADR, fmiref->parseddesc.fd->type);
3451 if (!IS_2_WORD_TYPE(curstack->type)) {
3453 #ifdef ENABLE_VERIFIER
3456 if (IS_2_WORD_TYPE(curstack->prev->type))
3457 goto throw_stack_category_error;
3460 OP2_0_ANY_ANY; /* pop two slots */
3463 iptr->opc = ICMD_POP;
3464 OP1_0_ANY; /* pop one (two-word) slot */
3468 /* pop 0 push 1 dup */
3471 #ifdef ENABLE_VERIFIER
3474 if (IS_2_WORD_TYPE(curstack->type))
3475 goto throw_stack_category_error;
3478 COUNT(count_dup_instruction);
3484 coalescing_boundary = sd.new - 1;
3489 if (IS_2_WORD_TYPE(curstack->type)) {
3491 iptr->opc = ICMD_DUP;
3496 /* ..., ????, cat1 */
3497 #ifdef ENABLE_VERIFIER
3499 if (IS_2_WORD_TYPE(curstack->prev->type))
3500 goto throw_stack_category_error;
3503 src1 = curstack->prev;
3506 COPY_UP(src1); iptr++; len--;
3509 coalescing_boundary = sd.new;
3513 /* pop 2 push 3 dup */
3516 #ifdef ENABLE_VERIFIER
3519 if (IS_2_WORD_TYPE(curstack->type) ||
3520 IS_2_WORD_TYPE(curstack->prev->type))
3521 goto throw_stack_category_error;
3526 src1 = curstack->prev;
3531 /* move non-temporary sources out of the way */
3532 if (!IS_TEMPVAR(src2)) {
3533 MOVE_TO_TEMP(src2); iptr++; len--;
3536 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3538 MOVE_UP(src1); iptr++; len--;
3539 MOVE_UP(src2); iptr++; len--;
3541 COPY_DOWN(curstack, dst1);
3543 coalescing_boundary = sd.new;
3548 if (IS_2_WORD_TYPE(curstack->type)) {
3549 /* ..., ????, cat2 */
3550 #ifdef ENABLE_VERIFIER
3552 if (IS_2_WORD_TYPE(curstack->prev->type))
3553 goto throw_stack_category_error;
3556 iptr->opc = ICMD_DUP_X1;
3560 /* ..., ????, cat1 */
3561 #ifdef ENABLE_VERIFIER
3564 if (IS_2_WORD_TYPE(curstack->prev->type)
3565 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3566 goto throw_stack_category_error;
3571 src1 = curstack->prev->prev;
3572 src2 = curstack->prev;
3574 POPANY; POPANY; POPANY;
3577 /* move non-temporary sources out of the way */
3578 if (!IS_TEMPVAR(src2)) {
3579 MOVE_TO_TEMP(src2); iptr++; len--;
3581 if (!IS_TEMPVAR(src3)) {
3582 MOVE_TO_TEMP(src3); iptr++; len--;
3585 DUP_SLOT(src2); dst1 = curstack; stackdepth++;
3586 DUP_SLOT(src3); dst2 = curstack; stackdepth++;
3588 MOVE_UP(src1); iptr++; len--;
3589 MOVE_UP(src2); iptr++; len--;
3590 MOVE_UP(src3); iptr++; len--;
3592 COPY_DOWN(curstack, dst2); iptr++; len--;
3593 COPY_DOWN(curstack->prev, dst1);
3595 coalescing_boundary = sd.new;
3599 /* pop 3 push 4 dup */
3603 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3604 /* ..., cat2, ???? */
3605 #ifdef ENABLE_VERIFIER
3607 if (IS_2_WORD_TYPE(curstack->type))
3608 goto throw_stack_category_error;
3611 iptr->opc = ICMD_DUP_X1;
3615 /* ..., cat1, ???? */
3616 #ifdef ENABLE_VERIFIER
3619 if (IS_2_WORD_TYPE(curstack->type)
3620 || IS_2_WORD_TYPE(curstack->prev->prev->type))
3621 goto throw_stack_category_error;
3625 src1 = curstack->prev->prev;
3626 src2 = curstack->prev;
3628 POPANY; POPANY; POPANY;
3631 /* move non-temporary sources out of the way */
3632 if (!IS_TEMPVAR(src2)) {
3633 MOVE_TO_TEMP(src2); iptr++; len--;
3635 if (!IS_TEMPVAR(src3)) {
3636 MOVE_TO_TEMP(src3); iptr++; len--;
3639 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3641 MOVE_UP(src1); iptr++; len--;
3642 MOVE_UP(src2); iptr++; len--;
3643 MOVE_UP(src3); iptr++; len--;
3645 COPY_DOWN(curstack, dst1);
3647 coalescing_boundary = sd.new;
3653 if (IS_2_WORD_TYPE(curstack->type)) {
3654 /* ..., ????, cat2 */
3655 if (IS_2_WORD_TYPE(curstack->prev->type)) {
3656 /* ..., cat2, cat2 */
3657 iptr->opc = ICMD_DUP_X1;
3661 /* ..., cat1, cat2 */
3662 #ifdef ENABLE_VERIFIER
3665 if (IS_2_WORD_TYPE(curstack->prev->prev->type))
3666 goto throw_stack_category_error;
3669 iptr->opc = ICMD_DUP_X2;
3675 /* ..., ????, ????, cat1 */
3677 if (IS_2_WORD_TYPE(curstack->prev->prev->type)) {
3678 /* ..., cat2, ????, cat1 */
3679 #ifdef ENABLE_VERIFIER
3681 if (IS_2_WORD_TYPE(curstack->prev->type))
3682 goto throw_stack_category_error;
3685 iptr->opc = ICMD_DUP2_X1;
3689 /* ..., cat1, ????, cat1 */
3690 #ifdef ENABLE_VERIFIER
3693 if (IS_2_WORD_TYPE(curstack->prev->type)
3694 || IS_2_WORD_TYPE(curstack->prev->prev->prev->type))
3695 goto throw_stack_category_error;
3699 src1 = curstack->prev->prev->prev;
3700 src2 = curstack->prev->prev;
3701 src3 = curstack->prev;
3703 POPANY; POPANY; POPANY; POPANY;
3706 /* move non-temporary sources out of the way */
3707 if (!IS_TEMPVAR(src2)) {
3708 MOVE_TO_TEMP(src2); iptr++; len--;
3710 if (!IS_TEMPVAR(src3)) {
3711 MOVE_TO_TEMP(src3); iptr++; len--;
3713 if (!IS_TEMPVAR(src4)) {
3714 MOVE_TO_TEMP(src4); iptr++; len--;
3717 DUP_SLOT(src3); dst1 = curstack; stackdepth++;
3718 DUP_SLOT(src4); dst2 = curstack; stackdepth++;
3720 MOVE_UP(src1); iptr++; len--;
3721 MOVE_UP(src2); iptr++; len--;
3722 MOVE_UP(src3); iptr++; len--;
3723 MOVE_UP(src4); iptr++; len--;
3725 COPY_DOWN(curstack, dst2); iptr++; len--;
3726 COPY_DOWN(curstack->prev, dst1);
3728 coalescing_boundary = sd.new;
3732 /* pop 2 push 2 swap */
3735 #ifdef ENABLE_VERIFIER
3738 if (IS_2_WORD_TYPE(curstack->type)
3739 || IS_2_WORD_TYPE(curstack->prev->type))
3740 goto throw_stack_category_error;
3744 src1 = curstack->prev;
3749 /* move non-temporary sources out of the way */
3750 if (!IS_TEMPVAR(src1)) {
3751 MOVE_TO_TEMP(src1); iptr++; len--;
3754 MOVE_UP(src2); iptr++; len--;
3757 coalescing_boundary = sd.new;
3764 coalescing_boundary = sd.new;
3765 #if !SUPPORT_DIVISION
3766 bte = iptr->sx.s23.s3.bte;
3769 if (md->memuse > rd->memuse)
3770 rd->memuse = md->memuse;
3771 if (md->argintreguse > rd->argintreguse)
3772 rd->argintreguse = md->argintreguse;
3774 /* make all stack variables saved */
3778 sd.var[copy->varnum].flags |= SAVEDVAR;
3779 copy->flags |= SAVEDVAR;
3784 #endif /* !SUPPORT_DIVISION */
3795 COUNT(count_pcmd_op);
3796 OP2_1(TYPE_INT, TYPE_INT, TYPE_INT);
3801 coalescing_boundary = sd.new;
3802 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
3803 bte = iptr->sx.s23.s3.bte;
3806 if (md->memuse > rd->memuse)
3807 rd->memuse = md->memuse;
3808 if (md->argintreguse > rd->argintreguse)
3809 rd->argintreguse = md->argintreguse;
3810 /* XXX non-leaf method? */
3812 /* make all stack variables saved */
3816 sd.var[copy->varnum].flags |= SAVEDVAR;
3817 copy->flags |= SAVEDVAR;
3822 #endif /* !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV) */
3827 #if SUPPORT_LONG_LOGICAL
3831 #endif /* SUPPORT_LONG_LOGICAL */
3832 COUNT(count_pcmd_op);
3833 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_LNG);
3839 COUNT(count_pcmd_op);
3840 OP2_1(TYPE_LNG, TYPE_INT, TYPE_LNG);
3848 COUNT(count_pcmd_op);
3849 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_FLT);
3857 COUNT(count_pcmd_op);
3858 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_DBL);
3862 COUNT(count_pcmd_op);
3863 #if SUPPORT_LONG_CMP_CONST
3864 if ((len == 0) || (iptr[1].sx.val.i != 0))
3867 switch (iptr[1].opc) {
3869 iptr->opc = ICMD_IF_LCMPEQ;
3871 iptr->dst.insindex = iptr[1].dst.insindex;
3872 iptr[1].opc = ICMD_NOP;
3874 OP2_BRANCH(TYPE_LNG, TYPE_LNG);
3877 COUNT(count_pcmd_bra);
3880 iptr->opc = ICMD_IF_LCMPNE;
3881 goto icmd_lcmp_if_tail;
3883 iptr->opc = ICMD_IF_LCMPLT;
3884 goto icmd_lcmp_if_tail;
3886 iptr->opc = ICMD_IF_LCMPGT;
3887 goto icmd_lcmp_if_tail;
3889 iptr->opc = ICMD_IF_LCMPLE;
3890 goto icmd_lcmp_if_tail;
3892 iptr->opc = ICMD_IF_LCMPGE;
3893 goto icmd_lcmp_if_tail;
3899 #endif /* SUPPORT_LONG_CMP_CONST */
3900 OP2_1(TYPE_LNG, TYPE_LNG, TYPE_INT);
3903 /* XXX why is this deactivated? */
3906 COUNT(count_pcmd_op);
3907 if ((len == 0) || (iptr[1].sx.val.i != 0))
3910 switch (iptr[1].opc) {
3912 iptr->opc = ICMD_IF_FCMPEQ;
3914 iptr->dst.insindex = iptr[1].dst.insindex;
3915 iptr[1].opc = ICMD_NOP;
3917 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3920 COUNT(count_pcmd_bra);
3923 iptr->opc = ICMD_IF_FCMPNE;
3924 goto icmd_if_fcmpl_tail;
3926 iptr->opc = ICMD_IF_FCMPL_LT;
3927 goto icmd_if_fcmpl_tail;
3929 iptr->opc = ICMD_IF_FCMPL_GT;
3930 goto icmd_if_fcmpl_tail;
3932 iptr->opc = ICMD_IF_FCMPL_LE;
3933 goto icmd_if_fcmpl_tail;
3935 iptr->opc = ICMD_IF_FCMPL_GE;
3936 goto icmd_if_fcmpl_tail;
3943 OPTT2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3947 COUNT(count_pcmd_op);
3948 if ((len == 0) || (iptr[1].sx.val.i != 0))
3951 switch (iptr[1].opc) {
3953 iptr->opc = ICMD_IF_FCMPEQ;
3955 iptr->dst.insindex = iptr[1].dst.insindex;
3956 iptr[1].opc = ICMD_NOP;
3958 OP2_BRANCH(TYPE_FLT, TYPE_FLT);
3961 COUNT(count_pcmd_bra);
3964 iptr->opc = ICMD_IF_FCMPNE;
3965 goto icmd_if_fcmpg_tail;
3967 iptr->opc = ICMD_IF_FCMPG_LT;
3968 goto icmd_if_fcmpg_tail;
3970 iptr->opc = ICMD_IF_FCMPG_GT;
3971 goto icmd_if_fcmpg_tail;
3973 iptr->opc = ICMD_IF_FCMPG_LE;
3974 goto icmd_if_fcmpg_tail;
3976 iptr->opc = ICMD_IF_FCMPG_GE;
3977 goto icmd_if_fcmpg_tail;
3984 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
3988 COUNT(count_pcmd_op);
3989 if ((len == 0) || (iptr[1].sx.val.i != 0))
3992 switch (iptr[1].opc) {
3994 iptr->opc = ICMD_IF_DCMPEQ;
3996 iptr->dst.insindex = iptr[1].dst.insindex;
3997 iptr[1].opc = ICMD_NOP;
3999 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4002 COUNT(count_pcmd_bra);
4005 iptr->opc = ICMD_IF_DCMPNE;
4006 goto icmd_if_dcmpl_tail;
4008 iptr->opc = ICMD_IF_DCMPL_LT;
4009 goto icmd_if_dcmpl_tail;
4011 iptr->opc = ICMD_IF_DCMPL_GT;
4012 goto icmd_if_dcmpl_tail;
4014 iptr->opc = ICMD_IF_DCMPL_LE;
4015 goto icmd_if_dcmpl_tail;
4017 iptr->opc = ICMD_IF_DCMPL_GE;
4018 goto icmd_if_dcmpl_tail;
4025 OPTT2_1(TYPE_DBL, TYPE_INT);
4029 COUNT(count_pcmd_op);
4030 if ((len == 0) || (iptr[1].sx.val.i != 0))
4033 switch (iptr[1].opc) {
4035 iptr->opc = ICMD_IF_DCMPEQ;
4037 iptr->dst.insindex = iptr[1].dst.insindex;
4038 iptr[1].opc = ICMD_NOP;
4040 OP2_BRANCH(TYPE_DBL, TYPE_DBL);
4043 COUNT(count_pcmd_bra);
4046 iptr->opc = ICMD_IF_DCMPNE;
4047 goto icmd_if_dcmpg_tail;
4049 iptr->opc = ICMD_IF_DCMPG_LT;
4050 goto icmd_if_dcmpg_tail;
4052 iptr->opc = ICMD_IF_DCMPG_GT;
4053 goto icmd_if_dcmpg_tail;
4055 iptr->opc = ICMD_IF_DCMPG_LE;
4056 goto icmd_if_dcmpg_tail;
4058 iptr->opc = ICMD_IF_DCMPG_GE;
4059 goto icmd_if_dcmpg_tail;
4066 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4071 COUNT(count_pcmd_op);
4072 OP2_1(TYPE_FLT, TYPE_FLT, TYPE_INT);
4077 COUNT(count_pcmd_op);
4078 OP2_1(TYPE_DBL, TYPE_DBL, TYPE_INT);
4087 case ICMD_INT2SHORT:
4088 COUNT(count_pcmd_op);
4089 OP1_1(TYPE_INT, TYPE_INT);
4092 COUNT(count_pcmd_op);
4093 OP1_1(TYPE_LNG, TYPE_LNG);
4096 COUNT(count_pcmd_op);
4097 OP1_1(TYPE_FLT, TYPE_FLT);
4100 COUNT(count_pcmd_op);
4101 OP1_1(TYPE_DBL, TYPE_DBL);
4105 COUNT(count_pcmd_op);
4106 OP1_1(TYPE_INT, TYPE_LNG);
4109 COUNT(count_pcmd_op);
4110 OP1_1(TYPE_INT, TYPE_FLT);
4113 COUNT(count_pcmd_op);
4114 OP1_1(TYPE_INT, TYPE_DBL);
4117 COUNT(count_pcmd_op);
4118 OP1_1(TYPE_LNG, TYPE_INT);
4121 COUNT(count_pcmd_op);
4122 OP1_1(TYPE_LNG, TYPE_FLT);
4125 COUNT(count_pcmd_op);
4126 OP1_1(TYPE_LNG, TYPE_DBL);
4129 COUNT(count_pcmd_op);
4130 OP1_1(TYPE_FLT, TYPE_INT);
4133 COUNT(count_pcmd_op);
4134 OP1_1(TYPE_FLT, TYPE_LNG);
4137 COUNT(count_pcmd_op);
4138 OP1_1(TYPE_FLT, TYPE_DBL);
4141 COUNT(count_pcmd_op);
4142 OP1_1(TYPE_DBL, TYPE_INT);
4145 COUNT(count_pcmd_op);
4146 OP1_1(TYPE_DBL, TYPE_LNG);
4149 COUNT(count_pcmd_op);
4150 OP1_1(TYPE_DBL, TYPE_FLT);
4153 case ICMD_CHECKCAST:
4154 coalescing_boundary = sd.new;
4155 if (iptr->flags.bits & INS_FLAG_ARRAY) {
4156 /* array type cast-check */
4158 bte = builtintable_get_internal(BUILTIN_arraycheckcast);
4161 if (md->memuse > rd->memuse)
4162 rd->memuse = md->memuse;
4163 if (md->argintreguse > rd->argintreguse)
4164 rd->argintreguse = md->argintreguse;
4166 /* make all stack variables saved */
4170 sd.var[copy->varnum].flags |= SAVEDVAR;
4171 copy->flags |= SAVEDVAR;
4175 OP1_1(TYPE_ADR, TYPE_ADR);
4178 case ICMD_INSTANCEOF:
4179 case ICMD_ARRAYLENGTH:
4180 coalescing_boundary = sd.new;
4181 OP1_1(TYPE_ADR, TYPE_INT);
4185 case ICMD_ANEWARRAY:
4186 coalescing_boundary = sd.new;
4187 OP1_1(TYPE_INT, TYPE_ADR);
4191 coalescing_boundary = sd.new;
4192 COUNT(count_check_null);
4193 COUNT(count_pcmd_mem);
4194 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4195 OP1_1(TYPE_ADR, fmiref->parseddesc.fd->type);
4200 case ICMD_GETSTATIC:
4201 coalescing_boundary = sd.new;
4202 COUNT(count_pcmd_mem);
4203 INSTRUCTION_GET_FIELDREF(iptr, fmiref);
4204 OP0_1(fmiref->parseddesc.fd->type);
4208 coalescing_boundary = sd.new;
4215 tbptr = BLOCK_OF(iptr->sx.s23.s3.jsrtarget.insindex);
4216 tbptr->type = BBTYPE_SBR;
4218 assert(sd.bptr->next); /* XXX exception */
4219 sd.var[curstack->varnum].vv.retaddr = sd.bptr->next;
4220 #if defined(ENABLE_VERIFIER)
4221 sd.var[curstack->varnum].SBRSTART = (void*) tbptr;
4224 tbptr = stack_mark_reached(&sd, tbptr, curstack, stackdepth);
4228 iptr->sx.s23.s3.jsrtarget.block = tbptr;
4230 /* We need to check for overflow right here because
4231 * the pushed value is poped afterwards */
4234 superblockend = true;
4235 /* XXX should not be marked as interface, as it does not need to be */
4236 /* allocated. Same for the invar of the target. */
4239 /* pop many push any */
4243 bte = iptr->sx.s23.s3.bte;
4247 case ICMD_INVOKESTATIC:
4248 case ICMD_INVOKESPECIAL:
4249 case ICMD_INVOKEVIRTUAL:
4250 case ICMD_INVOKEINTERFACE:
4251 COUNT(count_pcmd_met);
4253 /* Check for functions to replace with builtin
4256 if (builtintable_replace_function(iptr))
4259 INSTRUCTION_GET_METHODDESC(iptr, md);
4260 /* XXX resurrect this COUNT? */
4261 /* if (lm->flags & ACC_STATIC) */
4262 /* {COUNT(count_check_null);} */
4266 coalescing_boundary = sd.new;
4270 if (md->memuse > rd->memuse)
4271 rd->memuse = md->memuse;
4272 if (md->argintreguse > rd->argintreguse)
4273 rd->argintreguse = md->argintreguse;
4274 if (md->argfltreguse > rd->argfltreguse)
4275 rd->argfltreguse = md->argfltreguse;
4279 iptr->s1.argcount = stackdepth;
4280 iptr->sx.s23.s2.args = DMNEW(s4, stackdepth);
4283 for (i-- ; i >= 0; i--) {
4284 iptr->sx.s23.s2.args[i] = copy->varnum;
4286 /* do not change STACKVARs or LOCALVARS to ARGVAR*/
4287 /* -> won't help anyway */
4288 if (!(IS_INOUT(copy) || IS_LOCALVAR(copy))) {
4290 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4291 /* If we pass float arguments in integer argument registers, we
4292 * are not allowed to precolor them here. Floats have to be moved
4293 * to this regs explicitly in codegen().
4294 * Only arguments that are passed by stack anyway can be precolored
4295 * (michi 2005/07/24) */
4296 if (!(sd.var[copy->varnum].flags & SAVEDVAR) &&
4297 (!IS_FLT_DBL_TYPE(copy->type)
4298 || md->params[i].inmemory)) {
4300 if (!(sd.var[copy->varnum].flags & SAVEDVAR)) {
4305 if (md->params[i].inmemory) {
4306 sd.var[copy->varnum].vv.regoff =
4307 md->params[i].regoff;
4308 sd.var[copy->varnum].flags |=
4312 if (IS_FLT_DBL_TYPE(copy->type)) {
4313 #if defined(SUPPORT_PASS_FLOATARGS_IN_INTREGS)
4314 assert(0); /* XXX is this assert ok? */
4316 sd.var[copy->varnum].vv.regoff =
4317 rd->argfltregs[md->params[i].regoff];
4318 #endif /* SUPPORT_PASS_FLOATARGS_IN_INTREGS */
4321 #if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
4322 if (IS_2_WORD_TYPE(copy->type))
4323 sd.var[copy->varnum].vv.regoff =
4324 PACK_REGS( rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
4325 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
4328 #endif /* SUPPORT_COMBINE_INTEGER_REGISTERS */
4329 sd.var[copy->varnum].vv.regoff =
4330 rd->argintregs[md->params[i].regoff];
4338 /* deal with live-through stack slots "under" the */
4344 iptr->sx.s23.s2.args[i++] = copy->varnum;
4345 sd.var[copy->varnum].flags |= SAVEDVAR;
4346 copy->flags |= SAVEDVAR | PASSTHROUGH;
4350 /* pop the arguments */
4359 /* push the return value */
4361 if (md->returntype.type != TYPE_VOID) {
4362 GET_NEW_VAR(sd, new_index, md->returntype.type);
4363 DST(md->returntype.type, new_index);
4368 case ICMD_INLINE_START:
4369 case ICMD_INLINE_END:
4374 case ICMD_MULTIANEWARRAY:
4375 coalescing_boundary = sd.new;
4376 if (rd->argintreguse < MIN(3, INT_ARG_CNT))
4377 rd->argintreguse = MIN(3, INT_ARG_CNT);
4379 i = iptr->s1.argcount;
4383 iptr->sx.s23.s2.args = DMNEW(s4, i);
4385 #if defined(SPECIALMEMUSE)
4386 # if defined(__DARWIN__)
4387 if (rd->memuse < (i + INT_ARG_CNT +LA_SIZE_IN_POINTERS))
4388 rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4390 if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
4391 rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
4394 # if defined(__I386__)
4395 if (rd->memuse < i + 3)
4396 rd->memuse = i + 3; /* n integer args spilled on stack */
4397 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4398 if (rd->memuse < i + 2)
4399 rd->memuse = i + 2; /* 4*4 bytes callee save space */
4402 rd->memuse = i; /* n integer args spilled on stack */
4403 # endif /* defined(__I386__) */
4407 /* check INT type here? Currently typecheck does this. */
4408 iptr->sx.s23.s2.args[i] = copy->varnum;
4409 if (!(sd.var[copy->varnum].flags & SAVEDVAR)
4410 && (!IS_INOUT(copy))
4411 && (!IS_LOCALVAR(copy)) ) {
4412 copy->varkind = ARGVAR;
4413 sd.var[copy->varnum].flags |=
4414 INMEMORY & PREALLOC;
4415 #if defined(SPECIALMEMUSE)
4416 # if defined(__DARWIN__)
4417 sd.var[copy->varnum].vv.regoff = i +
4418 LA_SIZE_IN_POINTERS + INT_ARG_CNT;
4420 sd.var[copy->varnum].vv.regoff = i +
4421 LA_SIZE_IN_POINTERS + 3;
4424 # if defined(__I386__)
4425 sd.var[copy->varnum].vv.regoff = i + 3;
4426 # elif defined(__MIPS__) && SIZEOF_VOID_P == 4
4427 sd.var[copy->varnum].vv.regoff = i + 2;
4429 sd.var[copy->varnum].vv.regoff = i;
4430 # endif /* defined(__I386__) */
4431 #endif /* defined(SPECIALMEMUSE) */
4436 sd.var[copy->varnum].flags |= SAVEDVAR;
4437 copy->flags |= SAVEDVAR;
4441 i = iptr->s1.argcount;
4446 GET_NEW_VAR(sd, new_index, TYPE_ADR);
4447 DST(TYPE_ADR, new_index);
4453 new_internalerror("Unknown ICMD %d", opcode);
4459 } /* while instructions */
4461 /* stack slots at basic block end become interfaces */
4463 sd.bptr->outdepth = stackdepth;
4464 sd.bptr->outvars = DMNEW(s4, stackdepth);
4467 for (copy = curstack; copy; i--, copy = copy->prev) {
4471 /* with the new vars rd->interfaces will be removed */
4472 /* and all in and outvars have to be STACKVARS! */
4473 /* in the moment i.e. SWAP with in and out vars can */
4474 /* create an unresolvable conflict */
4481 v = sd.var + copy->varnum;
4484 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4485 /* no interface var until now for this depth and */
4487 jd->interface_map[i*5 + t].flags = v->flags;
4490 jd->interface_map[i*5 + t].flags |= v->flags;
4493 sd.bptr->outvars[i] = copy->varnum;
4496 /* check if interface slots at basic block begin must be saved */
4498 for (i=0; i<sd.bptr->indepth; ++i) {
4499 varinfo *v = sd.var + sd.bptr->invars[i];
4506 if (jd->interface_map[i*5 + t].flags == UNUSED) {
4507 /* no interface var until now for this depth and */
4509 jd->interface_map[i*5 + t].flags = v->flags;
4512 jd->interface_map[i*5 + t].flags |= v->flags;
4516 /* store the number of this block's variables */
4518 sd.bptr->varcount = sd.vartop - sd.bptr->varstart;
4520 #if defined(STACK_VERBOSE)
4521 stack_verbose_block_exit(&sd, superblockend);
4524 /* reach the following block, if any */
4527 if (!stack_reach_next_block(&sd))
4532 } while (sd.repeat && !deadcode);
4534 /* XXX reset TYPE_RET to TYPE_ADR */
4536 for (i=0; i<sd.vartop; ++i) {
4537 if (sd.var[i].type == TYPE_RET)
4538 sd.var[i].type = TYPE_ADR;
4541 /* XXX hack to fix up the ranges of the cloned single-block handlers */
4543 ex = jd->exceptiontable;
4544 for (; ex != NULL; ex = ex->down) {
4545 if (ex->start == ex->end) {
4546 assert(ex->end->next);
4547 ex->end = ex->end->next;
4551 /* gather statistics *****************************************************/
4553 #if defined(ENABLE_STATISTICS)
4555 if (jd->basicblockcount > count_max_basic_blocks)
4556 count_max_basic_blocks = jd->basicblockcount;
4557 count_basic_blocks += jd->basicblockcount;
4558 if (jd->instructioncount > count_max_javainstr)
4559 count_max_javainstr = jd->instructioncount;
4560 count_javainstr += jd->instructioncount;
4561 if (jd->stackcount > count_upper_bound_new_stack)
4562 count_upper_bound_new_stack = jd->stackcount;
4563 if ((sd.new - jd->stack) > count_max_new_stack)
4564 count_max_new_stack = (sd.new - jd->stack);
4566 sd.bptr = jd->basicblocks;
4567 for (; sd.bptr; sd.bptr = sd.bptr->next) {
4568 if (sd.bptr->flags > BBREACHED) {
4569 if (sd.bptr->indepth >= 10)
4570 count_block_stack[10]++;
4572 count_block_stack[sd.bptr->indepth]++;
4573 len = sd.bptr->icount;
4575 count_block_size_distribution[len]++;
4577 count_block_size_distribution[10]++;
4579 count_block_size_distribution[11]++;
4581 count_block_size_distribution[12]++;
4583 count_block_size_distribution[13]++;
4585 count_block_size_distribution[14]++;
4587 count_block_size_distribution[15]++;
4589 count_block_size_distribution[16]++;
4591 count_block_size_distribution[17]++;
4595 if (iteration_count == 1)
4596 count_analyse_iterations[0]++;
4597 else if (iteration_count == 2)
4598 count_analyse_iterations[1]++;
4599 else if (iteration_count == 3)
4600 count_analyse_iterations[2]++;
4601 else if (iteration_count == 4)
4602 count_analyse_iterations[3]++;
4604 count_analyse_iterations[4]++;
4606 if (jd->basicblockcount <= 5)
4607 count_method_bb_distribution[0]++;
4608 else if (jd->basicblockcount <= 10)
4609 count_method_bb_distribution[1]++;
4610 else if (jd->basicblockcount <= 15)
4611 count_method_bb_distribution[2]++;
4612 else if (jd->basicblockcount <= 20)
4613 count_method_bb_distribution[3]++;
4614 else if (jd->basicblockcount <= 30)
4615 count_method_bb_distribution[4]++;
4616 else if (jd->basicblockcount <= 40)
4617 count_method_bb_distribution[5]++;
4618 else if (jd->basicblockcount <= 50)
4619 count_method_bb_distribution[6]++;
4620 else if (jd->basicblockcount <= 75)
4621 count_method_bb_distribution[7]++;
4623 count_method_bb_distribution[8]++;
4625 #endif /* defined(ENABLE_STATISTICS) */
4627 /* everything's ok *******************************************************/
4631 /* goto labels for throwing verifier exceptions **************************/
4633 #if defined(ENABLE_VERIFIER)
4635 throw_stack_underflow:
4636 exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
4639 throw_stack_overflow:
4640 exceptions_throw_verifyerror(m, "Stack size too large");
4643 throw_stack_type_error:
4644 exceptions_throw_verifyerror_for_stack(m, expectedtype);
4647 throw_stack_category_error:
4648 exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
4655 /* functions for verbose stack analysis output ********************************/
4657 #if defined(STACK_VERBOSE)
4658 static void stack_verbose_show_varinfo(stackdata_t *sd, varinfo *v)
4660 printf("%c", show_jit_type_letters[v->type]);
4661 if (v->type == TYPE_RET)
4662 printf("{L%03d}", v->vv.retaddr->nr);
4666 static void stack_verbose_show_variable(stackdata_t *sd, s4 index)
4668 assert(index >= 0 && index < sd->vartop);
4669 stack_verbose_show_varinfo(sd, sd->var + index);
4673 static void stack_verbose_show_block(stackdata_t *sd, basicblock *bptr)
4677 printf("L%03d type:%d in:%d [", bptr->nr, bptr->type, bptr->indepth);
4679 for (i=0; i<bptr->indepth; ++i) {
4682 stack_verbose_show_variable(sd, bptr->invars[i]);
4687 printf("] inlocals [");
4688 if (bptr->inlocals) {
4689 for (i=0; i<sd->localcount; ++i) {
4692 stack_verbose_show_varinfo(sd, bptr->inlocals + i);
4697 printf("] out:%d [", bptr->outdepth);
4698 if (bptr->outvars) {
4699 for (i=0; i<bptr->outdepth; ++i) {
4702 stack_verbose_show_variable(sd, bptr->outvars[i]);
4710 printf(" (clone of L%03d)", bptr->original->nr);
4712 basicblock *b = bptr->copied_to;
4714 printf(" (copied to ");
4715 for (; b; b = b->copied_to)
4716 printf("L%03d ", b->nr);
4723 static void stack_verbose_block_enter(stackdata_t *sd, bool reanalyse)
4727 printf("======================================== STACK %sANALYSE BLOCK ",
4728 (reanalyse) ? "RE-" : "");
4729 stack_verbose_show_block(sd, sd->bptr);
4732 if (sd->handlers[0]) {
4733 printf("HANDLERS: ");
4734 for (i=0; sd->handlers[i]; ++i) {
4735 printf("L%03d ", sd->handlers[i]->handler->nr);
4743 static void stack_verbose_block_exit(stackdata_t *sd, bool superblockend)
4745 printf("%s ", (superblockend) ? "SUPERBLOCKEND" : "END");
4746 stack_verbose_show_block(sd, sd->bptr);
4753 * These are local overrides for various environment variables in Emacs.
4754 * Please do not remove this and leave it at the end of the file, where
4755 * Emacs will automagically detect them.
4756 * ---------------------------------------------------------------------
4759 * indent-tabs-mode: t
4763 * vim:noexpandtab:sw=4:ts=4: