/* src/vm/jit/jit.h - code generation header
- Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
- C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
- E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
- J. Wenninger, Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006, 2007, 2008
+ CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
This file is part of CACAO.
/* forward typedefs ***********************************************************/
typedef struct jitdata jitdata;
-typedef struct stackelement stackelement;
-typedef stackelement *stackptr;
typedef struct basicblock basicblock;
typedef struct instruction instruction;
typedef struct insinfo_inline insinfo_inline;
#include "vm/jit/codegen-common.h"
#include "vm/jit/reg.h"
#include "vm/jit/replace.h"
+#include "vm/jit/stack.h"
#include "vm/jit/stacktrace.h"
#if defined(ENABLE_INLINING)
#include "vm/jit/verify/typeinfo.h"
-#include "vmcore/descriptor.h"
#include "vmcore/method.h"
#include "vmcore/references.h"
instruction *instructions; /* ICMDs, valid between parse and stack */
basicblock *basicblocks; /* start of basic block list */
- stackelement *stack; /* XXX should become stack.c internal */
+ stackelement_t *stack; /* XXX should become stack.c internal */
s4 instructioncount;/* XXX remove this? */
s4 basicblockcount; /* number of basic blocks */
s4 stackcount; /* number of stackelements to allocate */
/* >= 0......index into jd->var, or */
/* UNUSED....this (javaindex,type) pair is not used */
+ s4 *reverselocalmap; /* map from CACAO varindex to javaindex */
+ /* (varindex must be < localcount) */
+
s4 maxlocals; /* max. number of javalocals */
interface_info *interface_map; /* interface variables (for simplereg) */
};
-/* stack element structure ****************************************************/
-
-/* flags */
-
-#define SAVEDVAR 1 /* variable has to survive method invocations */
-#define INMEMORY 2 /* variable stored in memory */
-#define SAVREG 4 /* allocated to a saved register */
-#define ARGREG 8 /* allocated to an arg register */
-#define PASSTHROUGH 32 /* stackslot was passed-through by an ICMD */
-#define PREALLOC 64 /* preallocated var like for ARGVARS. Used */
- /* with the new var system */
-#define INOUT 128 /* variable is an invar or/and an outvar */
-
-#define IS_SAVEDVAR(x) ((x) & SAVEDVAR)
-#define IS_INMEMORY(x) ((x) & INMEMORY)
-
-
-/* variable kinds */
-
-#define UNDEFVAR 0 /* stack slot will become temp during regalloc*/
-#define TEMPVAR 1 /* stack slot is temp register */
-#define STACKVAR 2 /* stack slot is numbered stack slot */
-#define LOCALVAR 3 /* stack slot is local variable */
-#define ARGVAR 4 /* stack slot is argument variable */
-
-
-struct stackelement {
- stackptr prev; /* pointer to next element towards bottom */
- instruction *creator; /* instruction that created this element */
- s4 type; /* slot type of stack element */
- s4 flags; /* flags (SAVED, INMEMORY) */
- s4 varkind; /* kind of variable or register */
- s4 varnum; /* number of variable */
-};
-
/* macros for accessing variables *********************************************
Use VAROP for s1, s2, s3 and dst operands (eg. VAROP(iptr->s1)),
static inline bool var_is_inout(const jitdata *jd, s4 i) {
const varinfo *v = jd->var + i;
- return ((i >= jd->localcount) && !(v->flags & PREALLOC) && (v->flags & INOUT));
+ return (
+ (i >= jd->localcount) && (
+ (!(v->flags & PREALLOC) && (v->flags & INOUT)) ||
+ /* special case of TYPE_RET, used with JSR */
+ ((v->flags & PREALLOC) && (v->flags & INOUT) && (v->type == TYPE_RET))
+ )
+ );
}
static inline bool var_is_temp(const jitdata *jd, s4 i) {
s4 tablelow; /* for TABLESWITCH */
u4 lookupcount; /* for LOOKUPSWITCH */
s4 retaddrnr; /* for ASTORE */
+ instruction **iargs; /* for PHI */
} s2_operand_t;
/*** s3 operand ***/
#if SIZEOF_VOID_P == 4
flags_operand_t flags; /* 4 bytes */
#endif
+#if defined(ENABLE_ESCAPE_REASON)
+ void *escape_reasons;
+#endif
};
s4 expredecessorcount;
s4 exouts; /* Number of exceptional exits */
- basicblock *subbasicblocks;
+ instruction *phis; /* Phi functions */
+ s4 phicount; /* Number of phi functions */
void *vp; /* Freely used by different passes */
#endif
#define FOR_EACH_INSTRUCTION(bptr, it) \
for ((it) = (bptr)->iinstr; (it) != (bptr)->iinstr + (bptr)->icount; ++(it))
+#define FOR_EACH_INSTRUCTION_REV(bptr, it) \
+ for ((it) = (bptr)->iinstr + (bptr)->icount - 1; (it) != (bptr)->iinstr - 1; --(it))
+
#if defined(ENABLE_SSA)
#define FOR_EACH_EXHANDLER(bptr, it) \
ICMD_IMULPOW2 = 214,
ICMD_LMULPOW2 = 215,
+ ICMD_GETEXCEPTION = 249,
+ ICMD_PHI = 250,
+
ICMD_INLINE_START = 251, /* instruction before inlined method */
ICMD_INLINE_END = 252, /* instruction after inlined method */
ICMD_INLINE_BODY = 253, /* start of inlined body */
if (
(icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
(icmd_table[iptr->opc].dataflow == DF_BUILTIN)
- ) {
+ ) {
return instruction_call_site(iptr)->returntype.type != TYPE_VOID;
} else {
return icmd_table[iptr->opc].dataflow >= DF_DST_BASE;