Merged revisions 7797-7917 via svnmerge from
[cacao.git] / src / vm / jit / optimizing / graph.c
index 88a8963eb4026c5949a9e2d21170dae69228700d..461cca8e60b64d29423f001f35c9d324193daeaa 100644 (file)
 
 */
 
+#include <stdlib.h>
+
+#include "config.h"
+
 #include "mm/memory.h"
 
 #include "toolbox/bitvector.h"
 
+#include "vm/jit/jit.h"
+
 #include "vm/jit/optimizing/lsra.h"
 #include "vm/jit/optimizing/ssa.h"
 #include "vm/jit/optimizing/graph.h"
 
 #ifdef GRAPH_DEBUG_VERBOSE
-#include "vm/options.h"
+#include "vmcore/options.h"
 #endif
 
-
 /* Helpers for graph_make_cfg */
-void graph_add_jsr( methodinfo *m, graphdata *gd, struct _sbr *sbr,int from,
-                                       int to);
-void graph_add_cfg( methodinfo *m, graphdata *gd, int from, int to);
-void graph_add_exceptions(methodinfo *m, codegendata *cd, graphdata *gd); 
-void graph_add_subs(methodinfo *m, graphdata *gd, struct _sbr *sbr);
+void graph_add_cfg( jitdata *jd, graphdata *gd, basicblock *, basicblock *);
+void graph_add_exceptions(jitdata *jd, graphdata *gd); 
 void graph_add_edge( graphdata *gd, int from, int to );
-/* Helper for graph_make_subs */
-void graph_add_sub( methodinfo *m, graphdata *gd, int b_index,
-                                       graph_element *ret, bool *visited );
+
 /* Helper for graph_get_first_* */
 int graph_get_first_(graph_element *ge, graphiterator *i);
 void transform_CFG(jitdata *, graphdata *);
@@ -161,35 +161,43 @@ void graph_add_edge( graphdata *gd, int from, int to ) {
        gd->num_pred[to]++;
 }
 
