1 /* src/vm/jit/allocator/liveness.c - liveness analysis for lsra
3 Copyright (C) 2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
33 #include "mm/memory.h"
35 #include "toolbox/logging.h"
36 #include "toolbox/worklist.h"
38 #include "vm/jit/builtin.hpp"
39 #include "vm/exceptions.hpp"
40 #include "vm/global.h"
41 #include "vm/method.hpp"
42 #include "vm/resolve.hpp"
43 #include "vm/jit/codegen-common.hpp"
44 #include "vm/jit/jit.hpp"
45 #include "vm/jit/allocator/lsra.h"
46 #include "vm/jit/allocator/liveness.h"
49 /* function prototypes */
50 void liveness_scan_registers_canditates(jitdata *jd, int b_index, int iindex,
51 stackelement_t* src, lv_sets *sets);
52 void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackelement_t* s,
53 lv_sets *sets, int op);
54 void liveness_set_local(lsradata *ls, int block, int g_iindex, s4 v_index,
55 int type, lv_sets *sets, int op);
57 void liveness_add_ss(struct lifetime *lt, stackelement_t* s) {
59 /* Stackslot noch nicht eingetragen? */
61 if (s->varnum != lt->v_index) {
62 ss = DNEW(struct stackslot);
64 ss->s->varnum = lt->v_index;
65 ss->next = lt->local_ss;
67 if (s != NULL) lt->savedvar |= s->flags & SAVEDVAR;
68 if (s != NULL) lt->type = s->type;
72 void liveness_join_ss( struct lsradata *ls, struct stackelement *in,
73 struct stackelement *out) {
74 struct lifetime *lt, *lto;
75 struct stackslot *ss, *ss_last;
78 if (in->varnum != out->varnum) {
79 lt = &(ls->lifetime[-in->varnum - 1]);
83 #ifdef LV_DEBUG_VERBOSE
84 log_text("liveness_join_ss: lifetime for instack not found\n");
90 if (out->varnum >= 0) { /* no lifetime for this slot till now */
91 liveness_add_ss(lt, out);
93 lto = &(ls->lifetime[-out->varnum - 1]);
96 if (lto->type == -1) {
97 #ifdef LV_DEBUG_VERBOSE
98 log_text("liveness_join_ss: lifetime for outstack not found\n");
103 #ifdef LV_DEBUG_CHECK
104 if (lto->type != lt->type) {
105 #ifdef LV_DEBUG_VERBOSE
106 log_text("liveness_join_ss: in/out stack type mismatch\n");
112 /* take Lifetime lto out of ls->lifetimes */
115 /* merge lto into lt of in */
117 /* change varnums of all lto->local_ss->s to lt->v_index */
118 ss_last = ss = lto->local_ss;
121 ss->s->varnum = lt->v_index;
124 /* link both lto->local_ss list to lt->local_ss */
125 if (ss_last != NULL) {
126 ss_last->next = lt->local_ss;
127 lt->local_ss = lto->local_ss;
130 lt->savedvar |= lto->savedvar;
131 lt->flags |= lto->flags;
132 lt->usagecount += lto->usagecount;
134 /*join of [bb|i]_first_def und [bb|i]_last_use */
135 if (lto->bb_first_def < lt->bb_first_def) {
136 lt->bb_first_def = lto->bb_first_def;
137 lt->i_first_def = lto->i_first_def;
138 } else if ((lto->bb_first_def == lt->bb_first_def) &&
139 ( lto->i_first_def < lt->i_first_def)) {
140 lt->i_first_def = lto->i_first_def;
142 if (lto->bb_last_use > lt->bb_last_use) {
143 lt->bb_last_use = lto->bb_last_use;
144 lt->i_last_use = lto->i_last_use;
145 } else if ((lto->bb_last_use == lt->bb_last_use) &&
146 ( lto->i_last_use > lt->i_last_use)) {
147 lt->i_last_use = lto->i_last_use;
153 /* join instack of Basic Block b_index with outstack of predecessors */
154 void liveness_join_lifetimes(jitdata *jd, int b_index) {
155 struct stackelement *in, *i, *out;
164 /* do not join instack of Exception Handler */
165 if (m->basicblocks[b_index].type == BBTYPE_EXH)
167 in=m->basicblocks[b_index].instack;
168 /* do not join first instack element of a subroutine header */
169 if (m->basicblocks[b_index].type == BBTYPE_SBR)
173 for (pred = ls->pred[b_index]; pred != NULL; pred = pred->next) {
174 out = m->basicblocks[pred->value].outstack;
175 for (i=in; (i != NULL); i = i->prev, out=out->prev) {
176 liveness_join_ss(ls, i, out);
182 void liveness_setup(jitdata *jd) {
183 int i, icount, b_index;
191 ls->icount_block = DMNEW(int, m->basicblockcount);
192 ls->icount_block[0] = icount = 0;
193 for(i = 0; i < m->basicblockcount; i++) {
195 /* create a global instruction index in icount_block */
196 if (ls->sorted[i-1] != -1)
197 icount += m->basicblocks[ ls->sorted[i-1] ].icount;
198 ls->icount_block[i] = icount;
201 if ((b_index = ls->sorted[i]) != -1) {
202 /* 'valid' Basic Block */
204 /* adapt in- and outstacks for LSRA */
205 src = m->basicblocks[b_index].instack;
206 if (m->basicblocks[b_index].type != BBTYPE_STD) {
207 #ifdef LV_DEBUG_CHECK
209 #ifdef LV_DEBUG_VERBOSE
210 log_text("No Incoming Stackslot for Exception/Subroutine BB\n");
215 if (src->varkind == STACKVAR)
216 src->varkind = TEMPVAR;
219 for (;src != NULL; src=src->prev) {
220 /* no ARGVAR possible at BB Boundaries with LSRA! */
221 /* -> change to TEMPVAR */
222 if (src->varkind == ARGVAR ) {
223 src->varkind = TEMPVAR;
224 /* On Architectures with own return registers a return
225 stackslot is marked as varkind=ARGVAR with varnum=-1
226 but for lsra a varkind==TEMPVAR, varnum=-1 would mean,
227 that already a lifetime was allocated! */
228 if (src->varnum < 0) src->varnum = 0;
230 else if (src->varkind == LOCALVAR ) {
231 /* only allowed for top most ss at sbr or exh entries! */
232 #ifdef LV_DEBUG_VERBOSE
233 log_text("LOCALVAR at basicblock instack\n");
237 if (src->varkind == STACKVAR )
238 /* no Interfaces at BB Boundaries with LSRA! */
239 /* -> change to TEMPVAR */
240 src->varkind = TEMPVAR;
244 src = m->basicblocks[b_index].outstack;
245 for (;src != NULL; src=src->prev) {
246 if (src->varkind == ARGVAR ) {
247 #ifdef LV_DEBUG_VERBOSE
248 log_text("ARGVAR at basicblock outstack\n");
251 } else if (src->varkind == LOCALVAR ) {
252 #ifdef LV_DEBUG_VERBOSE
253 log_text("LOCALVAR at basicblock outstack\n");
257 /* no Interfaces at BB Boundaries with LSRA! */
258 /* -> change to TEMPVAR */
259 if (src->varkind == STACKVAR )
260 src->varkind = TEMPVAR;
267 void liveness_init(jitdata *jd) {
270 stackelement_t* src, dst;
280 for(i = 0; i < m->basicblockcount; i++) {
281 if ((b_index = ls->sorted[i]) != -1) {
282 /* 'valid' Basic Block */
284 /* Scan Number of Stack Lifetimes */
285 lifetimes += m->basicblocks[b_index].indepth;
287 dst = m->basicblocks[b_index].instack;
288 len = m->basicblocks[b_index].icount;
289 iptr = m->basicblocks[b_index].iinstr;
290 for (;len>0; len--, iptr++) {
313 if (( dst != NULL) && (src != dst))
319 ls->maxlifetimes = lifetimes;
320 ls->lifetimecount = lifetimes + jd->maxlocals * (TYPE_ADR+1);
323 void liveness_scan_basicblock(jitdata *jd, int b_index,
324 lv_sets *sets, int lifetimes) {
335 src = m->basicblocks[b_index].instack;
337 iindex = m->basicblocks[b_index].icount - 1;
338 /* set iptr to last instruction of BB */
339 iptr = m->basicblocks[b_index].iinstr + iindex;
341 bv_reset(sets->in, lifetimes);
343 for (;iindex >= 0; iindex--, iptr--) {
344 /* get source Stack for the current instruction */
345 /* destination stack is available as iptr->dst */
346 /* source stack is either the destination stack of the previos */
347 /* instruction, or the basicblock instack for the first instruction */
348 if (iindex) /* != 0 is > 0 here, since iindex ist always >= 0 */
351 src=m->basicblocks[b_index].instack;
353 /* Reset kill and gen bitvectors for use in */
354 /* liveness_scan_register_canditates */
356 bv_reset(sets->kill, lifetimes);
357 bv_reset(sets->gen, lifetimes);
359 /* get gen and kill set of instruction */
361 liveness_scan_registers_canditates(jd, b_index, iindex, src, sets);
363 /* tmp = out(instr) - kill(instr) */
365 bv_minus(sets->tmp, sets->out, sets->kill, lifetimes);
367 /* in = gen(instr) union tmp = gen union (out - kill) */
369 bv_union(sets->in, sets->gen, sets->tmp, lifetimes);
371 /* Set SAVEDVAR flag for locals */
373 if (op_needs_saved[iptr->opc])
374 for(i = ls->maxlifetimes; i < ls->lifetimecount; i++)
375 if (!ls->lifetime[i].savedvar)
376 if ( bv_get_bit(sets->in,i) && bv_get_bit(sets->out,i) )
377 ls->lifetime[i].savedvar = SAVEDVAR;
379 /* out(instr-1) = in(instr) (only one successor)*/
381 bv_copy(sets->out, sets->in, lifetimes);
383 /* create gen sets for incoming stackslots */
385 /* global instruction index for bb b_index */
387 iindex = ls->icount_block[ls->sorted_rev[b_index]];
388 bv_reset(sets->kill, lifetimes);
389 bv_reset(sets->gen, lifetimes);
390 src = m->basicblocks[b_index].instack;
391 if (m->basicblocks[b_index].type != BBTYPE_STD) {
392 liveness_set_stack(ls, b_index, iindex, src, sets, LV_KILL);
395 for (;src != NULL; src=src->prev) {
396 /* only TEMP or LOCALVAR by now possible */
397 /* liveness_set_stack redirects for LOCALVARS */
398 liveness_set_stack(ls, b_index, iindex, src, sets, LV_GEN);
399 _LV_ASSERT( ((src->varkind == LOCALVAR) || (src->varkind == TEMPVAR)) );
401 /* in = gen union (out - kill) */
402 bv_minus(sets->tmp, sets->out, sets->kill, lifetimes);
403 bv_union(sets->in, sets->gen, sets->tmp, lifetimes);
406 void liveness(jitdata *jd) {
419 #ifdef LV_DEBUG_CHECK
425 /***************************************************************************
427 - Exact Lifeness Information for intra Basic Blocks Stackslots are trivial
428 They should not be included in the gen, kill, in and out sets to improve
430 - Local Vars as represented in rd->locals "are quite sparse". An intermediate
431 representation for really used index/type pairs should be implemented.
432 ***************************************************************************/
438 if (ls->lifetimecount == 0)
440 ls->lifetime = DMNEW(struct lifetime, ls->lifetimecount);
441 for (i=0; i < ls->lifetimecount; i++) ls->lifetime[i].type = -1;
443 sets.gen = bv_new(ls->lifetimecount);
444 sets.kill = bv_new(ls->lifetimecount);
445 sets.tmp = bv_new(ls->lifetimecount);
446 sets.out = bv_new(ls->lifetimecount);
447 sets.in = bv_new(ls->lifetimecount);
449 params = bv_new(ls->lifetimecount);
451 visited = bv_new(m->basicblockcount);
452 buff = DMNEW(char, ls->lifetimecount+1);
454 out = DMNEW(bitvector, m->basicblockcount);
455 in = DMNEW(bitvector, m->basicblockcount);
456 for(i = 0; i < m->basicblockcount; i++) {
457 out[i] = bv_new(ls->lifetimecount);
458 in[i] = bv_new(ls->lifetimecount);
461 /* set in[0] to arguments */
462 /* <-> kill at 0, -1 */
464 for (p = 0, i = 0; p < md->paramcount; p++) {
465 t = md->paramtypes[p].type;
467 if (rd->locals[i][t].type >= 0)
468 /* Param to Local init happens before normal Code */
469 liveness_set_local(ls, 0, -1, i, t, &sets, LV_KILL);
471 if (IS_2_WORD_TYPE(t)) /* increment local counter a second time */
472 i++; /* for 2 word types */
474 bv_copy(params, sets.kill, ls->lifetimecount);
476 /* fill Worklist so that last node will be taken out first */
477 W = wl_new(m->basicblockcount);
478 for (i = 0; i < m->basicblockcount; i++)
479 if (ls->sorted[i] != -1)
480 wl_add(W, ls->sorted[i]);
482 /* Worklist algorithm*/
483 while (!wl_is_empty(W)) {
486 /* out[b_index] = for all s element of successors(b_index) union in[s]*/
487 for (succ = ls->succ[b_index]; succ != NULL; succ = succ->next)
488 bv_union(out[b_index], out[b_index], in[succ->value],
491 bv_copy(sets.out, out[b_index], ls->lifetimecount);
493 /* compute in[b_index] */
494 liveness_scan_basicblock(jd, b_index, &sets, ls->lifetimecount);
496 if (!bv_get_bit(visited, b_index)) {
497 liveness_join_lifetimes(jd, b_index);
498 bv_set_bit(visited, b_index);
501 if (!bv_equal(sets.in, in[b_index], ls->lifetimecount)) {
502 bv_copy(in[b_index], sets.in, ls->lifetimecount);
503 for(pred = ls->pred[b_index]; pred != NULL; pred = pred->next)
504 wl_add(W, pred->value);
508 #ifdef LV_DEBUG_CHECK
509 s = m->basicblocks[b_index].instack;
510 if ((s != NULL) && (m->basicblocks[b_index].flags != BBTYPE_STD))
512 for( ; s != NULL; s = s->prev) {
513 #ifdef LV_DEBUG_VERBOSE
514 if (!bv_get_bit(in[b_index], -s->varnum - 1)) {
515 log_text("liveness: Error In Stacklot not live!\n");
518 _LV_ASSERT( (bv_get_bit(in[b_index], -s->varnum - 1)) );
522 for (i = 0; i < m->basicblockcount; i++)
523 if ((b_index=ls->sorted[i]) != -1) {
524 for(t = 0; t < ls->lifetimecount; t++) {
525 if (ls->lifetime[t].type != -1) {
526 if (bv_get_bit(in[b_index], t)) {
527 p = ls->icount_block[ls->sorted_rev[b_index]];
528 if (p < ls->lifetime[t].i_first_def)
529 ls->lifetime[t].i_first_def = p;
531 if (bv_get_bit(out[b_index], t)) {
533 ls->icount_block[ls->sorted_rev[b_index]]+m->basicblocks[b_index].icount - 1;
534 if (p > ls->lifetime[t].i_last_use)
535 ls->lifetime[t].i_last_use = p;
543 struct lifetime *liveness_get_ss_lifetime(lsradata *ls, stackelement_t* s) {
546 if (s->varnum >= 0) { /* new stackslot lifetime */
547 #ifdef LV_DEBUG_VERBOSE
548 if (-ls->v_index - 1 >= ls->maxlifetimes) {
549 printf("%i %i\n", -ls->v_index - 1, ls->maxlifetimes);
552 _LV_ASSERT(-ls->v_index - 1 < ls->maxlifetimes);
554 n = &(ls->lifetime[-ls->v_index - 1]);
556 n->v_index = ls->v_index--;
560 n->i_first_def = INT_MAX;
565 n = &(ls->lifetime[-s->varnum - 1]);
567 liveness_add_ss( n, s);
571 void liveness_set_stack(lsradata *ls, int block, int g_iindex, stackelement_t* s,
576 if (s->varkind == LOCALVAR) {
577 liveness_set_local(ls, block, g_iindex, s->varnum, s->type, sets, op);
578 } else if (s->varkind == TEMPVAR) {
579 n = liveness_get_ss_lifetime(ls, s);
581 bv_set_bit(sets->kill, -s->varnum - 1);
582 if (n->i_first_def > g_iindex) {
583 n->i_first_def = g_iindex;
587 bv_set_bit(sets->gen, -s->varnum - 1);
588 if (n->i_last_use < g_iindex) {
589 n->i_last_use = g_iindex;
592 n->usagecount+=ls->nesting[ls->sorted_rev[block]];
596 void liveness_set_local(lsradata *ls, int block, int g_iindex, s4 v_index,
597 int type, lv_sets *sets, int op) {
600 n = &(ls->lifetime[ ls->maxlifetimes + v_index * (TYPE_ADR+1) + type]);
602 if (n->type == -1) { /* new local lifetime */
606 /* TODO: Look if local really needs to be a savedvar */
607 n->savedvar = 0; /* SAVEDVAR; */
612 n->i_first_def = INT_MAX;
614 n->usagecount+=ls->nesting[ls->sorted_rev[block]];
616 bv_set_bit(sets->kill, ls->maxlifetimes + v_index * (TYPE_ADR+1)+ type);
617 if (n->i_first_def > g_iindex) {
618 n->i_first_def = g_iindex;
622 bv_set_bit(sets->gen, ls->maxlifetimes + v_index * (TYPE_ADR+1) + type);
623 if (n->i_last_use < g_iindex) {
624 n->i_last_use = g_iindex;
629 void liveness_scan_registers_canditates(jitdata *jd, int b_index, int iindex,
630 stackelement_t* src, lv_sets *sets)
632 /* methodinfo *lm; */
633 builtintable_entry *bte;
644 iptr = m->basicblocks[b_index].iinstr + iindex;
646 g_iindex = ls->icount_block[ls->sorted_rev[b_index]] + iindex;
650 /* local read (return adress) */
651 liveness_set_local(ls, b_index, g_iindex, iptr->op1, TYPE_ADR, sets, LV_GEN);
655 /* case ICMD_ELSE_ICONST: */
660 case ICMD_PUTSTATICCONST:
661 case ICMD_INLINE_START:
662 case ICMD_INLINE_END:
663 case ICMD_INLINE_GOTO:
667 /* local = local+<const> */
668 liveness_set_local(ls, b_index, g_iindex, iptr->op1, TYPE_INT, sets, LV_GEN);
669 liveness_set_local(ls, b_index, g_iindex, iptr->op1, TYPE_INT, sets, LV_KILL);
672 /* pop 0 push 1 const: const->stack */
679 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
682 /* pop 0 push 1 load: local->stack */
688 if (dst->varkind != LOCALVAR) {
689 /* local->value on stack */
690 liveness_set_local(ls, b_index, g_iindex, iptr->op1,
691 iptr->opc - ICMD_ILOAD, sets, LV_GEN);
693 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
694 } else /* if (dst->varnum != iptr->op1) */ {
696 liveness_set_local(ls, b_index, g_iindex, iptr->op1,
697 iptr->opc - ICMD_ILOAD, sets, LV_GEN);
698 liveness_set_local(ls, b_index, g_iindex, dst->varnum,
699 iptr->opc - ICMD_ILOAD, sets, LV_KILL);
704 /* Stack(arrayref,index)->stack */
715 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
716 /* stack->arrayref */
717 liveness_set_stack(ls, b_index, g_iindex, src->prev, sets, LV_GEN);
718 /* arrayref[index]->stack */
719 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
723 /* stack(arrayref,index,value)->arrayref[index]=value */
734 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
736 liveness_set_stack(ls, b_index, g_iindex, src->prev, sets, LV_GEN);
737 /* stack -> arrayref */
738 liveness_set_stack(ls, b_index, g_iindex, src->prev->prev, sets, LV_GEN);
741 /* pop 1 push 0 store: stack -> local */
747 if (src->varkind != LOCALVAR) {
749 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
750 liveness_set_local(ls, b_index, g_iindex, iptr->op1, iptr->opc - ICMD_ISTORE,
753 liveness_set_local(ls, b_index, g_iindex, src->varnum, iptr->opc-ICMD_ISTORE,
755 liveness_set_local(ls, b_index, g_iindex, iptr->op1, iptr->opc - ICMD_ISTORE,
761 case ICMD_POP: /* throw away a stackslot */
762 /* TODO: check if used anyway (DUP...) and change codegen to */
763 /* ignore this stackslot */
764 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
772 case ICMD_ARETURN: /* stack(value) -> [empty] */
774 case ICMD_ATHROW: /* stack(objref) -> undefined */
776 case ICMD_PUTSTATIC: /* stack(value) -> static_field */
777 case ICMD_PUTFIELDCONST:
779 /* pop 1 push 0 branch */
780 case ICMD_IFNULL: /* stack(value) -> branch? */
797 /* pop 1 push 0 table branch */
798 case ICMD_TABLESWITCH:
799 case ICMD_LOOKUPSWITCH:
801 case ICMD_MONITORENTER:
802 case ICMD_MONITOREXIT:
804 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
808 case ICMD_POP2: /* throw away 2 stackslots */
809 /* TODO: check if used anyway (DUP...) and change codegen to */
810 /* ignore this stackslot */
811 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
812 liveness_set_stack(ls, b_index, g_iindex, src->prev, sets, LV_GEN);
815 /* pop 2 push 0 branch */
817 case ICMD_IF_ICMPEQ: /* stack (v1,v2) -> branch(v1,v2) */
835 case ICMD_PUTFIELD: /* stack(objref,value) -> objref = value */
837 case ICMD_IASTORECONST:
838 case ICMD_LASTORECONST:
839 case ICMD_AASTORECONST:
840 case ICMD_BASTORECONST:
841 case ICMD_CASTORECONST:
842 case ICMD_SASTORECONST:
844 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
845 liveness_set_stack(ls, b_index, g_iindex, src->prev, sets, LV_GEN);
848 /* pop 0 push 1 dup */
850 /* src == dst->prev */
853 /* src and dst->prev are identical */
854 /* liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_KILL);
855 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_GEN);*/
857 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
861 /* pop 0 push 2 dup */
863 /* src == dst->prev->prev */
864 /* src->prev == dst->prev->prev->prev */
866 /* src->prev -> dst->prev-> */
868 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
869 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
872 /* pop 2 push 3 dup */
875 /* src->prev -> dst->prev */
876 /* src -> dst->prev->prev */
878 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
879 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
880 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev, sets,
882 liveness_set_stack(ls, b_index, g_iindex + 1, src, sets, LV_GEN);
883 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev, sets, LV_GEN);
886 /* pop 3 push 4 dup */
889 /* src->prev -> dst->prev */
890 /* src->prev->prev -> dst->prev->prev */
891 /* dst (=src) -> dst->prev->prev->prev */
893 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
894 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
895 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev, sets,
897 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev->prev, sets,
899 liveness_set_stack(ls, b_index, g_iindex + 1, src, sets, LV_GEN);
900 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev, sets, LV_GEN);
901 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev->prev, sets,
905 /* pop 3 push 5 dup */
908 /* src->prev -> dst->prev */
909 /* src->prev->prev -> dst->prev->prev */
910 /* dst (=src) -> dst->prev->prev->prev */
911 /* dst->prev (=src->prev) -> dst->prev->prev->prev->prev */
912 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
913 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
914 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev, sets,
916 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev->prev, sets,
918 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev->prev->prev,
920 liveness_set_stack(ls, b_index, g_iindex + 1, src, sets, LV_GEN);
921 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev, sets, LV_GEN);
922 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev->prev, sets,
926 /* pop 4 push 6 dup */
929 /* src->prev -> dst->prev */
930 /* src->prev->prev -> dst->prev->prev */
931 /* src->prev->prev->prev -> dst->prev->prev->prev */
932 /* dst (=src) -> dst->prev->prev->prev->prev */
933 /* dst->prev (=src->prev) -> dst->prev->prev->prev->prev->prev */
934 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
935 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
936 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev, sets,
938 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev->prev, sets,
940 liveness_set_stack(ls, b_index, g_iindex, dst->prev->prev->prev->prev,
942 liveness_set_stack(ls, b_index, g_iindex,
943 dst->prev->prev->prev->prev->prev, sets, LV_KILL);
944 liveness_set_stack(ls, b_index, g_iindex + 1, src, sets, LV_GEN);
945 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev, sets, LV_GEN);
946 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev->prev, sets,
948 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev->prev->prev,
952 /* pop 2 push 2 swap */
954 /* src -> dst->prev */
955 /* src->prev -> dst */
956 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
957 liveness_set_stack(ls, b_index, g_iindex, dst->prev, sets, LV_KILL);
958 liveness_set_stack(ls, b_index, g_iindex + 1, src, sets, LV_GEN);
959 liveness_set_stack(ls, b_index, g_iindex + 1, src->prev, sets, LV_GEN);
1013 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1014 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
1015 liveness_set_stack(ls, b_index, g_iindex, src->prev, sets, LV_GEN);
1019 case ICMD_LADDCONST:
1020 case ICMD_LSUBCONST:
1021 case ICMD_LMULCONST:
1025 case ICMD_LANDCONST:
1027 case ICMD_LXORCONST:
1028 case ICMD_LSHLCONST:
1029 case ICMD_LSHRCONST:
1030 case ICMD_LUSHRCONST:
1032 case ICMD_IADDCONST:
1033 case ICMD_ISUBCONST:
1034 case ICMD_IMULCONST:
1038 case ICMD_IANDCONST:
1040 case ICMD_IXORCONST:
1041 case ICMD_ISHLCONST:
1042 case ICMD_ISHRCONST:
1043 case ICMD_IUSHRCONST:
1045 /* case ICMD_IFEQ_ICONST: */
1046 /* case ICMD_IFNE_ICONST: */
1047 /* case ICMD_IFLT_ICONST: */
1048 /* case ICMD_IFGE_ICONST: */
1049 /* case ICMD_IFGT_ICONST: */
1050 /* case ICMD_IFLE_ICONST: */
1055 case ICMD_INT2SHORT:
1073 case ICMD_CHECKCAST:
1075 case ICMD_ARRAYLENGTH:
1076 case ICMD_INSTANCEOF:
1079 case ICMD_ANEWARRAY:
1082 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1083 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
1087 case ICMD_GETSTATIC:
1090 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1093 /* pop many push any */
1095 case ICMD_INVOKESTATIC:
1096 case ICMD_INVOKESPECIAL:
1097 case ICMD_INVOKEVIRTUAL:
1098 case ICMD_INVOKEINTERFACE:
1099 INSTRUCTION_GET_METHODDESC(iptr,md);
1102 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
1105 if (md->returntype.type != TYPE_VOID)
1106 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1114 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
1117 if (md->returntype.type != TYPE_VOID)
1118 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1121 case ICMD_MULTIANEWARRAY:
1124 liveness_set_stack(ls, b_index, g_iindex, src, sets, LV_GEN);
1127 liveness_set_stack(ls, b_index, g_iindex, dst, sets, LV_KILL);
1131 exceptions_throw_internalerror("Unknown ICMD %d during register allocation",
1138 * These are local overrides for various environment variables in Emacs.
1139 * Please do not remove this and leave it at the end of the file, where
1140 * Emacs will automagically detect them.
1141 * ---------------------------------------------------------------------
1144 * indent-tabs-mode: t
1148 * vim:noexpandtab:sw=4:ts=4: