* src/vm/jit/alpha/emit.c [ENABLE_THREADS] (threads/native/lock.h):
[cacao.git] / src / vm / jit / stack.c
index ac8365c042e2ffc2d06870528f220a3d16598e31..beb5a6c8f78c77646fdccea52c6831e80c9f3053 100644 (file)
@@ -30,7 +30,7 @@
             Christian Thalinger
             Christian Ullrich
 
-   $Id: stack.c 5136 2006-07-14 17:05:12Z edwin $
+   $Id: stack.c 5251 2006-08-18 13:01:00Z twisti $
 
 */
 
@@ -55,6 +55,7 @@
 #include "vm/resolve.h"
 #include "vm/statistics.h"
 #include "vm/stringlocal.h"
+#include "vm/jit/cfg.h"
 #include "vm/jit/codegen-common.h"
 #include "vm/jit/abi.h"
 #include "vm/jit/show.h"
@@ -442,12 +443,12 @@ bool new_stack_analyse(jitdata *jd)
                bptr->type = BBTYPE_EXH;
                bptr->instack = new;
                bptr->indepth = 1;
-               bptr->pre_count = 10000;
+               bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
                STACKRESET;
                NEWXSTACK;
        }
 
-       /* count predecessors of each block **************************************/
+       /* count predecessors of each block ***************************************/
 
 #if CONDITIONAL_LOADCONST
        /* XXX move this to a separate function */
@@ -492,37 +493,37 @@ bool new_stack_analyse(jitdata *jd)
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:
                                        /* XXX add missing conditional branches */
-                                       bptr[1].pre_count++;
+                                       bptr[1].predecessorcount++;
                                        /* FALLTHROUGH */
 
                                        /* unconditional branch */
                                case ICMD_GOTO:
-                                       BLOCK_OF(iptr->dst.insindex)->pre_count++;
+                                       BLOCK_OF(iptr->dst.insindex)->predecessorcount++;
                                        break;
 
                                        /* switches */
                                case ICMD_TABLESWITCH:
                                        table = iptr->dst.table;
-                                       BLOCK_OF((table++)->insindex)->pre_count++;
+                                       BLOCK_OF((table++)->insindex)->predecessorcount++;
                                        i = iptr->sx.s23.s3.tablehigh
                                                - iptr->sx.s23.s2.tablelow + 1;
                                        while (--i >= 0) {
-                                               BLOCK_OF((table++)->insindex)->pre_count++;
+                                               BLOCK_OF((table++)->insindex)->predecessorcount++;
                                        }
                                        break;
 
                                case ICMD_LOOKUPSWITCH:
                                        lookup = iptr->dst.lookup;
-                                       BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->pre_count++;
+                                       BLOCK_OF(iptr->sx.s23.s3.lookupdefault.insindex)->predecessorcount++;
                                        i = iptr->sx.s23.s2.lookupcount;
                                        while (--i >= 0) {
-                                               BLOCK_OF((lookup++)->target.insindex)->pre_count++;
+                                               BLOCK_OF((lookup++)->target.insindex)->predecessorcount++;
                                        }
                                        break;
 
                                        /* default - fall into next block */
                                default:
-                                       bptr[1].pre_count++;
+                                       bptr[1].predecessorcount++;
                                        break;
                        } /* end switch */
                } /* end basic block loop */