-/* split the edge from BB from shown by iterator i wiht new_block */
+/* split the edge from BB from shown by iterator i with new_block */
 void graph_split_edge(graphdata *gd, int from, graphiterator *i, int new_block) {
        graphiterator i_pred;
        graph_element *n;
        int l, succ;
 
        /* i->value is the BB index of the "old" successor */
+
        succ = (*i)->value;
+
        /* search for iterator showing predecessor edge from BB succ back to */
        /* from */
+
        l = graph_get_first_predecessor(gd, succ, &i_pred);
        for(; (l != -1) && (l != from); l = graph_get_next(&i_pred));
        _GRAPH_ASSERT(l == from);
 
        /* change CFG entries */
+
        (*i)->value = new_block;
        i_pred->value = new_block;
 
        /* and insert the CFG successor and predecesser entries for new_block */
        /* 2 entries needed */
+
        n = DMNEW(graph_element, 2);
+
        /* make the successor entry for new_block */
+
        n->value = succ;
        n->next = gd->successor[new_block];
        gd->successor[new_block] = n;
        gd->num_succ[new_block]++;
 
-       n++;
        /* make the predecessor entry for new_block */
+
+       n++;
        n->value = from;
        n->next = gd->predecessor[new_block];
        gd->predecessor[new_block] = n;
@@ -201,42 +209,35 @@ Generate the Control Flow Graph
 ( pred,succ,num_pred of lsradata structure) 
 ************************************************/
 void graph_make_cfg(jitdata *jd,graphdata *gd) {
-       instruction *ip;
-       s4 *s4ptr;
-       int high, low, count;
-       int b_index, len;
-       bool fall_through;
-       struct _sbr sbr; /* list of subroutines, sorted by header */
+       instruction *iptr;
+       lookup_target_t *lookup;
+       branch_target_t *table;
+       int len, i, l;
        methodinfo *m;
        codegendata *cd;
        registerdata *rd;
        lsradata *ls;
+       basicblock *bptr;
 
        m = jd->m;
        cd = jd->cd;
        rd = jd->rd;
        ls = jd->ls;
 
-       sbr.next = NULL;
-
        /* Add edge from new Basic Block 0 (parameter initialization) */
        graph_add_edge(gd, 0, 1);
 
-       b_index=0;
-       while (b_index < m->basicblockcount ) {
-               if (m->basicblocks[b_index].flags >= BBREACHED) {
-                       fall_through = false;
-                                                                       
-                       if ((len = m->basicblocks[b_index].icount)) {
-                               /* set ip to last non NOP instruction   */
-                               ip = m->basicblocks[b_index].iinstr +
-                                       m->basicblocks[b_index].icount -1;
-                               while ((len>0) && (ip->opc == ICMD_NOP)) {
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+               if (bptr->flags >= BBREACHED) {
+                       if ((len = bptr->icount)) {
+                               /* set iptr to last non NOP instruction */
+                               iptr = bptr->iinstr + bptr->icount -1;
+                               while ((len>0) && (iptr->opc == ICMD_NOP)) {
                                        len--;
-                                       ip--;
+                                       iptr--;
                                }
                                /* block contains instructions  */
-                               switch (ip->opc) {                      /* check type of last instruction */
+                               switch (iptr->opc) {            /* check type of last instruction */
                                case ICMD_RETURN:
                                case ICMD_IRETURN:
                                case ICMD_LRETURN:
@@ -244,7 +245,6 @@ void graph_make_cfg(jitdata *jd,graphdata *gd) {
                                case ICMD_DRETURN:
                                case ICMD_ARETURN:
                                case ICMD_ATHROW:
-/*                                     graph_add_cfg(m, gd, b_index, m->basicblockcount); */
                                        break;                            /* function returns -> end of graph */
 
                                case ICMD_IFNULL:
@@ -275,70 +275,65 @@ void graph_make_cfg(jitdata *jd,graphdata *gd) {
                                case ICMD_IF_LCMPLE:
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:                /* branch -> add next block */
-                                       fall_through = true;
-/*                                     graph_add_cfg(m, gd, b_index, b_index+1); */
-                                       /* fall throu -> add branch target */
+                                       /* Add branch target */
+                                       graph_add_cfg(jd, gd, bptr, iptr->dst.block);
+                                       /* Add fall through path */
+                                       graph_add_cfg(jd, gd, bptr, bptr->next);
+                                       break;
+
                           
                                case ICMD_GOTO:
-                                       graph_add_cfg(m, gd, b_index,  m->basicblockindex[ip->op1]);
-                                       if (fall_through)
-                                               graph_add_cfg(m, gd, b_index, b_index+1);
+                                       graph_add_cfg(jd, gd, bptr,  iptr->dst.block);
                                        break;                                  /* visit branch (goto) target   */
                                
                                case ICMD_TABLESWITCH:          /* switch statement                             */
-                                       s4ptr = ip->val.a;
-                               
-                                       graph_add_cfg(m, gd, b_index,  m->basicblockindex[*s4ptr]);
-                               
-                                       s4ptr++;
-                                       low = *s4ptr;
-                                       s4ptr++;
-                                       high = *s4ptr;
-                               
-                                       count = (high-low+1);
-                               
-                                       while (--count >= 0) {
-                                               s4ptr++;
-                                               graph_add_cfg(m, gd, b_index, 
-                                                                        m->basicblockindex[*s4ptr]);
-                                   }
+                                       table = iptr->dst.table;
+                                       l = iptr->sx.s23.s2.tablelow;
+                                       i = iptr->sx.s23.s3.tablehigh;
+                                       i = i - l + 1;
+
+                                       /* Add default target */
+
+                                       graph_add_cfg(jd, gd, bptr,  table[0].block);
+                                       table += i;
+
+                                       while (--i >= 0) {
+                                               graph_add_cfg(jd, gd, bptr,  table->block);
+                                               --table;
+                                       }
                                        break;
                                
                                case ICMD_LOOKUPSWITCH:         /* switch statement                             */
-                                       s4ptr = ip->val.a;
-                          
-                                       graph_add_cfg(m, gd, b_index,  m->basicblockindex[*s4ptr]);
-                               
-                                       ++s4ptr;
-                                       count = *s4ptr++;
-                               
-                                       while (--count >= 0) {
-                                               graph_add_cfg(m, gd, b_index,
-                                                                         m->basicblockindex[s4ptr[1]]);
-                                               s4ptr += 2;
-                                   }
-                                       break;
+                                       lookup = iptr->dst.lookup;
+                                       i = iptr->sx.s23.s2.lookupcount;
+                       
+                                       while (--i >= 0) {
+                                               graph_add_cfg(jd, gd, bptr, lookup->target.block);
+                                               lookup++;
+                                       }
 
-                               case ICMD_JSR:
-                                       graph_add_jsr(m, gd, &sbr, b_index, m->basicblockindex[ip->op1]);
+                                       graph_add_cfg(jd, gd, bptr, iptr->sx.s23.s3.lookupdefault.block);
                                        break;
-                               
+
                                case ICMD_RET:
+                               case ICMD_JSR:
+                                       assert(0);
                                        break;
+
+                               case ICMD_NOP:
+                                       assert(0);
                                
                                default:
-                                       graph_add_cfg(m, gd, b_index, b_index + 1 );
+                                       graph_add_cfg(jd, gd, bptr, bptr + 1 );
                                        break;  
-                           } /* switch (ip->opc)*/                        
-                   }     /* if (m->basicblocks[blockIndex].icount) */
-           }         /* if (m->basicblocks[b_index].flags >= BBREACHED) */
-               b_index++;
-       }             /* while (b_index < m->basicblockcount ) */
-
-       /* add subroutines before exceptions! They "destroy" the CFG */
-       graph_add_subs(m, gd, &sbr); 
-       graph_add_exceptions(m, cd, gd);
+                           } /* switch (iptr->opc)*/                        
+                   }     /* if (bptr->icount) */
+           }         /* if (bptr->flags >= BBREACHED) */
+       }             /* for (bptr = ...; bptr != NULL; bptr = bptr->next) */
+
+       graph_add_exceptions(jd, gd);
        transform_CFG(jd, gd);
+
 #ifdef GRAPH_DEBUG_VERBOSE
        if (compileverbose)
                graph_print(ls, gd);
@@ -348,13 +343,19 @@ void graph_make_cfg(jitdata *jd,graphdata *gd) {
 /*****************************************************************
 add Edges from guarded Areas to Exception handlers in the CFG
 *****************************************************************/
-void graph_add_exceptions(methodinfo *m, codegendata *cd, graphdata *gd) { 
-       int i;
+void graph_add_exceptions(jitdata *jd, graphdata *gd) { 
+#if 0
+       basicblock *bptr;
+       raw_exception_entry *ex;
+       codegendata *cd;
+
+       cd = jd->cd;
 
        /* add cfg edges from all bb of a try block to the start of the according */
        /* exception handler to ensure the right order after depthfirst search    */
-       exceptiontable *ex;
+
        ex=jd->exceptiontable;
+
 #ifdef GRAPH_DEBUG_VERBOSE
        if (compileverbose)
                printf("ExTable(%i): ", jd->exceptiontablelength);
@@ -367,166 +368,49 @@ void graph_add_exceptions(methodinfo *m, codegendata *cd, graphdata *gd) {
                        printf("[%i-%i]->%i ",ex->start->nr, ex->end->nr,
                                   ex->handler->nr);
 #endif
-               _GRAPH_ASSERT(ex->handler->nr < m->basicblockcount);
-               _GRAPH_ASSERT(m->basicblocks[ex->handler->nr].flags >= BBREACHED);
+
+               _GRAPH_ASSERT(ex->handler->nr < jd->new_basicblockcount);
+               _GRAPH_ASSERT(ex->handler->flags >= BBREACHED);
                _GRAPH_ASSERT(ex->start->nr <= ex->end->nr);
 
                /* loop all valid Basic Blocks of the guarded area and add CFG edges  */
                /* to the appropriate handler */
-               for (i=ex->start->nr; (i <= ex->end->nr) &&
-                                (i < m->basicblockcount); i++)
-                       if (m->basicblocks[i].flags >= BBREACHED)
-                               graph_add_cfg(m, gd, i, ex->handler->nr);
+               for (bptr = ex->start; (bptr != NULL) && (bptr != ex->end); bptr = bptr->next) 
+                       if (bptr->flags >= BBREACHED)
+                               graph_add_cfg(jd, gd, bptr, ex->handler);
+
+               _GRAPH_ASSERT((bptr != NULL) 
+                                         && ((bptr->flags >=BBREACHED) || (bptr == ex->end)));
        }
 #ifdef GRAPH_DEBUG_VERBOSE
        if (compileverbose)
                printf("\n");
 #endif
-}
-
-/**************************************************
-Add subroutines from ls->sbr list to CFG
-**************************************************/
-void graph_add_subs(methodinfo *m, graphdata *gd, struct _sbr *sbr) {
-       struct _sbr *_sbr;
-       bool *visited;
-       int i;
-#ifdef GRAPH_DEBUG_VERBOSE
-       graph_element *ret;
-#endif
-
-       visited = (bool *)DMNEW(int, m->basicblockcount + 1);
-       for (i=0; i <= m->basicblockcount; i++) visited[i] = false;
-       for (_sbr = sbr->next; _sbr != NULL; _sbr=_sbr->next) {
-#ifdef GRAPH_DEBUG_VERBOSE
-               if (compileverbose) {
-                       printf("Subroutine Header: %3i Return Adresses:",_sbr->header);
-                       for (ret = _sbr->ret; ret != NULL; ret = ret->next)
-                               printf(" %3i", ret->value);
-                       printf("\n");
-               }
 #endif
-               graph_add_sub( m, gd, _sbr->header, _sbr->ret, visited );
-
-       }
 }
 
+
 /******************************************************************
 Add the CFG Edge into next und succ
 ******************************************************************/
-void graph_add_cfg( methodinfo *m, graphdata *gd, int from, int to) {
+void graph_add_cfg( jitdata *jd, graphdata *gd, basicblock *from,
+                                       basicblock *to) {
 
        /* ignore Empty, Deleted,... Basic Blocks as target */
        /* TODO: Setup BasicBlock array before to avoid this */
        /*       best together with using the basicblock list, so lsra works */
        /*       with opt_loops, too */
-       for (;(to < m->basicblockcount) && (m->basicblocks[to].flags < BBREACHED);
-                to++);
 
-       /* add one to from and to, so the to be inserted Basic Block 0 is */
-       /* already regarded */
-       graph_add_edge( gd, from + 1, to + 1);
-}
+       for (; (to != NULL) && (to->flags < BBREACHED); to = to->next);
 
-/*******************************************************************
-Remember Subroutine "jumps" in ls->sbr and add the CFG Edge of the 
-"jump" into succ and pred 
-*******************************************************************/
-void graph_add_jsr( methodinfo *m, graphdata *gd, struct _sbr *sbr, int from,
-                                       int to) {
-       struct _sbr *_sbr, *n;
-       graph_element *ret;
+       _GRAPH_ASSERT(to != NULL);
 
-       /* ignore Empty, Deleted,... Basic Blocks as target */
-       /* TODO: Setup BasicBlock array before to avoid this */
-       /*       best together with using the basicblock list, so lsra works */
-       /*       with opt_loops, too */
-       for (; (to < m->basicblockcount) && (m->basicblocks[to].flags < BBREACHED);
-                to++);
-       _GRAPH_ASSERT( to != m->basicblockcount );
-
-       graph_add_cfg(m, gd, from, to);
-
-       /* from + 1 ist the return Basic Block Index */
-       for (from++; (from < m->basicblockcount) &&
-                        (m->basicblocks[from].flags < BBREACHED); from++);
-       _GRAPH_ASSERT(from != m->basicblockcount);
-
-       /* add subroutine info in ls->sbr.next */
-
-       /* search for right place to insert */
-       for (_sbr = sbr; (_sbr->next != NULL) && (_sbr->next->header < to);
-                _sbr=_sbr->next);
-       
-       if ((_sbr->next!= NULL) && (_sbr->next->header == to)) {
-               /* Entry for this sub already exist */
-               _sbr = _sbr->next;
-       } else {
-               /* make new Entry and insert it in ls->sbr.next */
-               n = DNEW( struct _sbr );
-               n->header = to;
-               n->ret = NULL;
-
-               n->next = _sbr->next;
-               _sbr->next = n;
-
-               _sbr = n;
-       }
 
-       /* now insert return adress in sbr->ret */
-       ret = DNEW(graph_element);
-       ret->value = from;
-       ret->next = _sbr->ret;
-       _sbr->ret = ret;
+       /* add one to from and to, so the to be inserted Basic Block 0 is */
+       /* already regarded */
+       graph_add_edge( gd, from->nr + 1, to->nr + 1);
 }
 
-/**************************************************
-Add a subroutine to CFG
-**************************************************/
-void graph_add_sub(methodinfo *m, graphdata *gd, int b_index,
-                                  graph_element *ret, bool *visited ) {
-       graph_element *l;
-       instruction *ip;
-       bool next_block;
-       graphiterator i;
-       int s;
-
-       /* break at virtual End Block */
-       if (b_index != m->basicblockcount) {
-               visited[b_index] = true;
-               next_block = false;
-
-               if (m->basicblocks[b_index].flags < BBREACHED)
-                       next_block = true;
-               if (!next_block && !(m->basicblocks[b_index].icount))
-                       next_block = true;
-
-               if (!next_block) {
-                       ip = m->basicblocks[b_index].iinstr +
-                               m->basicblocks[b_index].icount - 1;
-               
-                       if (ip->opc == ICMD_JSR) /* nested Subroutines */
-                               next_block = true;
-               }
-
-               if (!next_block) {
-                       if (ip->opc == ICMD_RET) {
-                               /* subroutine return found -> add return adresses to CFG */
-                               for (l = ret; l != NULL; l = l->next)
-                                       graph_add_cfg( m, gd, b_index, l->value);
-                       } else { /* follow CFG */
-                               s = graph_get_first_successor(gd, b_index, &i); 
-                               for(; s != -1; s = graph_get_next(&i))
-                                       if (!visited[s])
-                                               graph_add_sub( m, gd, l->value, ret, visited);
-                       }
-               } else { /* fall through to next block */
-                       if (b_index + 1 < m->basicblockcount)
-                               if (!visited[b_index + 1])
-                                       graph_add_sub(m, gd, b_index + 1, ret, visited);
-               }
-       }
-}
 
 /*****************************************************************
 Sort Basic Blocks using Depth First search in reverse post order
@@ -597,19 +481,20 @@ void graph_DFS(lsradata *ls, graphdata *gd) {
 }
 
 
-void graph_init_basicblock( basicblock *bptr, int b_index) {
+void graph_init_basicblock(jitdata *jd, basicblock *bptr, int b_index) {
                bptr->nr = b_index;
                bptr->icount = 0;
                bptr->iinstr = NULL;
                bptr->type = BBTYPE_STD;
                bptr->flags = BBFINISHED;
-               bptr->instack = NULL;
-               bptr->outstack = NULL;
+               bptr->invars = NULL;
+               bptr->outvars = NULL;
                bptr->indepth = 0;
                bptr->outdepth = 0;
                bptr->branchrefs = NULL;
                bptr->mpc = -1;
                bptr->next = NULL;
+               bptr->method = jd->m;
 }
 
 /*********************************************************************+
@@ -622,8 +507,8 @@ TODO: Do not insert blocks right now - just adopt the call graph!
 void transform_CFG(jitdata *jd, graphdata *gd) {
        int i, j, k, n, num_new_blocks;
        int **var_def;
-       basicblock *tmp;
-       stackptr in, out, new_stack;
+       basicblock *tmp, *bptr;
+       s4 *in, *out, *new_in_stack, *new_out_stack;
        graphiterator iter;
        int *num_succ;
        struct graph_element **successor;
@@ -644,8 +529,8 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        /* multiple predecessor -> if found insert a new block between to split   */
        /* this edge. As first step count how many blocks have to be inserted.    */
 
-       num_new_blocks = 0;
-       for(i = 0; i< m->basicblockcount + 1; i++) {
+       num_new_blocks = 1;
+       for(i = 0; i< jd->basicblockcount + 1; i++) {
                if (graph_has_multiple_successors(gd, i)) {
                        k = graph_get_first_successor(gd, i, &iter);
                        for(; k != -1; k = graph_get_next(&iter)) {
@@ -658,24 +543,33 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        }
        
        /* increase now basicblockcount accordingly. */
-       ls->basicblockcount = m->basicblockcount + num_new_blocks + 1;
+       ls->basicblockcount = jd->basicblockcount + num_new_blocks;
 
        ls->basicblocks = DMNEW(basicblock *, ls->basicblockcount);
+       for(i = 0; i< ls->basicblockcount; i++)
+               ls->basicblocks[i] = NULL;
+
        /* copy Basic Block References to ls->basicblocks */
-       for(i = 0; i< m->basicblockcount; i++) {
-               ls->basicblocks[i+1] = &(m->basicblocks[i]);
-               ls->basicblocks[i+1]->nr = i+1;
+
+       for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
+/*             if (bptr->flags >= BBREACHED) { */
+                       _GRAPH_ASSERT(bptr->nr < jd->basicblockcount);
+                       ls->basicblocks[bptr->nr + 1] = bptr;
+                       bptr->nr = bptr->nr+1;
+/*             } */
        }
        
-       /* Create new Basic Blocks: 0, [m->basicblockcount..ls->basicblockcount[ */
-       /* num_new_blocks + 1 have to be inserted*/
-       tmp = DMNEW( basicblock, num_new_blocks + 1);
+       /* Create new Basic Blocks:
+          0, [jd->new_basicblockcount..ls->basicblockcount[ */
+       /* num_new_blocks have to be inserted*/
+
+       tmp = DMNEW( basicblock, num_new_blocks);
        ls->basicblocks[0] = tmp;
-       graph_init_basicblock( tmp, 0);
+       graph_init_basicblock( jd, tmp, 0);
        tmp++;
        ls->basicblocks[0]->next = ls->basicblocks[1];
 
-       if (ls->basicblockcount > m->basicblockcount + 1) {
+       if (ls->basicblockcount > jd->basicblockcount + 1) {
                /* new Blocks have to be inserted                   */
                num_succ = DMNEW(int, ls->basicblockcount);
                successor = DMNEW(graph_element *, ls->basicblockcount);
@@ -683,19 +577,19 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
                num_pred = DMNEW(int, ls->basicblockcount);
                predecessor = DMNEW(graph_element *, ls->basicblockcount);
 
-               /* regard the + 1 for the already regarded new BB 0 */
+               /* regard the + 1 for the already inserted new BB 0 */
                /* So recreate ls->var_def                          */
                var_def = DMNEW(int *, ls->basicblockcount);
-               for(i = 0; i < m->basicblockcount + 1; i++) {
+               for(i = 0; i < jd->basicblockcount + 1; i++) {
                        var_def[i] = ls->var_def[i];
                        num_succ[i] = gd->num_succ[i];
                        num_pred[i] = gd->num_pred[i];
                        successor[i] = gd->successor[i];
                        predecessor[i] = gd->predecessor[i];
                }
-               for(i = m->basicblockcount + 1; i < ls->basicblockcount; i++) {
-                       var_def[i] = bv_new(ls->max_vars);
-                       graph_init_basicblock( tmp, i);
+               for(i = jd->basicblockcount + 1; i < ls->basicblockcount; i++) {
+                       var_def[i] = bv_new(jd->varcount);
+                       graph_init_basicblock( jd, tmp, i);
                        ls->basicblocks[i] = tmp;
                        tmp++;
 
@@ -716,8 +610,8 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
        }
 
        /* Now Split the edges */
-       num_new_blocks = m->basicblockcount + 1; /* first free new block index */
-       for(i = 0; i < m->basicblockcount + 1; i++) {
+       num_new_blocks = jd->basicblockcount + 1; /* first free new block index */
+       for(i = 0; i < jd->basicblockcount + 1; i++) {
                if (graph_has_multiple_successors(gd, i)) {/* more than one successor */
                        j = graph_get_first_successor( gd, i, &iter);
                        for(; j != -1; j = graph_get_next(&iter)) {
@@ -734,48 +628,43 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
 
                                        ls->basicblocks[num_new_blocks]->indepth =
                                                ls->basicblocks[i]->outdepth;
-                                       out = ls->basicblocks[i]->outstack;
-                                       ls->basicblocks[num_new_blocks]->instack = in = NULL;
+                                       out = ls->basicblocks[i]->outvars;
+                                       ls->basicblocks[num_new_blocks]->invars = in = NULL;
 
                                        if (ls->basicblocks[num_new_blocks]->indepth > 0) 
-                                               new_stack = DMNEW( stackelement,
+                                               new_in_stack = DMNEW( s4,
+                                                                         ls->basicblocks[num_new_blocks]->indepth);
+                                               new_out_stack = DMNEW( s4,
                                                                          ls->basicblocks[num_new_blocks]->indepth);
+
                                        for(n=0; n<ls->basicblocks[num_new_blocks]->indepth; n++) {
-                                               if (in == NULL) {
-                                                       in = new_stack++;
-                                               } else {
-                                                       in->prev = new_stack++;
-                                                       in = in->prev;
-                                               }
-                                               in->type = out->type;
-                                               in->varkind = STACKVAR;
-                                               in->varnum = 0;
-                                               in->regoff = 0;
-                                               in->flags = 0;
-                                               in->prev = NULL;
-                                               /* Add Definition */
-                                               if (n == 0)
-                                                       ls->basicblocks[num_new_blocks]->instack = in;
-
-                                               out = out->prev;
+                                               new_in_stack[n] = out[n];
+                                               new_out_stack[n] = out[n];
                                        }
+                                       ls->basicblocks[num_new_blocks]->invars = new_in_stack;
 
                                        /* Create Outstack */
-                                       ls->basicblocks[num_new_blocks]->outstack =
-                                               ls->basicblocks[num_new_blocks]->instack;
+                                       ls->basicblocks[num_new_blocks]->outvars =
+                                               new_out_stack;
                                        ls->basicblocks[num_new_blocks]->outdepth = 
                                                ls->basicblocks[num_new_blocks]->indepth;
 
                                        _GRAPH_ASSERT(ls->basicblocks[num_new_blocks]->outdepth == 
-                                                       ls->basicblocks[j]->indepth );
+                                                                 ls->basicblocks[j]->indepth );
+
+#if 0
+                                       /* !!!! There can't be inoutvar definitions in one of these */
+                                       /* newly inserted basicblocks !!!! */
 
                                        /* Add Definition */
                                        /* decrease nr temporarly, because ssa_set_interface*/
                                        /* adds 1 since it is called from stack.c, where there is */
                                        /* no new BB 0 inserted like now */
+
                                        ls->basicblocks[num_new_blocks]->nr--;
-                                       ssa_set_interface(cd, ls, ls->basicblocks[num_new_blocks]);
+                                       ssa_set_interface(jd, ls->basicblocks[num_new_blocks]);
                                        ls->basicblocks[num_new_blocks]->nr++;
+#endif
                                        num_new_blocks++;
                                }
                        }
@@ -784,10 +673,10 @@ void transform_CFG(jitdata *jd, graphdata *gd) {
 }
 
 void transform_BB(jitdata *jd, graphdata *gd) {
-       int i, len;
+       int n, len;
        int pred, succ;
        basicblock *last_block;
-       instruction *ip;
+       instruction *iptr;
        graphiterator iter;
        methodinfo *m;
        lsradata *ls;
@@ -797,130 +686,120 @@ void transform_BB(jitdata *jd, graphdata *gd) {
 
        /* the "real" last Block is always an empty block        */
        /* so take the one before, to insert new blocks after it */
-       last_block = &(m->basicblocks[m->basicblockcount - 1]);
+       last_block = &(jd->basicblocks[jd->basicblockcount - 1]);
        _GRAPH_ASSERT(last_block->next->next == NULL);
        _GRAPH_ASSERT(last_block->next->flags <= BBREACHED);
        last_block->next->nr = ls->basicblockcount;
 
        /* look through new blocks */
-       for(i = m->basicblockcount + 1; i < ls->basicblockcount ; i++) {
+       for(n = jd->basicblockcount + 1; n < ls->basicblockcount ; n++) {
                /* if a phi move happens at this block, we need this block */
                /* if not, remove him from the CFG */
-               if (ls->num_phi_moves[i] > 0) {
+               if (ls->num_phi_moves[n] > 0) {
                        /* i can only have one predecessor and one successor! */
-                       _GRAPH_ASSERT( graph_has_multiple_predecessors(gd,i) == false);
-                       _GRAPH_ASSERT( graph_has_multiple_successors(gd,i) == false);
+                       _GRAPH_ASSERT( graph_has_multiple_predecessors(gd, n) == false);
+                       _GRAPH_ASSERT( graph_has_multiple_successors(gd, n) == false);
                        
-                       succ = graph_get_first_successor(gd, i, &iter);
-                       pred = graph_get_first_predecessor(gd, i, &iter);
+                       succ = graph_get_first_successor(gd, n, &iter);
+                       pred = graph_get_first_predecessor(gd, n, &iter);
 
-                       /* set ip to last instruction                         */
+                       /* set iptr to last instruction                       */
                        len = ls->basicblocks[pred]->icount;
-                       ip = ls->basicblocks[pred]->iinstr + len - 1;
-                       while ((len>0) && (ip->opc == ICMD_NOP)) {
+                       iptr = ls->basicblocks[pred]->iinstr + len - 1;
+                       while ((len>0) && (iptr->opc == ICMD_NOP)) {
                                len--;
-                               ip--;
+                               iptr--;
                        }
 
                                
                        /* with JSR there can not be multiple successors  */
-                       _GRAPH_ASSERT(ip->opc != ICMD_JSR);
+                       _GRAPH_ASSERT(iptr->opc != ICMD_JSR);
                        /* If the return Statment has more successors and  */
                        /* one of these has more predecessor, we are in    */
                        /* troubles - one would have to insert a new Block */
                        /* after the one which executes the ICMD_JSR       */
                        /* !!TODO!! if subroutines will not be inlined     */
-                       _GRAPH_ASSERT(ip->opc != ICMD_RET);
+                       _GRAPH_ASSERT(iptr->opc != ICMD_RET);
 
                        /* link new block into basicblocks list */
                        /* if edge to split is the "fallthrough" path of the */
                        /* conditional, then link the new block inbetween    */
                        /* and generate no ICMD */
                        /* else if edge to split is the branch, generate a   */
-                       /* ICMD_GOTO and add new BB at and of BB List        */
+                       /* ICMD_GOTO and add new BB at the end of the BB List*/
                        if ((ls->basicblocks[pred]->next == ls->basicblocks[succ]) 
-                               && (ip->opc != ICMD_LOOKUPSWITCH)
-                               && (ip->opc != ICMD_TABLESWITCH)
-                               && (ip->opc != ICMD_GOTO)) {
+                               && (iptr->opc != ICMD_LOOKUPSWITCH)
+                               && (iptr->opc != ICMD_TABLESWITCH)
+                               && (iptr->opc != ICMD_GOTO)) {
                                /* GOTO, *SWITCH have no fallthrough path */
 
                                /* link into fallthrough path */
                                
                                                
-                               ls->basicblocks[i]->next =
+                               ls->basicblocks[n]->next =
                                        ls->basicblocks[pred]->next;
                                ls->basicblocks[pred]->next =
-                                       ls->basicblocks[i];
+                                       ls->basicblocks[n];
                                /* generate no instructions */
-                               ls->basicblocks[i]->icount = 1; 
-                               ls->basicblocks[i]->iinstr = NEW(instruction);
-                               ls->basicblocks[i]->iinstr[0].opc =     ICMD_NOP;
+                               ls->basicblocks[n]->icount = 1; 
+                               ls->basicblocks[n]->iinstr = NEW(instruction);
+                               ls->basicblocks[n]->iinstr[0].opc =     ICMD_NOP;
                        } else {
-                               /* Block i is in the Branch path */
+                               /* Block n is in the Branch path */
                                /* link Block at the end */
-                               ls->basicblocks[i]->next =last_block->next;
-                               last_block->next = ls->basicblocks[i];
-                               last_block = ls->basicblocks[i];
+                               ls->basicblocks[n]->next =last_block->next;
+                               last_block->next = ls->basicblocks[n];
+                               last_block = ls->basicblocks[n];
 
                                /* change the Branch Target to BB i */
 
 
        
-                               switch(ip->opc) {
+                               switch(iptr->opc) {
                                case ICMD_LOOKUPSWITCH:
                                        {
-                                               s4 k, l, *s4ptr;
-                                               void **tptr;
-                                                       
-                                               tptr = (void **) ip->target;
-                                               if ((basicblock*)tptr[0] == ls->basicblocks[succ]) {
-                                                       /* target found -> change*/
-                                                       tptr[0] = ls->basicblocks[i];
-                                               }
+                                               s4 i;
+                                               lookup_target_t *lookup;
 
-                                               s4ptr = ip->val.a;
-                                               l = s4ptr[0];                  /* default  */
-                                               k = s4ptr[1];                  /* count    */
-                               
-                                               while (--k >= 0) {
-                                                       s4ptr += 2;
-                                                       ++tptr;
+                                               lookup = iptr->dst.lookup;
 
-                                                       if ((basicblock*)tptr[0] == ls->basicblocks[succ])
-                                                       {
+                                               i = iptr->sx.s23.s2.lookupcount;
+                       
+                                               while (--i >= 0) {
+                                                       if (lookup->target.block == ls->basicblocks[succ])
                                                                /* target found -> change */
-                                                               tptr[0] = ls->basicblocks[i];
-                                                       }
+                                                               lookup->target.block = ls->basicblocks[n];
+                                                       lookup++;
                                                }
+
+                                               if (iptr->sx.s23.s3.lookupdefault.block == ls->basicblocks[succ])
+                                                       /* target found -> change */
+                                                       iptr->sx.s23.s3.lookupdefault.block = ls->basicblocks[n];
                                        }
                                        break;
                                case ICMD_TABLESWITCH:
                                        {
-                                               s4 k, l, *s4ptr;
-                                               void **tptr;
+                                               s4 i, l;
+                                               branch_target_t *table;
 
-                                               tptr = (void **) ip->target;
-                                               
-                                               s4ptr = ip->val.a;
-                                               l = s4ptr[1];              /* low     */
-                                               k = s4ptr[2];              /* high    */
+                                               table = iptr->dst.table;
+
+                                               l = iptr->sx.s23.s2.tablelow;
+                                               i = iptr->sx.s23.s3.tablehigh;
 
-                                               k = k - l + 1;
+                                               i = i - l + 1;
 
-                                               if ((basicblock*)tptr[0] == ls->basicblocks[succ])
-                                               {
+                                               if (table[0].block ==  ls->basicblocks[succ]) /* default target */
                                                        /* target found -> change*/
-                                                       tptr[0] = ls->basicblocks[i];
-                                               }
-                                               tptr += k;
-                                                       
-                                               while (--k >= 0) {
-                                                       if ((basicblock*)tptr[0] == ls->basicblocks[succ])
-                                                       {
-                                                               /* target found -> change*/
-                                                               tptr[0] = ls->basicblocks[i];
-                                                       }
-                                                       --tptr;
+                                                       table[0].block = ls->basicblocks[n];
+
+                                               table += i;
+
+                                               while (--i >= 0) {
+                                                       if (table->block == ls->basicblocks[succ])
+                                                               /* target found -> change */
+                                                               table->block = ls->basicblocks[n];
+                                                       --table;
                                                }
                                        }
                                        break;
@@ -953,8 +832,8 @@ void transform_BB(jitdata *jd, graphdata *gd) {
                                case ICMD_IF_ACMPEQ:
                                case ICMD_IF_ACMPNE:                
                                case ICMD_GOTO:
-                                       _GRAPH_ASSERT(ip->target == ls->basicblocks[succ]);
-                                       ip->target = ls->basicblocks[i];
+                                       _GRAPH_ASSERT(iptr->dst.block == ls->basicblocks[succ]);
+                                       iptr->dst.block = ls->basicblocks[n];
                                        break;
                                default:
                                        /* Exception Edge to split */
@@ -963,17 +842,14 @@ void transform_BB(jitdata *jd, graphdata *gd) {
                                }
 
                                /* Generate the ICMD_GOTO */
-                               ls->basicblocks[i]->icount = 1; 
-                               ls->basicblocks[i]->iinstr =
+                               ls->basicblocks[n]->icount = 1; 
+                               ls->basicblocks[n]->iinstr =
                                        DNEW(instruction);
-                               ls->basicblocks[i]->iinstr->opc =
+                               ls->basicblocks[n]->iinstr->opc =
                                        ICMD_GOTO;
-                               ls->basicblocks[i]->iinstr->target =
+                               ls->basicblocks[n]->iinstr->dst.block =
                                        ls->basicblocks[succ];
-                               ls->basicblocks[i]->iinstr->op1 = succ;
                        }
-                       ls->basicblocks[i]->iinstr[0].dst = 
-                               ls->basicblocks[i]->outstack;
                }
        }
 }