*/
+#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 *);
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;
( 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:
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:
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);
/*****************************************************************
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);
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
}
-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;
}
/*********************************************************************+
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;
/* 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)) {
}
/* 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);
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++;
}
/* 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)) {
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++;
}
}
}
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;
/* 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;
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 */
}
/* 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;
}
}
}