@@ -549,7 +550,7 @@ bool new_stack_analyse(jitdata *jd)
 
                while (--b_count >= 0) {
 #if defined(STACK_VERBOSE)
-                       printf("ANALYZING BLOCK L%03d\n", bptr->debug_nr);
+                       printf("ANALYZING BLOCK L%03d\n", bptr->nr);
 #endif
 
                        if (bptr->flags == BBDELETED) {
@@ -653,18 +654,6 @@ icmd_NOP:
                                                CLR_DST; /* XXX live through? */
                                                break;
 
-                                       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_ELSE_ICONST:
-                                               USE_S1(TYPE_INT);
-                                               CLR_SX;
-                                               CLR_DST; /* XXX live through? */
-                                               break;
-
                                        case ICMD_RET:
                                                USE_S1_LOCAL(TYPE_ADR);
                                                CLR_SX;
@@ -2522,8 +2511,9 @@ icmd_BUILTIN:
                                                REQUIRE(i);
 
                                                /* XXX optimize for <= 2 args */
-                                               iptr->s1.argcount = i;
-                                               iptr->sx.s23.s2.args = DMNEW(stackptr, i);
+                                               /* XXX not for ICMD_BUILTIN */
+                                               iptr->s1.argcount = stackdepth;
+                                               iptr->sx.s23.s2.args = DMNEW(stackptr, stackdepth);
 
                                                copy = curstack;
                                                for (i-- ; i >= 0; i--) {
@@ -2579,11 +2569,19 @@ icmd_BUILTIN:
                                                        copy = copy->prev;
                                                }
 
+                                               /* deal with live-through stack slots "under" the arguments */
+                                               /* XXX not for ICMD_BUILTIN */
+
+                                               i = md->paramcount;
+
                                                while (copy) {
+                                                       iptr->sx.s23.s2.args[i++] = copy;
                                                        copy->flags |= SAVEDVAR;
                                                        copy = copy->prev;
                                                }
 
+                                               /* pop the arguments */
+
                                                i = md->paramcount;
 
                                                stackdepth -= i;
@@ -2591,6 +2589,8 @@ icmd_BUILTIN:
                                                        POPANY;
                                                }
 
+                                               /* push the return value */
+
                                                if (md->returntype.type != TYPE_VOID) {
                                                        NEW_DST(md->returntype.type, stackdepth);
                                                        stackdepth++;
@@ -2615,11 +2615,11 @@ icmd_BUILTIN:
 
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                               if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
-                                                       rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                               if (rd->memuse < (i + INT_ARG_CNT + LA_SIZE_IN_POINTERS))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                               if (rd->memuse < (i + LA_WORD_SIZE + 3))
-                                                       rd->memuse = i + LA_WORD_SIZE + 3;
+                                               if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
@@ -2643,9 +2643,9 @@ icmd_BUILTIN:
                                                                copy->flags |= INMEMORY;
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                                               copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                                               copy->regoff = i + LA_WORD_SIZE + 3;
+                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
@@ -2812,16 +2812,15 @@ icmd_BUILTIN:
 #if defined(ENABLE_VERIFIER)
 
 throw_stack_underflow:
-       *exceptionptr =
-               new_verifyerror(m, "Unable to pop operand off an empty stack");
+       exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
        return false;
 
 throw_stack_overflow:
-       *exceptionptr = new_verifyerror(m, "Stack size too large");
+       exceptions_throw_verifyerror(m, "Stack size too large");
        return false;
 
 throw_stack_depth_error:
-       *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
+       exceptions_throw_verifyerror(m,"Stack depth mismatch");
        return false;
 
 throw_stack_type_error:
@@ -2829,8 +2828,7 @@ throw_stack_type_error:
        return false;
 
 throw_stack_category_error:
-       *exceptionptr =
-               new_verifyerror(m, "Attempt to split long or double on the stack");
+       exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
        return false;
 
 #endif
@@ -2875,10 +2873,6 @@ bool stack_analyse(jitdata *jd)
        cd   = jd->cd;
        rd   = jd->rd;
 
-#if defined(ENABLE_LSRA)
-       m->maxlifetimes = 0;
-#endif
-
        last_store = DMNEW(s4 , cd->maxlocals * 5);
        
        new = m->stack;
@@ -2893,81 +2887,11 @@ bool stack_analyse(jitdata *jd)
                bptr->type = BBTYPE_EXH;
                bptr->instack = new;
                bptr->indepth = 1;
-               bptr->pre_count = 10000;
+               bptr->predecessorcount = CFG_UNKNOWN_PREDECESSORS;
                STACKRESET;
                NEWXSTACK;
        }
 
-#if CONDITIONAL_LOADCONST
-       b_count = m->basicblockcount;
-       bptr = m->basicblocks;
-       while (--b_count >= 0) {
-               if (bptr->icount != 0) {
-                       iptr = bptr->iinstr + bptr->icount - 1;
-                       switch (iptr->opc) {
-                       case ICMD_RET:
-                       case ICMD_RETURN:
-                       case ICMD_IRETURN:
-                       case ICMD_LRETURN:
-                       case ICMD_FRETURN:
-                       case ICMD_DRETURN:
-                       case ICMD_ARETURN:
-                       case ICMD_ATHROW:
-                               break;
-
-                       case ICMD_IFEQ:
-                       case ICMD_IFNE:
-                       case ICMD_IFLT:
-                       case ICMD_IFGE:
-                       case ICMD_IFGT:
-                       case ICMD_IFLE:
-
-                       case ICMD_IFNULL:
-                       case ICMD_IFNONNULL:
-
-                       case ICMD_IF_ICMPEQ:
-                       case ICMD_IF_ICMPNE:
-                       case ICMD_IF_ICMPLT:
-                       case ICMD_IF_ICMPGE:
-                       case ICMD_IF_ICMPGT:
-                       case ICMD_IF_ICMPLE:
-
-                       case ICMD_IF_ACMPEQ:
-                       case ICMD_IF_ACMPNE:
-                               bptr[1].pre_count++;
-                       case ICMD_GOTO:
-                               m->basicblocks[m->basicblockindex[iptr->op1]].pre_count++;
-                               break;
-
-                       case ICMD_TABLESWITCH:
-                               s4ptr = iptr->val.a;
-                               m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               i = *s4ptr++;                               /* low     */
-                               i = *s4ptr++ - i + 1;                       /* high    */
-                               while (--i >= 0) {
-                                       m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               }
-                               break;
-                                       
-                       case ICMD_LOOKUPSWITCH:
-                               s4ptr = iptr->val.a;
-                               m->basicblocks[m->basicblockindex[*s4ptr++]].pre_count++;
-                               i = *s4ptr++;                               /* count   */
-                               while (--i >= 0) {
-                                       m->basicblocks[m->basicblockindex[s4ptr[1]]].pre_count++;
-                                       s4ptr += 2;
-                               }
-                               break;
-                       default:
-                               bptr[1].pre_count++;
-                               break;
-                       }
-               }
-               bptr++;
-       }
-#endif /* CONDITIONAL_LOADCONST */
-
-
        do {
                loops++;
                b_count = m->basicblockcount;
@@ -3016,10 +2940,18 @@ bool stack_analyse(jitdata *jd)
                                while (--len >= 0)  {
                                        opcode = iptr->opc;
 
+                                       /* check if ICMD opcode could throw an exception        */
+                                       /* and if so remember the instruction index in last_pei */
+
+                                       if (op_data[opcode][PEI])
+                                               last_pei = bptr->icount - len - 1;
+
 #if defined(USEBUILTINTABLE)
 # if defined(ENABLE_INTRP)
                                        if (!opt_intrp) {
 # endif
+                                               /* check for opcodes to replace */
+
                                                bte = builtintable_get_automatic(opcode);
 
                                                if (bte && bte->opcode == opcode) {
@@ -3034,6 +2966,12 @@ bool stack_analyse(jitdata *jd)
 # endif
 #endif /* defined(USEBUILTINTABLE) */
 
+                                       /* Check for functions to replace with builtin
+                                          functions. */
+
+                                       if (builtintable_replace_function(iptr))
+                                               goto builtin;
+
                                        /* this is the main switch */
 
                                        switch (opcode) {
@@ -3043,14 +2981,6 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_CHECKNULL:
                                                COUNT(count_check_null);
                                        case ICMD_NOP:
-
-                                       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_ELSE_ICONST:
                                                SETDST;
                                                break;
 
@@ -4160,82 +4090,6 @@ bool stack_analyse(jitdata *jd)
                                        case ICMD_IFGT:
                                        case ICMD_IFLE:
                                                COUNT(count_pcmd_bra);
-#if CONDITIONAL_LOADCONST && 0
-# if defined(ENABLE_INTRP)
-                                               if (!opt_intrp) {
-# endif
-                                                       tbptr = m->basicblocks + b_index;
-
-                                                       if ((b_count >= 3) &&
-                                                               ((b_index + 2) == m->basicblockindex[iptr[0].op1]) &&
-                                                               (tbptr[1].pre_count == 1) &&
-                                                               (tbptr[1].iinstr[0].opc == ICMD_ICONST) &&
-                                                               (tbptr[1].iinstr[1].opc == ICMD_GOTO)   &&
-                                                               ((b_index + 3) == m->basicblockindex[tbptr[1].iinstr[1].op1]) &&
-                                                               (tbptr[2].pre_count == 1) &&
-                                                               (tbptr[2].iinstr[0].opc == ICMD_ICONST)  &&
-                                                               (tbptr[2].icount==1)) {
-                                                               /*printf("tbptr[2].icount=%d\n",tbptr[2].icount);*/
-                                                               OP1_1(TYPE_INT, TYPE_INT);
-                                                               switch (iptr[0].opc) {
-                                                               case ICMD_IFEQ:
-                                                                       iptr[0].opc = ICMD_IFNE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFNE:
-                                                                       iptr[0].opc = ICMD_IFEQ_ICONST;
-                                                                       break;
-                                                               case ICMD_IFLT:
-                                                                       iptr[0].opc = ICMD_IFGE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFGE:
-                                                                       iptr[0].opc = ICMD_IFLT_ICONST;
-                                                                       break;
-                                                               case ICMD_IFGT:
-                                                                       iptr[0].opc = ICMD_IFLE_ICONST;
-                                                                       break;
-                                                               case ICMD_IFLE:
-                                                                       iptr[0].opc = ICMD_IFGT_ICONST;
-                                                                       break;
-                                                               }
-#if 1
-                                                               iptr[0].val.i = iptr[1].val.i;
-                                                               iptr[1].opc = ICMD_ELSE_ICONST;
-                                                               iptr[1].val.i = iptr[3].val.i;
-                                                               iptr[2].opc = ICMD_NOP;
-                                                               iptr[3].opc = ICMD_NOP;
-#else
-                                                               /* HACK: save compare value in iptr[1].op1 */    
-                                                               iptr[1].op1 = iptr[0].val.i;     
-                                                               iptr[0].val.i = tbptr[1].iinstr[0].val.i;        
-                                                               iptr[1].opc = ICMD_ELSE_ICONST;          
-                                                               iptr[1].val.i = tbptr[2].iinstr[0].val.i;        
-                                                               tbptr[1].iinstr[0].opc = ICMD_NOP;       
-                                                               tbptr[1].iinstr[1].opc = ICMD_NOP;       
-                                                               tbptr[2].iinstr[0].opc = ICMD_NOP;       
-#endif
-                                                               tbptr[1].flags = BBDELETED;
-                                                               tbptr[2].flags = BBDELETED;
-                                                               tbptr[1].icount = 0;
-                                                               tbptr[2].icount = 0;
-                                                               if (tbptr[3].pre_count == 2) {
-                                                                       len += tbptr[3].icount + 3;
-                                                                       bptr->icount += tbptr[3].icount + 3;
-                                                                       tbptr[3].flags = BBDELETED;
-                                                                       tbptr[3].icount = 0;
-                                                                       b_index++;
-                                                               }
-                                                               else {
-                                                                       bptr->icount++;
-                                                                       len ++;
-                                                               }
-                                                               b_index += 2;
-                                                               break;
-                                                       }
-# if defined(ENABLE_INTRP)
-                                               }
-# endif
-
-#endif /* CONDITIONAL_LOADCONST */
 
                                                /* iptr->val.i is set implicitly in parse by
                                                   clearing the memory or from IF_ICMPxx
@@ -5034,9 +4888,7 @@ bool stack_analyse(jitdata *jd)
                                        /* pop many push any */
 
                                        case ICMD_BUILTIN:
-#if defined(USEBUILTINTABLE)
                                        builtin:
-#endif
                                                bte = (builtintable_entry *) iptr->val.a;
                                                md = bte->md;
                                                goto _callhandling;
@@ -5052,7 +4904,7 @@ bool stack_analyse(jitdata *jd)
 
                                        _callhandling:
 
-                                               last_pei = bptr->icount - len - 1;
+/*                                             last_pei = bptr->icount - len - 1; */
 
                                                i = md->paramcount;
 
@@ -5141,11 +4993,11 @@ bool stack_analyse(jitdata *jd)
                                                REQUIRE(i);
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                               if (rd->memuse < (i + INT_ARG_CNT + LA_WORD_SIZE))
-                                                       rd->memuse = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                               if (rd->memuse < (i + INT_ARG_CNT + LA_SIZE_IN_POINTERS))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                               if (rd->memuse < (i + LA_WORD_SIZE + 3))
-                                                       rd->memuse = i + LA_WORD_SIZE + 3;
+                                               if (rd->memuse < (i + LA_SIZE_IN_POINTERS + 3))
+                                                       rd->memuse = i + LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
@@ -5168,9 +5020,9 @@ bool stack_analyse(jitdata *jd)
                                                                copy->flags |= INMEMORY;
 #if defined(SPECIALMEMUSE)
 # if defined(__DARWIN__)
-                                                               copy->regoff = i + LA_WORD_SIZE + INT_ARG_CNT;
+                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + INT_ARG_CNT;
 # else
-                                                               copy->regoff = i + LA_WORD_SIZE + 3;
+                                                               copy->regoff = i + LA_SIZE_IN_POINTERS + 3;
 # endif
 #else
 # if defined(__I386__)
@@ -5327,16 +5179,15 @@ bool stack_analyse(jitdata *jd)
 #if defined(ENABLE_VERIFIER)
 
 throw_stack_underflow:
-       *exceptionptr =
-               new_verifyerror(m, "Unable to pop operand off an empty stack");
+       exceptions_throw_verifyerror(m, "Unable to pop operand off an empty stack");
        return false;
 
 throw_stack_overflow:
-       *exceptionptr = new_verifyerror(m, "Stack size too large");
+       exceptions_throw_verifyerror(m, "Stack size too large");
        return false;
 
 throw_stack_depth_error:
-       *exceptionptr = new_verifyerror(m,"Stack depth mismatch");
+       exceptions_throw_verifyerror(m, "Stack depth mismatch");
        return false;
 
 throw_stack_type_error:
@@ -5344,8 +5195,7 @@ throw_stack_type_error:
        return false;
 
 throw_stack_category_error:
-       *exceptionptr =
-               new_verifyerror(m, "Attempt to split long or double on the stack");
+       exceptions_throw_verifyerror(m, "Attempt to split long or double on the stack");
        return false;
 
 #endif