Changes: Stefan Ring
Christian Thalinger
- Christian Ullrich
+ Christian Ullrich
Michael Starzinger
- Edwin Steiner
+ Edwin Steiner
- $Id: simplereg.c 4454 2006-02-06 00:02:50Z edwin $
+ $Id: simplereg.c 5321 2006-09-05 16:12:09Z edwin $
*/
#include "vm/jit/reg.h"
#include "vm/jit/allocator/simplereg.h"
-/* function prototypes for this file */
-static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
-static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd);
-static void allocate_scratch_registers(methodinfo *m, registerdata *rd);
+/* function prototypes for this file ******************************************/
+static void interface_regalloc(jitdata *jd);
+static void local_regalloc(jitdata *jd);
+static void new_allocate_scratch_registers(jitdata *jd);
+static void allocate_scratch_registers(jitdata *jd);
-/* function interface_regalloc *************************************************
- allocates registers for all interface variables
+/* regalloc ********************************************************************
+
+ Does a simple register allocation.
*******************************************************************************/
-void regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
+bool new_regalloc(jitdata *jd)
{
- interface_regalloc(m, cd, rd);
- allocate_scratch_registers(m, rd);
- local_regalloc(m, cd, rd);
+ /* There is a problem with the use of unused float argument
+ registers in leafmethods for stackslots on c7 (2 * Dual Core
+ AMD Opteron(tm) Processor 270) - runtime for the jvm98 _mtrt
+ benchmark is heaviliy increased. This could be prevented by
+ setting rd->argfltreguse to FLT_ARG_CNT before calling
+ allocate_scratch_registers and setting it back to the original
+ value before calling local_regalloc. */
+
+ interface_regalloc(jd);
+ new_allocate_scratch_registers(jd);
+ local_regalloc(jd);
+
+ /* everthing's ok */
+
+ return true;
}
-/* function interface_regalloc *************************************************
+/* interface_regalloc **********************************************************
- allocates registers for all interface variables
+ Allocates registers for all interface variables.
*******************************************************************************/
-static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
+static void interface_regalloc(jitdata *jd)
{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+
int s, t, tt, saved;
int intalloc, fltalloc; /* Remember allocated Register/Memory offset */
/* in case a more vars are packed into this interface slot */
/* on HAS_4BYTE_STACKSLOT architectures */
int typeloop[] = { TYPE_LNG, TYPE_DBL, TYPE_INT, TYPE_FLT, TYPE_ADR };
- /* rd->memuse was already set in stack.c to allocate stack space for */
- /* passing arguments to called methods */
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ /* rd->memuse was already set in stack.c to allocate stack space
+ for passing arguments to called methods. */
+
#if defined(__I386__)
if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
/* reserve 0(%esp) for Monitorenter/exit Argument on i386 */
}
#endif
- if (m->isleafmethod) {
+ if (jd->isleafmethod) {
/* Reserve argument register, which will be used for Locals acting */
/* as Parameters */
if (rd->argintreguse < m->parseddesc->argintreguse)
if (!saved) {
#if defined(HAS_ADDRESS_REGISTER_FILE)
if (IS_ADR_TYPE(t)) {
- if (!m->isleafmethod
+ if (!jd->isleafmethod
&&(rd->argadrreguse < ADR_ARG_CNT)) {
v->regoff = rd->argadrregs[rd->argadrreguse++];
} else if (rd->tmpadrreguse > 0) {
v->flags |= rd->interfaces[s][fltalloc].flags
& INMEMORY;
v->regoff = rd->interfaces[s][fltalloc].regoff;
- } else if (!m->isleafmethod
- && (rd->argfltreguse < FLT_ARG_CNT)) {
+ } else if (rd->argfltreguse < FLT_ARG_CNT) {
v->regoff = rd->argfltregs[rd->argfltreguse++];
} else if (rd->tmpfltreguse > 0) {
v->regoff = rd->tmpfltregs[--rd->tmpfltreguse];
v->regoff =
rd->interfaces[s][intalloc].regoff;
} else
- if (!m->isleafmethod &&
- (rd->argintreguse
- + intregsneeded < INT_ARG_CNT)) {
+ if (rd->argintreguse + intregsneeded
+ < INT_ARG_CNT) {
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
if (intregsneeded)
v->regoff=PACK_REGS(
}
+/* local_regalloc **************************************************************
-/* function local_regalloc *****************************************************
-
- allocates registers for all local variables
+ Allocates registers for all local variables.
*******************************************************************************/
-static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd)
+static void local_regalloc(jitdata *jd)
{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
+
int p, s, t, tt;
int intalloc, fltalloc;
varinfo *v;
int aargcnt;
#endif
- if (m->isleafmethod) {
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
+ if (jd->isleafmethod) {
methoddesc *md = m->parseddesc;
iargcnt = rd->argintreguse;
}
-#define reg_free_temp(rd,s) if (s->varkind == TEMPVAR) reg_free_temp_func(rd, s)
+#define reg_free_temp(rd,s) if (((s)->varkind == TEMPVAR) && (!((s)->flags & STCOPY))) reg_free_temp_func(rd, (s))
+
+/* Do not free regs/memory locations used by Stackslots flagged STCOPY! There is still another Stackslot */
+/* alive using this reg/memory location */
static void reg_free_temp_func(registerdata *rd, stackptr s)
{
#ifdef HAS_ADDRESS_REGISTER_FILE
} else if (IS_ADR_TYPE(s->type)) {
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
- s->flags &= ~SAVEDTMP;
+/* s->flags &= ~SAVEDTMP; */
rd->freesavadrregs[rd->freesavadrtop++] = s->regoff;
} else
rd->freetmpadrregs[rd->freetmpadrtop++] = s->regoff;
#endif
} else if (IS_FLT_DBL_TYPE(s->type)) {
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
- s->flags &= ~SAVEDTMP;
+/* s->flags &= ~SAVEDTMP; */
rd->freesavfltregs[rd->freesavflttop++] = s->regoff;
} else if (s->flags & TMPARG) {
- s->flags &= ~TMPARG;
+/* s->flags &= ~TMPARG; */
rd->freeargfltregs[rd->freeargflttop++] = s->regoff;
} else
rd->freetmpfltregs[rd->freetmpflttop++] = s->regoff;
} else { /* IS_INT_LNG_TYPE */
if (s->flags & (SAVEDVAR | SAVEDTMP)) {
- s->flags &= ~SAVEDTMP;
+/* s->flags &= ~SAVEDTMP; */
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
if (intregsneeded) {
rd->freesavintregs[rd->freesavinttop] =
rd->freesavinttop += intregsneeded + 1;
} else if (s->flags & TMPARG) {
- s->flags &= ~TMPARG;
+/* s->flags &= ~TMPARG; */
#if defined(SUPPORT_COMBINE_INTEGER_REGISTERS)
if (intregsneeded) {
rd->freeargintregs[rd->freearginttop] =
}
}
+static bool reg_alloc_dup(stackptr src, stackptr dst) {
+ /* only copy TEMPVARS, do not mess with STACKVAR, */
+ /* LOCALVAR, or ARGVAR */
+ if ((src->varkind == TEMPVAR) && (dst->varkind == TEMPVAR)) {
+ /* can not allocate a REG_TMP to a REG_SAV Slot */
+ if (src->flags & INMEMORY) {
+ dst->regoff = src->regoff;
+ dst->flags |= INMEMORY;
+ return true;
+ } else if ((src->flags & SAVEDVAR) == (dst->flags & SAVEDVAR)) {
+ dst->regoff = src->regoff;
+ dst->flags |= src->flags & SAVEDTMP;
+ dst->flags |= src->flags & TMPARG;
+ return true;
+#if 0
+ } else if ((dst->flags & SAVEDVAR) == 0) {
+ /* can only use a REG_SAV as REG_TMP! */
+ dst->regoff = src->regoff;
+ dst->flags |= src->flags & TMPARG;
+ dst->flags |= SAVEDTMP;
+ return true;
+#endif
+ }
+ }
+ /* no copy possible - allocate a new reg/memory location*/
+ return false;
+}
+
+/* Mark the copies (STCOPY) at the dst stack right for DUPx and SWAP */
+static void new_reg_mark_copy(registerdata *rd, stackptr *dupslots,
+ int nin, int nout, int nthrough)
+{
+ s4 src_regoff[4];
+ s4 src_flags[4];
+ stackptr dst_stackslots[6];
+ int s_bottom, d_bottom, i, j, slots;
+ bool found;
+ stackptr sp;
+ stackptr *argp;
+
+ assert(nin <= 4 && (nout + nthrough) <= 6);
+
+ /* remember all different Registers/Memory Location of used TEMPVAR */
+ /* instacks in src_varnum[] and src_flags[] _uniquely_. Take the STCOPY */
+ /* flag of the last (deepest) occurence */
+ slots = nin;
+ argp = dupslots + slots;
+ for (s_bottom = 4; slots--; ) {
+ sp = *--argp;
+ if (sp->varkind == TEMPVAR) {
+ found = false;
+ for (i = 3; i >= s_bottom; i--) {
+ if ((src_regoff[i] == sp->regoff) &&
+ ((src_flags[i] & INMEMORY) == (sp->flags & INMEMORY)) )
+ {
+ src_flags[i] &= (~STCOPY | (sp->flags & STCOPY));
+ found = true;
+ }
+ }
+ if (!found) {
+ s_bottom--;
+ src_regoff[s_bottom] = sp->regoff;
+ src_flags[s_bottom] = sp->flags;
+ }
+ }
+ }
+
+ /* Remember used TEMPVAR dst Stackslots in dst_stackslots[], since they */
+ /* have to be from the "lowest" upwards, and the stackelements list is */
+ /* linked from only top downwards */
+
+ slots = nthrough + nout;
+ argp = dupslots + nin + nout;
+ for (d_bottom = 6; slots--; ) {
+ sp = *--argp;
+ if (sp->varkind == TEMPVAR) {
+ d_bottom--;
+ dst_stackslots[d_bottom] = sp;
+ }
+ }
+ /* Mark all reused reg/mem in dst stacklots with STCOPY, if the */
+ /* corresponding src stackslot was marked STCOPY*/
+ /* if the correspondig STCOPY from the src stackslot was not set, do not */
+ /* mark the lowest occurence at dst stackslots */
+ /* mark in src_flag reg/mem with STKEEP, if they where reused in the dst */
+ /* stacklots, so they are not freed afterwards */
+ for (i = d_bottom; i < 6; i++) {
+ for (j = s_bottom; j < 4; j++) {
+ if ( (src_regoff[j] == dst_stackslots[i]->regoff) &&
+ ((src_flags[j] & INMEMORY) == (dst_stackslots[i]->flags & INMEMORY)) )
+ {
+ if (src_flags[j] & STCOPY) {
+ dst_stackslots[i]->flags |= STCOPY;
+ }
+ else {
+ src_flags[j] |= STCOPY;
+ dst_stackslots[i]->flags &= ~STCOPY;
+ }
+ /* do not free reg/mem of src Stackslot */
+ src_flags[j] |= STKEEP;
+ }
+ }
+ }
-static void allocate_scratch_registers(methodinfo *m, registerdata *rd)
+ /* free all reg/mem of src stack, which where not marked with STKEEP */
+ for (j=s_bottom; j < 4; j++) {
+ if ((src_flags[j] & STKEEP)==0) {
+ /* free, if STCOPY of src stackslot is not set */
+ /* STCOPY is already checked in reg_free_temp macro! */
+ slots = nin;
+ argp = dupslots + slots;
+ while (--slots) {
+ sp = *--argp;
+ if ((src_regoff[j] == sp->regoff) &&
+ ((src_flags[j] & INMEMORY) == (sp->flags & INMEMORY)) )
+ {
+ reg_free_temp(rd, sp);
+ }
+ }
+ }
+ }
+}
+
+
+/* allocate_scratch_registers **************************************************
+
+ Allocate temporary (non-interface, non-local) registers.
+
+*******************************************************************************/
+
+static void new_allocate_scratch_registers(jitdata *jd)
{
- s4 opcode;
+ methodinfo *m;
+ registerdata *rd;
s4 i;
s4 len;
- stackptr src;
- stackptr dst;
- instruction *iptr;
+ new_instruction *iptr;
basicblock *bptr;
- methodinfo *lm;
builtintable_entry *bte;
methoddesc *md;
+ stackptr *argp;
+
+ /* get required compiler data */
+
+ m = jd->m;
+ rd = jd->rd;
/* initialize temp registers */
reg_init_temp(m, rd);
- bptr = m->basicblocks;
+ bptr = jd->new_basicblocks;
while (bptr != NULL) {
if (bptr->flags >= BBREACHED) {
- dst = bptr->instack;
-
-
iptr = bptr->iinstr;
len = bptr->icount;
while (--len >= 0) {
- src = dst;
- dst = iptr->dst;
- opcode = iptr->opc;
-
- switch (opcode) {
+ switch (iptr->opc) {
/* pop 0 push 0 */
case ICMD_NOP:
- case ICMD_ELSE_ICONST:
case ICMD_CHECKNULL:
case ICMD_IINC:
case ICMD_JSR:
case ICMD_FLOAD:
case ICMD_DLOAD:
case ICMD_ALOAD:
- reg_new_temp(rd, dst);
+ reg_new_temp(rd, iptr->dst.var);
break;
/* pop 2 push 1 */
case ICMD_BALOAD:
case ICMD_CALOAD:
case ICMD_SALOAD:
- reg_free_temp(rd, src);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst);
+ reg_free_temp(rd, iptr->sx.s23.s2.var);
+ reg_free_temp(rd, iptr->s1.var);
+ reg_new_temp(rd, iptr->dst.var);
break;
/* pop 3 push 0 */
case ICMD_BASTORE:
case ICMD_CASTORE:
case ICMD_SASTORE:
- reg_free_temp(rd, src);
- reg_free_temp(rd, src->prev);
- reg_free_temp(rd, src->prev->prev);
+ reg_free_temp(rd, iptr->sx.s23.s3.var);
+ reg_free_temp(rd, iptr->sx.s23.s2.var);
+ reg_free_temp(rd, iptr->s1.var);
break;
/* pop 1 push 0 store */
case ICMD_MONITORENTER:
case ICMD_MONITOREXIT:
- reg_free_temp(rd, src);
+ reg_free_temp(rd, iptr->s1.var);
break;
/* pop 2 push 0 branch */
case ICMD_IF_LCMPGT:
case ICMD_IF_LCMPLE:
+ case ICMD_IF_FCMPEQ:
+ case ICMD_IF_FCMPNE:
+
+ case ICMD_IF_FCMPL_LT:
+ case ICMD_IF_FCMPL_GE:
+ case ICMD_IF_FCMPL_GT:
+ case ICMD_IF_FCMPL_LE:
+
+ case ICMD_IF_FCMPG_LT:
+ case ICMD_IF_FCMPG_GE:
+ case ICMD_IF_FCMPG_GT:
+ case ICMD_IF_FCMPG_LE:
+
+ case ICMD_IF_DCMPEQ:
+ case ICMD_IF_DCMPNE:
+
+ case ICMD_IF_DCMPL_LT:
+ case ICMD_IF_DCMPL_GE:
+ case ICMD_IF_DCMPL_GT:
+ case ICMD_IF_DCMPL_LE:
+
+ case ICMD_IF_DCMPG_LT:
+ case ICMD_IF_DCMPG_GE:
+ case ICMD_IF_DCMPG_GT:
+ case ICMD_IF_DCMPG_LE:
+
case ICMD_IF_ACMPEQ:
case ICMD_IF_ACMPNE:
case ICMD_BASTORECONST:
case ICMD_CASTORECONST:
case ICMD_SASTORECONST:
- reg_free_temp(rd, src);
- reg_free_temp(rd, src->prev);
+ reg_free_temp(rd, iptr->sx.s23.s2.var);
+ reg_free_temp(rd, iptr->s1.var);
break;
/* pop 0 push 1 dup */
case ICMD_DUP:
- reg_new_temp(rd, dst);
+ /* src === dst->prev (identical Stackslot Element) */
+ /* src --> dst (copied value, take same reg/mem) */
+
+ if (!reg_alloc_dup(iptr->s1.var, iptr->dst.var)) {
+ reg_new_temp(rd, iptr->dst.var);
+ } else {
+ iptr->dst.var->flags |= STCOPY;
+ }
break;
/* pop 0 push 2 dup */
case ICMD_DUP2:
- reg_new_temp(rd, dst->prev);
- reg_new_temp(rd, dst);
+ /* src->prev === dst->prev->prev->prev (identical Stackslot Element) */
+ /* src === dst->prev->prev (identical Stackslot Element) */
+ /* src->prev --> dst->prev (copied value, take same reg/mem) */
+ /* src --> dst (copied value, take same reg/mem) */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+1]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 2);
break;
/* pop 2 push 3 dup */
case ICMD_DUP_X1:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst->prev);
- reg_new_temp(rd, dst->prev->prev);
+ /* src->prev --> dst->prev (copied value, take same reg/mem) */
+ /* src --> dst (copied value, take same reg/mem) */
+ /* src --> dst->prev->prev (copied value, take same reg/mem) */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+2]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+2]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+1]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 3, 0);
break;
/* pop 3 push 4 dup */
case ICMD_DUP_X2:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst->prev);
- reg_free_temp(rd, src->prev->prev);
- reg_new_temp(rd, dst->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev);
+ /* src->prev->prev --> dst->prev->prev */
+ /* src->prev --> dst->prev */
+ /* src --> dst */
+ /* src --> dst->prev->prev->prev */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+3]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+3]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+2]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+2]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+1]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 4, 0);
break;
/* pop 3 push 5 dup */
case ICMD_DUP2_X1:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst->prev);
- reg_free_temp(rd, src->prev->prev);
- reg_new_temp(rd, dst->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev->prev);
+ /* src->prev->prev --> dst->prev->prev */
+ /* src->prev --> dst->prev */
+ /* src --> dst */
+ /* src->prev --> dst->prev->prev->prev->prev */
+ /* src --> dst->prev->prev->prev */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+1]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[3+4]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+4]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[3+3]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+3]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[3+2]))
+ reg_new_temp(rd, iptr->dst.dupslots[3+2]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 3, 5, 0);
break;
/* pop 4 push 6 dup */
case ICMD_DUP2_X2:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst->prev);
- reg_free_temp(rd, src->prev->prev);
- reg_new_temp(rd, dst->prev->prev);
- reg_free_temp(rd, src->prev->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev->prev);
- reg_new_temp(rd, dst->prev->prev->prev->prev->prev);
+ /* src->prev->prev->prev --> dst->prev->prev->prev */
+ /* src->prev->prev --> dst->prev->prev */
+ /* src->prev --> dst->prev */
+ /* src --> dst */
+ /* src->prev --> dst->prev->prev->prev->prev->prev */
+ /* src --> dst->prev->prev->prev->prev */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+1]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[3], iptr->dst.dupslots[4+5]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+5]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[2], iptr->dst.dupslots[4+4]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+4]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[4+3]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+3]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[4+2]))
+ reg_new_temp(rd, iptr->dst.dupslots[4+2]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 4, 6, 0);
break;
/* pop 2 push 2 swap */
case ICMD_SWAP:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst->prev);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst);
+ /* src --> dst->prev (copy) */
+ /* src->prev --> dst (copy) */
+
+ if (!reg_alloc_dup(iptr->dst.dupslots[1], iptr->dst.dupslots[2+0]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+0]);
+ if (!reg_alloc_dup(iptr->dst.dupslots[0], iptr->dst.dupslots[2+1]))
+ reg_new_temp(rd, iptr->dst.dupslots[2+1]);
+ new_reg_mark_copy(rd, iptr->dst.dupslots, 2, 2, 0);
break;
/* pop 2 push 1 */
case ICMD_FCMPG:
case ICMD_DCMPL:
case ICMD_DCMPG:
- reg_free_temp(rd, src);
- reg_free_temp(rd, src->prev);
- reg_new_temp(rd, dst);
+ reg_free_temp(rd, iptr->sx.s23.s2.var);
+ reg_free_temp(rd, iptr->s1.var);
+ reg_new_temp(rd, iptr->dst.var);
break;
/* pop 1 push 1 */
case ICMD_LSHRCONST:
case ICMD_LUSHRCONST:
- case ICMD_IFEQ_ICONST:
- case ICMD_IFNE_ICONST:
- case ICMD_IFLT_ICONST:
- case ICMD_IFGE_ICONST:
- case ICMD_IFGT_ICONST:
- case ICMD_IFLE_ICONST:
-
case ICMD_INEG:
case ICMD_INT2BYTE:
case ICMD_INT2CHAR:
case ICMD_ANEWARRAY:
case ICMD_GETFIELD:
- reg_free_temp(rd, src);
- reg_new_temp(rd, dst);
+ reg_free_temp(rd, iptr->s1.var);
+ reg_new_temp(rd, iptr->dst.var);
break;
/* pop 0 push 1 */
case ICMD_GETSTATIC:
case ICMD_NEW:
- reg_new_temp(rd, dst);
+ reg_new_temp(rd, iptr->dst.var);
break;
/* pop many push any */
case ICMD_INVOKESPECIAL:
case ICMD_INVOKEVIRTUAL:
case ICMD_INVOKEINTERFACE:
- lm = iptr->val.a;
-
- if (lm)
- md = lm->parseddesc;
- else {
- unresolved_method *um = iptr->target;
- md = um->methodref->parseddesc.md;
- }
+ INSTRUCTION_GET_METHODDESC(iptr,md);
i = md->paramcount;
+ argp = iptr->sx.s23.s2.args;
while (--i >= 0) {
- reg_free_temp(rd, src);
- src = src->prev;
+ reg_free_temp(rd, *argp);
+ argp++;
}
if (md->returntype.type != TYPE_VOID)
- reg_new_temp(rd, dst);
+ reg_new_temp(rd, iptr->dst.var);
break;
case ICMD_BUILTIN:
- bte = iptr->val.a;
+ bte = iptr->sx.s23.s3.bte;
md = bte->md;
i = md->paramcount;
+ argp = iptr->sx.s23.s2.args;
while (--i >= 0) {
- reg_free_temp(rd, src);
- src = src->prev;
+ reg_free_temp(rd, *argp);
+ argp++;
}
if (md->returntype.type != TYPE_VOID)
- reg_new_temp(rd, dst);
+ reg_new_temp(rd, iptr->dst.var);
break;
case ICMD_MULTIANEWARRAY:
- i = iptr->op1;
+ i = iptr->s1.argcount;
+ argp = iptr->sx.s23.s2.args;
while (--i >= 0) {
- reg_free_temp(rd, src);
- src = src->prev;
+ reg_free_temp(rd, *argp);
+ argp++;
}
- reg_new_temp(rd, dst);
+ reg_new_temp(rd, iptr->dst.var);
break;
default:
#if defined(ENABLE_STATISTICS)
-void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) {
+void reg_make_statistics(jitdata *jd)
+{
+ methodinfo *m;
+ codegendata *cd;
+ registerdata *rd;
int i,type;
s4 len;
stackptr src, src_old;
int size_interface; /* == maximum size of in/out stack at basic block boundaries */
bool in_register;
+ /* get required compiler data */
+
+ m = jd->m;
+ cd = jd->cd;
+ rd = jd->rd;
+
in_register = true;
size_interface = 0;
while (bptr != NULL) {
if (bptr->flags >= BBREACHED) {
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
if (!opt_lsra) {
#endif
/* check for memory moves from interface to BB instack */
dst = dst->prev;
}
-#if defined(ENABLE_LSRA)
+#if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
}
#endif
} /* while blocks */
count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */
if (in_register) count_method_in_register++;
+ if (in_register) {
+ printf("INREGISTER: %s%s%s\n",m->class->name->text, m->name->text, m->descriptor->text);
+ }
}
#endif /* defined(ENABLE_STATISTICS) */