X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fvm%2Fjit%2Freg.inc;h=639e5176f939c7c52f672b9c414e34f6715b777a;hb=e8c1205458c3b3a2ab8d250dfe1c9738765928cf;hp=f027d8aa2187b7c9229bce3681a7f4f673a0a045;hpb=769052a5eb14575d74a0f813a584e35352c713a7;p=cacao.git diff --git a/src/vm/jit/reg.inc b/src/vm/jit/reg.inc index f027d8aa2..639e5176f 100644 --- a/src/vm/jit/reg.inc +++ b/src/vm/jit/reg.inc @@ -1,10 +1,9 @@ -/* jit/reg.inc - register allocator +/* src/vm/jit/reg.inc - register allocator - Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 - Institut f. Computersprachen, TU Wien - R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst, - S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, - J. Wenninger + Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, + R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, + C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, + Institut f. Computersprachen - TU Wien This file is part of CACAO. @@ -30,13 +29,14 @@ Changes: Stefan Ring Christian Thalinger - $Id: reg.inc 1459 2004-11-05 16:23:02Z twisti $ + $Id: reg.inc 2219 2005-04-05 15:42:57Z christian $ */ -#include "jit/reg.h" -#include "toolbox/memory.h" +#include "arch.h" +#include "mm/memory.h" +#include "vm/jit/reg.h" /* function prototypes for this file */ @@ -88,14 +88,14 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) } } - rd->argintregs = MNEW(s4, rd->intreg_argnum); - rd->tmpintregs = MNEW(s4, rd->tmpintregcnt); - rd->savintregs = MNEW(s4, rd->savintregcnt); - rd->freeargintregs = MNEW(s4, rd->intreg_argnum); - rd->freetmpintregs = MNEW(s4, rd->tmpintregcnt); - rd->freesavintregs = MNEW(s4, rd->savintregcnt); + rd->argintregs = DMNEW(s4, rd->intreg_argnum); + rd->tmpintregs = DMNEW(s4, rd->tmpintregcnt); + rd->savintregs = DMNEW(s4, rd->savintregcnt); + rd->freeargintregs = DMNEW(s4, rd->intreg_argnum); + rd->freetmpintregs = DMNEW(s4, rd->tmpintregcnt); + rd->freesavintregs = DMNEW(s4, rd->savintregcnt); #ifdef USETWOREGS - rd->secondregs = MNEW(s4, rd->intregsnum); + rd->secondregs = DMNEW(s4, rd->intregsnum); #endif rd->intreg_argnum = 0; @@ -112,7 +112,7 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) rd->savintregs[rd->savintreguse++] = i; break; case REG_TMP: - rd->tmpintregs[rd->tmpintreguse++] = i; + rd->tmpintregs[rd->tmpintreguse++] = i; break; case REG_ARG: rd->argintregs[rd->intreg_argnum++] = i; @@ -149,13 +149,70 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) rd->secondregs[rd->argintregs[rd->intreg_argnum - 1]] = REG_ITMP3; #endif +#ifdef HAS_ADDRESS_REGISTER_FILE + /* setup the address register table */ + rd->adrreg_argnum = 0; + rd->tmpadrregcnt = 0; + rd->savadrregcnt = 0; + + for (rd->adrregsnum = 0; nregdescadr[rd->adrregsnum] != REG_END; rd->adrregsnum++) { + switch (nregdescadr[rd->adrregsnum]) { + case REG_SAV: + rd->savadrregcnt++; + break; + case REG_TMP: + rd->tmpadrregcnt++; + break; + case REG_ARG: + rd->adrreg_argnum++; + break; + } + } + + rd->argadrregs = DMNEW(s4, rd->adrreg_argnum); + rd->tmpadrregs = DMNEW(s4, rd->tmpadrregcnt); + rd->savadrregs = DMNEW(s4, rd->savadrregcnt); + rd->freeargadrregs = DMNEW(s4, rd->adrreg_argnum); + rd->freetmpadrregs = DMNEW(s4, rd->tmpadrregcnt); + rd->freesavadrregs = DMNEW(s4, rd->savadrregcnt); + + rd->adrreg_argnum = 0; + rd->argadrreguse = 0; + rd->tmpadrreguse = 0; + rd->savadrreguse = 0; + + for (i = 0; i < rd->adrregsnum; i++) { + switch (nregdescadr[i]) { + case REG_RET: + rd->adrreg_ret = i; + break; + case REG_SAV: + rd->savadrregs[rd->savadrreguse++] = i; + break; + case REG_TMP: + rd->tmpadrregs[rd->tmpadrreguse++] = i; + break; + case REG_ARG: + rd->argadrregs[rd->adrreg_argnum++] = i; + rd->argadrreguse++; + break; + } + } + +/* #if defined(????) */ + /* + * on xdsp the argument registers are in ascending order ??? + */ +/* #endif */ +#endif + /* setup the float register table */ rd->fltreg_argnum = 0; rd->tmpfltregcnt = 0; rd->savfltregcnt = 0; - for (rd->floatregsnum = 0; nregdescfloat[rd->floatregsnum] != REG_END; rd->floatregsnum++) { - switch (nregdescfloat[rd->floatregsnum]) { + for (rd->fltregsnum = 0; nregdescfloat[rd->fltregsnum] != REG_END; rd->fltregsnum++) { + switch (nregdescfloat[rd->fltregsnum]) { case REG_SAV: rd->savfltregcnt++; break; @@ -168,22 +225,22 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) } } - rd->argfltregs = MNEW(s4, rd->fltreg_argnum); - rd->tmpfltregs = MNEW(s4, rd->tmpfltregcnt); - rd->savfltregs = MNEW(s4, rd->savfltregcnt); - rd->freeargfltregs = MNEW(s4, rd->fltreg_argnum); - rd->freetmpfltregs = MNEW(s4, rd->tmpfltregcnt); - rd->freesavfltregs = MNEW(s4, rd->savfltregcnt); + rd->argfltregs = DMNEW(s4, rd->fltreg_argnum); + rd->tmpfltregs = DMNEW(s4, rd->tmpfltregcnt); + rd->savfltregs = DMNEW(s4, rd->savfltregcnt); + rd->freeargfltregs = DMNEW(s4, rd->fltreg_argnum); + rd->freetmpfltregs = DMNEW(s4, rd->tmpfltregcnt); + rd->freesavfltregs = DMNEW(s4, rd->savfltregcnt); rd->fltreg_argnum = 0; rd->argfltreguse = 0; rd->tmpfltreguse = 0; rd->savfltreguse = 0; - for (i = 0; i < rd->floatregsnum; i++) { + for (i = 0; i < rd->fltregsnum; i++) { switch (nregdescfloat[i]) { case REG_RET: - rd->floatreg_ret = i; + rd->fltreg_ret = i; break; case REG_SAV: rd->savfltregs[rd->savfltreguse++] = i; @@ -199,9 +256,9 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) } - rd->freemem = MNEW(s4, id->cummaxstack); - rd->locals = MNEW(varinfo5, id->cumlocals); - rd->interfaces = MNEW(varinfo5, id->cummaxstack); + rd->freemem = DMNEW(s4, id->cummaxstack); + rd->locals = DMNEW(varinfo5, id->cumlocals); + rd->interfaces = DMNEW(varinfo5, id->cummaxstack); for (v = rd->locals, i = id->cumlocals; i > 0; v++, i--) { v[0][TYPE_INT].type = -1; @@ -223,6 +280,11 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) v[0][TYPE_ADR].type = -1; v[0][TYPE_ADR].flags = 0; } +#ifdef SPECIALMEMUSE + rd->ifmemuse = 6; +#else + rd->ifmemuse = 0; /* init to zero -> analyse_stack will set it to a higher value, if appropriate */ +#endif } @@ -234,27 +296,7 @@ void reg_setup(methodinfo *m, registerdata *rd, t_inlining_globals *id) void reg_free(methodinfo *m, registerdata *rd) { - if (rd->argintregs) MFREE(rd->argintregs, s4, rd->intreg_argnum); - if (rd->argfltregs) MFREE(rd->argfltregs, s4, rd->fltreg_argnum); - if (rd->tmpintregs) MFREE(rd->tmpintregs, s4, rd->tmpintregcnt); - if (rd->savintregs) MFREE(rd->savintregs, s4, rd->savintregcnt); - if (rd->tmpfltregs) MFREE(rd->tmpfltregs, s4, rd->tmpfltregcnt); - if (rd->savfltregs) MFREE(rd->savfltregs, s4, rd->savfltregcnt); - - if (rd->freeargintregs) MFREE(rd->freeargintregs, s4, rd->intreg_argnum); - if (rd->freeargfltregs) MFREE(rd->freeargfltregs, s4, rd->fltreg_argnum); - if (rd->freetmpintregs) MFREE(rd->freetmpintregs, s4, rd->tmpintregcnt); - if (rd->freesavintregs) MFREE(rd->freesavintregs, s4, rd->savintregcnt); - if (rd->freetmpfltregs) MFREE(rd->freetmpfltregs, s4, rd->tmpfltregcnt); - if (rd->freesavfltregs) MFREE(rd->freesavfltregs, s4, rd->savfltregcnt); - -#ifdef USETWOREGS - if (rd->secondregs) MFREE(rd->secondregs, s4, rd->intregsnum); -#endif - - if (rd->freemem) MFREE(rd->freemem, s4, m->maxstack); - if (rd->locals) MFREE(rd->locals, varinfo5, m->maxlocals); - if (rd->interfaces) MFREE(rd->interfaces, varinfo5, m->maxstack); + /* void */ } @@ -293,34 +335,44 @@ void regalloc(methodinfo *m, codegendata *cd, registerdata *rd) static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) { int s, t, saved; - int intalloc, fltalloc; + int intalloc, fltalloc; /* ?per Interface slot only one flt or one int type can be allocated to a register? */ varinfo *v; int regsneeded = 0; /* allocate stack space for passing arguments to called methods */ +#ifdef INVOKE_NEW_DEBUG + int temp; + + if (compileverbose) { + temp = rd->ifmemuse; +#if !defined(SPECIALMEMUSE) + /* For this to work properly the integer argument register count must be */ + /* less or equal the float argument register count (e.g. x86_64). */ + /* (arch.h: INT_ARG_CNT <= FLT_ARG_CNT) */ + if (rd->arguments_num > INT_ARG_CNT) { + rd->ifmemuse = rd->arguments_num - INT_ARG_CNT; -#ifndef SPECIALMEMUSE -#if defined(__X86_64__) - /* - * XXX: we have a problem here, but allocating a little more stack space - * is better than having a bug - */ - /* if (arguments_num > (intreg_argnum + fltreg_argnum)) */ - /* ifmemuse = arguments_num - (intreg_argnum + fltreg_argnum); */ - if (rd->arguments_num > rd->fltreg_argnum) - rd->ifmemuse = rd->arguments_num - rd->fltreg_argnum; -#else - if (rd->arguments_num > rd->intreg_argnum) - rd->ifmemuse = rd->arguments_num - rd->intreg_argnum; + } else { + rd->ifmemuse = 0; + } #endif - else - rd->ifmemuse = 0; + if (compileverbose) { + printf("ifmemuse by reg.inc: %3i,%3i by stack.c: %3i\n",rd->ifmemuse, rd->maxmemuse,temp); + if (temp != rd->ifmemuse) + printf("Warning: Difference in ifmemuse calculated the old way and the new way\n"); + } + rd->ifmemuse = temp; + } #endif rd->iftmpintregcnt = rd->tmpintregcnt; rd->ifsavintregcnt = rd->savintregcnt; rd->iftmpfltregcnt = rd->tmpfltregcnt; rd->ifsavfltregcnt = rd->savfltregcnt; +#ifdef HAS_ADDRESS_REGISTER_FILE + rd->iftmpadrregcnt = rd->tmpadrregcnt; + rd->ifsavadrregcnt = rd->savadrregcnt; +#endif for (s = 0; s < cd->maxstack; s++) { intalloc = -1; fltalloc = -1; @@ -337,6 +389,23 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0; #endif if (!saved) { +#ifdef HAS_ADDRESS_REGISTER_FILE + if (t == TYPE_ADR) { + if (rd->iftmpadrregcnt > 0) { + rd->iftmpadrregcnt--; + v->regoff = rd->tmpadrregs[rd->iftmpadrregcnt]; + } + else if (rd->ifsavadrregcnt > 0) { + rd->ifsavadrregcnt--; + v->regoff = rd->savadrregs[rd->ifsavadrregcnt]; + } + else { + v->flags |= INMEMORY; + v->regoff = rd->ifmemuse; + rd->ifmemuse += regsneeded + 1; + } + } else { +#endif if (IS_FLT_DBL_TYPE(t)) { if (fltalloc >= 0) { v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY; @@ -389,8 +458,24 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) #endif intalloc = t; } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif } else { +#ifdef HAS_ADDRESS_REGISTER_FILE + if (t == TYPE_ADR) { + if (rd->ifsavadrregcnt > 0) { + rd->ifsavadrregcnt--; + v->regoff = rd->savadrregs[rd->ifsavadrregcnt]; + } + else { + v->flags |= INMEMORY; + v->regoff = rd->ifmemuse; + rd->ifmemuse += regsneeded + 1; + } + } else { +#endif if (IS_FLT_DBL_TYPE(t)) { if (fltalloc >= 0) { v->flags |= rd->interfaces[s][fltalloc].flags & INMEMORY; @@ -435,6 +520,9 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) #endif intalloc = t; } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif } } /* if (type >= 0) */ } /* for t */ @@ -447,6 +535,11 @@ static void interface_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) rd->maxargfltreguse = -1; rd->maxtmpfltreguse = rd->iftmpfltregcnt; rd->maxsavfltreguse = rd->ifsavfltregcnt; +#ifdef HAS_ADDRESS_REGISTER_FILE + rd->maxargadrreguse = -1; + rd->maxtmpadrreguse = rd->iftmpadrregcnt; + rd->maxsavadrreguse = rd->ifsavadrregcnt; +#endif } @@ -467,8 +560,14 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) if (m->isleafmethod) { int arg, doublewordarg, iargcnt, fargcnt; +#ifdef HAS_ADDRESS_REGISTER_FILE + int aargcnt; +#endif arg = 0, iargcnt = 0, fargcnt = 0; +#ifdef HAS_ADDRESS_REGISTER_FILE + aargcnt = 0; +#endif doublewordarg = 0; for (s = 0; s < cd->maxlocals; s++) { intalloc = -1; fltalloc = -1; @@ -479,6 +578,33 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) if (v->type >= 0) { #ifdef USETWOREGS regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0; +#endif +#ifdef HAS_ADDRESS_REGISTER_FILE + if (t == TYPE_ADR) { + /* doublewordarg not possible for xdsp */ +#if !defined(CONSECUTIVE_ADDRESSARGS) + aargcnt = arg; +#endif + if ((arg < m->paramcount) && (aargcnt < rd->adrreg_argnum)) { + v->flags = 0; + v->regoff = rd->argadrregs[aargcnt]; + } + if (rd->maxtmpadrreguse > 0) { + rd->maxtmpadrreguse--; + v->flags = 0; + v->regoff = rd->tmpadrregs[rd->maxtmpadrreguse]; + } + else if (rd->maxsavadrreguse > 0) { + rd->maxsavadrreguse--; + v->flags = 0; + v->regoff = rd->savadrregs[rd->maxsavadrreguse]; + } + else { + v->flags |= INMEMORY; + v->regoff = rd->ifmemuse; + rd->ifmemuse += regsneeded + 1; + } + } else { #endif if (IS_FLT_DBL_TYPE(t)) { #if !defined(CONSECUTIVE_FLOATARGS) @@ -568,6 +694,9 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) #endif intalloc = t; } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif } } if (arg < m->paramcount) { @@ -586,12 +715,20 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) doublewordarg = 1; } else { +#ifdef HAS_ADDRESS_REGISTER_FILE + if ( TYPE_ADR == m->paramtypes[arg] ) { + aargcnt++; + } else { +#endif if (IS_FLT_DBL_TYPE(m->paramtypes[arg])) { fargcnt++; } else { iargcnt++; } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif arg++; } } @@ -607,6 +744,20 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) if (v->type >= 0) { #ifdef USETWOREGS regsneeded = (IS_2_WORD_TYPE(t)) ? 1 : 0; +#endif +#ifdef HAS_ADDRESS_REGISTER_FILE + if ( t == TYPE_ADR ) { + if (rd->maxsavadrreguse > 0) { + rd->maxsavadrreguse--; + v->flags = 0; + v->regoff = rd->savadrregs[rd->maxsavadrreguse]; + } + else { + v->flags = INMEMORY; + v->regoff = rd->maxmemuse; + rd->maxmemuse += regsneeded + 1; + } + } else { #endif if (IS_FLT_DBL_TYPE(t)) { if (fltalloc >= 0) { @@ -654,13 +805,15 @@ static void local_regalloc(methodinfo *m, codegendata *cd, registerdata *rd) #endif intalloc = t; } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif + } } } } - - static void reg_init_temp(registerdata *rd) { rd->freememtop = 0; @@ -670,15 +823,28 @@ static void reg_init_temp(registerdata *rd) rd->freesavinttop = 0; rd->freetmpflttop = 0; rd->freesavflttop = 0; +#ifdef HAS_ADDRESS_REGISTER_FILE + rd->freetmpadrtop = 0; + rd->freesavadrtop = 0; +#endif rd->tmpintreguse = rd->iftmpintregcnt; rd->savintreguse = rd->ifsavintregcnt; rd->tmpfltreguse = rd->iftmpfltregcnt; rd->savfltreguse = rd->ifsavfltregcnt; +#ifdef HAS_ADDRESS_REGISTER_FILE + rd->tmpadrreguse = rd->iftmpadrregcnt; + rd->savadrreguse = rd->ifsavadrregcnt; +#endif +#if defined(USE_UNUSED_ARGUMENT_REGISTERS) /* all argument registers are available */ rd->argintreguse = rd->intreg_argnum; rd->argfltreguse = rd->fltreg_argnum; +#ifdef HAS_ADDRESS_REGISTER_FILE + rd->argadrreguse = rd->adrreg_argnum; +#endif +#endif /*defined(USE_UNUSED_ARGUMENT_REGISTERS)*/ } @@ -704,6 +870,22 @@ static void reg_new_temp_func(registerdata *rd, stackptr s) if (tryagain == 1) { if (!(s->flags & SAVEDVAR)) s->flags |= SAVEDTMP; +#ifdef HAS_ADDRESS_REGISTER_FILE + if (s->type == TYPE_ADR) { + if (rd->freesavadrtop > 0) { + rd->freesavadrtop--; + s->regoff = rd->freesavadrregs[rd->freesavadrtop]; + return; + + } else if (rd->savadrreguse > 0) { + rd->savadrreguse--; + if (rd->savadrreguse < rd->maxsavadrreguse) + rd->maxsavadrreguse = rd->savadrreguse; + s->regoff = rd->savadrregs[rd->savadrreguse]; + return; + } + } else { +#endif if (IS_FLT_DBL_TYPE(s->type)) { if (rd->freesavflttop > 0) { rd->freesavflttop--; @@ -741,8 +923,26 @@ static void reg_new_temp_func(registerdata *rd, stackptr s) } #endif } - +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif } else { +#ifdef HAS_ADDRESS_REGISTER_FILE + if (s->type == TYPE_ADR) { + if (rd->freetmpadrtop > 0) { + rd->freetmpadrtop--; + s->regoff = rd->freetmpadrregs[rd->freetmpadrtop]; + return; + + } else if (rd->tmpadrreguse > 0) { + rd->tmpadrreguse--; + if (rd->tmpadrreguse < rd->maxtmpadrreguse) + rd->maxtmpadrreguse = rd->tmpadrreguse; + s->regoff = rd->tmpadrregs[rd->tmpadrreguse]; + return; + } + } else { +#endif if (IS_FLT_DBL_TYPE(s->type)) { if (rd->freetmpflttop > 0) { rd->freetmpflttop--; @@ -780,6 +980,9 @@ static void reg_new_temp_func(registerdata *rd, stackptr s) } #endif } +#ifdef HAS_ADDRESS_REGISTER_FILE + } +#endif } } @@ -816,6 +1019,15 @@ static void reg_free_temp_func(registerdata *rd, stackptr s) rd->freemem[rd->freememtop + 1] = s->regoff + 1; rd->freememtop += regsneeded + 1; +#ifdef HAS_ADDRESS_REGISTER_FILE + } else if (s->type == TYPE_ADR) { + if (s->flags & (SAVEDVAR | 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; @@ -887,6 +1099,9 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) case ICMD_RET: case ICMD_RETURN: case ICMD_GOTO: + case ICMD_PUTSTATICCONST: + case ICMD_INLINE_START: + case ICMD_INLINE_END: break; /* pop 0 push 1 const */ @@ -960,6 +1175,7 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) case ICMD_ATHROW: case ICMD_PUTSTATIC: + case ICMD_PUTFIELDCONST: /* pop 1 push 0 branch */ @@ -1154,6 +1370,7 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) case ICMD_IADDCONST: case ICMD_ISUBCONST: case ICMD_IMULCONST: + case ICMD_IMULPOW2: case ICMD_IDIVPOW2: case ICMD_IREMPOW2: case ICMD_IANDCONST: @@ -1166,6 +1383,7 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) case ICMD_LADDCONST: case ICMD_LSUBCONST: case ICMD_LMULCONST: + case ICMD_LMULPOW2: case ICMD_LDIVPOW2: case ICMD_LREMPOW2: case ICMD_LANDCONST: @@ -1273,6 +1491,156 @@ static void allocate_scratch_registers(methodinfo *m, registerdata *rd) } +#ifdef STATISTICS +void reg_make_statistics( methodinfo *m, codegendata *cd, registerdata *rd) { + int i,type; + s4 len; + stackptr src, src_old; + stackptr dst; + instruction *iptr; + basicblock *bptr; + int size_interface; /* == maximum size of in/out stack at basic block boundaries */ + bool in_register; + + in_register = true; + + size_interface = 0; + + /* count how many local variables are held in memory or register */ + for(i=0; i < cd->maxlocals; i++) + for (type=0; type <=4; type++) + if (rd->locals[i][type].type != -1) { /* valid local */ + if (rd->locals[i][type].flags & INMEMORY) { + count_locals_spilled++; + in_register=false; + } + else + count_locals_register++; + } + /* count how many stack slots are held in memory or register */ + + bptr = m->basicblocks; + while (bptr != NULL) { + if (bptr->flags >= BBREACHED) { + +#ifdef LSRA + if (!opt_lsra) { +#endif + /* check for memory moves from interface to BB instack */ + dst = bptr->instack; + len = bptr->indepth; + + if (len > size_interface) size_interface = len; + + while (dst != NULL) { + len--; + if (dst->varkind != STACKVAR) { + if ( (dst->flags & INMEMORY) || + (rd->interfaces[len][dst->type].flags & INMEMORY) || + ( (dst->flags & INMEMORY) && + (rd->interfaces[len][dst->type].flags & INMEMORY) && + (dst->regoff != rd->interfaces[len][dst->type].regoff) )) + { + /* one in memory or both inmemory at different offsets */ + count_mem_move_bb++; + in_register=false; + } + } + + dst = dst->prev; + } + + /* check for memory moves from BB outstack to interface */ + dst = bptr->outstack; + len = bptr->outdepth; + if (len > size_interface) size_interface = len; + + while (dst) { + len--; + if (dst->varkind != STACKVAR) { + if ( (dst->flags & INMEMORY) || \ + (rd->interfaces[len][dst->type].flags & INMEMORY) || \ + ( (dst->flags & INMEMORY) && \ + (rd->interfaces[len][dst->type].flags & INMEMORY) && \ + (dst->regoff != rd->interfaces[len][dst->type].regoff) )) + { + /* one in memory or both inmemory at different offsets */ + count_mem_move_bb++; + in_register=false; + } + } + + dst = dst->prev; + } +#ifdef LSRA + } +#endif + + + dst = bptr->instack; + iptr = bptr->iinstr; + len = bptr->icount; + src_old = NULL; + + while (--len >= 0) { + src = dst; + dst = iptr->dst; + + if ((src!= NULL) && (src != src_old)) { /* new stackslot */ + switch (src->varkind) { + case TEMPVAR: + case STACKVAR: + if (!(src->flags & INMEMORY)) + count_ss_register++; + else { + count_ss_spilled++; + in_register=false; + } + break; + /* case LOCALVAR: */ + /* if (!(rd->locals[src->varnum][src->type].flags & INMEMORY)) */ + /* count_ss_register++; */ + /* else */ + /* count_ss_spilled++; */ + /* break; */ + case ARGVAR: + if (!(src->flags & INMEMORY)) + count_argument_mem_ss++; + else + count_argument_reg_ss++; + break; + + + /* if (IS_FLT_DBL_TYPE(src->type)) { */ + /* if (src->varnum < FLT_ARG_CNT) { */ + /* count_ss_register++; */ + /* break; */ + /* } */ + /* } else { */ + /* #if defined(__POWERPC__) */ + /* if (src->varnum < INT_ARG_CNT - (IS_2_WORD_TYPE(src->type) != 0)) { */ + /* #else */ + /* if (src->varnum < INT_ARG_CNT) { */ + /* #endif */ + /* count_ss_register++; */ + /* break; */ + /* } */ + /* } */ + /* count_ss_spilled++; */ + /* break; */ + } + } + src_old = src; + + iptr++; + } /* while instructions */ + } /* if */ + bptr = bptr->next; + } /* while blocks */ + count_interface_size += size_interface; /* accummulate the size of the interface (between bb boundaries) */ + if (in_register) count_method_in_register++; +} +#endif /* * These are local overrides for various environment variables in Emacs. * Please do not remove this and leave it at the end of the file, where