-/* src/vm/optimizing/ssa3.c
+/* src/vm/jit/optimizing/ssa3.c
Copyright (C) 2008
CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
* Unify access to phi args.
*/
-#include "vm/jit/jit.h"
+
+#include "config.h"
+
+#include "vm/jit/jit.hpp"
#include "vm/global.h"
#include "mm/memory.h"
-#include "mm/dumpmemory.h"
+#include "mm/dumpmemory.hpp"
#include "toolbox/list.h"
#include <limits.h>
/*#define ELIMINATE_NOP_LOAD_STORE*/
#define FIXME(x) x
#define SSA_VERIFY
-#define SSA_VERBOSE
+/*#define SSA_VERBOSE */
/*
__attribute__((always_inline))
/*** vars *******************************************************************/
-#define VARS_CATEGORY_SHIFT 29
-#define VARS_INDEX_MASK 0x1FFFFFFF
+#define VARS_CATEGORY_SHIFT 28
+#define VARS_INDEX_MASK 0x0FFFFFFF
#define VARS_CATEGORY_LOCAL 0
#define VARS_CATEGORY_STACK 1
}
#endif
-static inline void phis_copy_to(const phis_t *ps, instruction *dst) {
- MCOPY(
- dst,
- ps->items,
- instruction,
- ps->count
- );
+static inline unsigned phis_copy_to(const phis_t *ps, instruction *dst) {
+ instruction *it;
+ instruction *out = dst;
+
+ FOR_EACH_PHI_FUNCTION(ps, it) {
+ *(out++) = *it;
+ }
+
+ return (out - dst);
}
/*** state_array ************************************************************/
basicblock_chain_t chain;
basicblock *last = NULL;
basicblock *marker = NULL;
+ s4 vartop;
+ unsigned i;
if (jd->exceptiontablelength == 0) {
return;
basicblock_chain_init(&chain);
- /* We need to allocate new iovars */
+ /* Remember, where we started adding IO variables. */
- avail_vars = (jd->varcount - jd->vartop);
- add_vars = jd->exceptiontablelength;
-
- if (add_vars > avail_vars) {
- add_vars -= avail_vars;
- jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, jd->varcount + add_vars);
- jd->varcount += add_vars;
- }
+ vartop = jd->vartop;
/* For each exception handler block, create one block with a prologue block */
FOR_EACH_BASICBLOCK(jd, bptr) {
if (bptr->type == BBTYPE_EXH) {
+ /*
+
+ +---- EXH (exh)-------+
+ | in0 in1 in2 exc |
+ | ..... |
+ +---------------------+
+
+ === TRANSFORMED TO ===>
+
+ +---- PROL (exh) -------+
+ | in0 in1 in2 |
+ | GETEXECEPTION => OU3 |
+ | GOTO REAL_EXH |
+ | in0 in1 in2 OU3 |
+ +-----------------------+
+
+ +---- REAL_EXH (std) -+
+ | in0 in1 in2 exc |
+ | ...... |
+ +---------------------+
+
+ */
+
bptr->type = BBTYPE_STD;
bptr->predecessorcount = 0; /* legacy */
iptr = DMNEW(instruction, 2);
MZERO(iptr, instruction, 2);
+
+ /* Create outvars */
+
+ exh->outdepth = bptr->indepth;
+
+ if (exh->outdepth > 0) {
+ exh->outvars = DMNEW(s4, exh->outdepth);
+ for (i = 0; i < exh->outdepth; ++i) {
+ exh->outvars[i] = vartop++;
+ }
+ }
+
+ /* Create invars */
+ exh->indepth = exh->outdepth - 1;
+ exh->invars = exh->outvars;
+
+#if 0
/* Create new outvar */
assert(jd->vartop < jd->varcount);
jd->vartop += 1;
jd->var[v].type = TYPE_ADR;
jd->var[v].flags = INOUT;
+#endif
exh->nr = jd->basicblockcount;
jd->basicblockcount += 1;
exh->type = BBTYPE_EXH;
exh->icount = 2;
exh->iinstr = iptr;
+/*
exh->outdepth = 1;
exh->outvars = DNEW(s4);
exh->outvars[0] = v;
+*/
exh->predecessorcount = -1; /* legacy */
exh->flags = BBFINISHED;
exh->method = jd->m;
/* Get exception */
iptr->opc = ICMD_GETEXCEPTION;
- iptr->dst.varindex = v;
+ iptr->dst.varindex = exh->outvars[exh->outdepth - 1];
iptr += 1;
/* Goto real exception handler */
}
}
+ /* We need to allocate the new iovars in the var array */
+
+ avail_vars = (jd->varcount - jd->vartop);
+ add_vars = (vartop - jd->vartop);
+
+ if (add_vars > avail_vars) {
+ add_vars -= avail_vars;
+ jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, jd->varcount + add_vars);
+ jd->varcount += add_vars;
+ }
+
+ jd->vartop = vartop;
+
/* Put the chain of exception handlers between just before the last
basic block (end marker). */
for (ee = jd->exceptiontable; ee; ee = ee->down) {
assert(ee->handler->vp);
- ee->handler = ee->handler->vp;
+
+ bptr = ee->handler;
+ exh = (basicblock *)ee->handler->vp;
+
+ ee->handler = exh;
+
+ /* Set up IO variables in newly craeted exception handlers. */
+
+ for (i = 0; i < exh->outdepth; ++i) {
+ v = exh->outvars[i];
+
+ jd->var[v].flags = INOUT;
+ jd->var[v].type = jd->var[ bptr->invars[i] ].type;
+ }
}
}
basicblock *bptr;
basicblock_info_t *bbi;
instruction *itph;
+
+ /* XXX */
+ return;
+
FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
if (basicblock_reached(bptr)) {
bbi = bb_info(bptr);
basicblock_get_ex_predecessor_index(bb, pei, *itsucc),
ssa->locals
);
+
+ ssa_enter_merge(
+ bbi->stack,
+ succi->stack,
+ *itsucc,
+ basicblock_get_ex_predecessor_index(bb, pei, *itsucc),
+ ssa->stack
+ );
}
}
instruction *itph;
bool ret = false;
+ /* XXX */
+ return;
+
FOR_EACH_PHI_FUNCTION(t->phis, itph) {
phi_calculate_redundancy(itph);
state_array_allocate_items(bbi->stack->state_array);
}
+#if 0
/* Exception handlers have a clean stack. */
+ /* Not true with inlining. */
+
if (bb->type == BBTYPE_EXH) {
state_array_assert_no_items(bbi->stack->state_array);
state_array_allocate_items(bbi->stack->state_array);
}
+#endif
/* Some in/out vars get marked as INOUT in simplereg,
and are not marked at this point.
FOR_EACH_BASICBLOCK(ssa->jd, bptr) {
bbi = bb_info(bptr);
if (bbi != NULL) {
- bptr->phicount =
- bbi->locals->phis->count +
- bbi->stack->phis->count;
-
- bptr->phis = DMNEW(instruction, bptr->phicount);
+ bptr->phis = DMNEW(instruction, bbi->locals->phis->count + bbi->stack->phis->count);
dst = bptr->phis;
- phis_copy_to(bbi->locals->phis, dst);
+ dst += phis_copy_to(bbi->locals->phis, dst);
- dst += bbi->locals->phis->count;
+ dst += phis_copy_to(bbi->stack->phis, dst);
- phis_copy_to(bbi->stack->phis, dst);
+ bptr->phicount = dst - bptr->phis;
}
}
}
}
instruction_set_uses(iptr, ssa->s_buf, uses, uses_count);
}
+ bptr->phicount = 0;
}
unfix_exception_handlers(ssa->jd);
ssa->jd->localcount = ssa->original.localcount;
}
+#include "vm/rt-timing.h"
+
void yssa(jitdata *jd) {
basicblock *it;
basicblock_info_t *iti;
ssa_info *ssa;
+ struct timespec bs, es, be, ee;
+
+ RT_TIMING_GET_TIME(bs);
+
#ifdef SSA_VERBOSE
bool verb = true;
if (verb) {
/*ssa_enter_create_phi_graph(ssa);*/
- /*escape_analysis_perform(ssa->jd);*/
+ RT_TIMING_GET_TIME(be);
+ escape_analysis_perform(ssa->jd);
+ RT_TIMING_GET_TIME(ee);
/*
ssa_leave_create_phi_moves(ssa);
}
#endif
+ RT_TIMING_GET_TIME(es);
+
+ RT_TIMING_TIME_DIFF(bs, es, RT_TIMING_1);
+ RT_TIMING_TIME_DIFF(be, ee, RT_TIMING_2);
}
void eliminate_subbasicblocks(jitdata *jd) {