Unified variables changes for common/i386.
[cacao.git] / src / vm / jit / jit.h
index 12161d21d02d6317077ede5f6aeda70a537f6e15..9418bbca53f94cfc4daf78d95845fd3ef6a27ee1 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Christian Thalinger
                        Edwin Steiner
 
-   $Id: jit.h 5024 2006-06-10 14:53:54Z edwin $
+   $Id: jit.h 5404 2006-09-07 13:29:05Z christian $
 
 */
 
@@ -38,6 +38,8 @@
 #ifndef _JIT_H
 #define _JIT_H
 
+#define NEW_VAR
+
 /* forward typedefs ***********************************************************/
 
 typedef struct jitdata jitdata;
@@ -46,7 +48,6 @@ typedef stackelement *stackptr;
 typedef struct basicblock basicblock;
 typedef struct branchref branchref;
 typedef struct instruction instruction;
-typedef struct new_instruction new_instruction;
 typedef struct insinfo_inline insinfo_inline;
 
 
@@ -70,10 +71,15 @@ typedef struct insinfo_inline insinfo_inline;
 #if defined(ENABLE_LOOP)
 # include "vm/jit/loop/loop.h"
 #endif
+#if defined(ENABLE_SSA) 
+# include "vm/jit/optimizing/lsra.h"
+#endif
+#if defined(ENABLE_LSRA)
+# include "vm/jit/allocator/lsra.h"
+#endif
 
 #include "vm/jit/verify/typeinfo.h"
 
-
 /* common jit/codegen macros **************************************************/
 
 #if defined(ENABLE_STATISTICS)
@@ -87,19 +93,22 @@ typedef struct insinfo_inline insinfo_inline;
 
 /* jitdata ********************************************************************/
 
-#define JITDATA_FLAG_IFCONV    0x00000001
-
 struct jitdata {
-       methodinfo   *m;                    /* methodinfo of the method compiled  */
-       codeinfo     *code;
-       codegendata  *cd;
-       registerdata *rd;
+       methodinfo      *m;                 /* methodinfo of the method compiled  */
+       codeinfo        *code;
+       codegendata     *cd;
+       registerdata    *rd;
 #if defined(ENABLE_LOOP)
-       loopdata     *ld;
+       loopdata        *ld;
+#endif
+#if defined(ENABLE_SSA) || defined(ENABLE_LSRA)
+       lsradata     *ls;
 #endif
-       u4            flags;                /* contains JIT compiler flags        */
 
-       new_instruction *new_instructions;
+       u4               flags;             /* contains JIT compiler flags        */
+       bool             isleafmethod;      /* does method call subroutines       */
+
+       instruction     *new_instructions;
        basicblock      *new_basicblocks;
        s4              *new_basicblockindex;
        stackelement    *new_stack;
@@ -107,30 +116,62 @@ struct jitdata {
        s4               new_basicblockcount;
        s4               new_stackcount;
        s4               new_c_debug_nr;
+
+#if defined(NEW_VAR)
+       varinfo *var;
+       s4      vartop;
+    
+       s4      varcount;
+       s4      localcount;
+    s4      *local_map; /* internal structure to rename(de-coallesc) locals  */
+                           /* and keep the coalescing info for simplereg.       */
+                           /* local_map[local_index * 5 + local_type] =         */
+                           /* new_index in rd->var or LOCAL_UNUSED              */
+       s4      *interface_map; /* like local_map for interfaces */
+#endif
 };
 
+#define UNUSED                     -1
 
-/************************** stack element structure ***************************/
+#define JITDATA_FLAG_PARSE               0x00000001
+#define JITDATA_FLAG_VERIFY              0x00000002
 
-/* slot types */
+#define JITDATA_FLAG_INSTRUMENT          0x00000004
 
-/* Unified these with longer names. Maybe someday use only
- * one set of names? -Edwin
- */
-/*#define TYPE_INT   0*/               /* the stack slot types must numbered in the  */
-#define TYPE_LNG   TYPE_LONG    /*1*/  /* same order as the ICMD_Ixxx to ICMD_Axxx   */
-#define TYPE_FLT   TYPE_FLOAT   /*2*/  /* instructions (LOAD and STORE)              */
-#define TYPE_DBL   TYPE_DOUBLE  /*3*/  /* integer, long, float, double, address      */
-#define TYPE_ADR   TYPE_ADDRESS /*4*/
+#define JITDATA_FLAG_IFCONV              0x00000008
+#define JITDATA_FLAG_REORDER             0x00000010
+
+#define JITDATA_FLAG_SHOWINTERMEDIATE    0x20000000
+#define JITDATA_FLAG_SHOWDISASSEMBLE     0x40000000
+#define JITDATA_FLAG_VERBOSECALL         0x80000000
 
-#define IS_INT_LNG_TYPE(a)      (!((a) & TYPE_FLT))
-#define IS_FLT_DBL_TYPE(a)      ((a) & TYPE_FLT)
-#define IS_2_WORD_TYPE(a)       ((a) & TYPE_LNG)
 
-#define IS_INT_TYPE(a)          ((a) == TYPE_INT)
-#define IS_LNG_TYPE(a)          ((a) == TYPE_LNG)
-#define IS_ADR_TYPE(a)          ((a) == TYPE_ADR)
+#define JITDATA_HAS_FLAG_PARSE(jd) \
+    ((jd)->flags & JITDATA_FLAG_PARSE)
 
+#define JITDATA_HAS_FLAG_VERIFY(jd) \
+    ((jd)->flags & JITDATA_FLAG_VERIFY)
+
+#define JITDATA_HAS_FLAG_INSTRUMENT(jd) \
+    ((jd)->flags & JITDATA_FLAG_INSTRUMENT)
+
+#define JITDATA_HAS_FLAG_IFCONV(jd) \
+    ((jd)->flags & JITDATA_FLAG_IFCONV)
+
+#define JITDATA_HAS_FLAG_REORDER(jd) \
+    ((jd)->flags & JITDATA_FLAG_REORDER)
+
+#define JITDATA_HAS_FLAG_SHOWINTERMEDIATE(jd) \
+    ((jd)->flags & JITDATA_FLAG_SHOWINTERMEDIATE)
+
+#define JITDATA_HAS_FLAG_SHOWDISASSEMBLE(jd) \
+    ((jd)->flags & JITDATA_FLAG_SHOWDISASSEMBLE)
+
+#define JITDATA_HAS_FLAG_VERBOSECALL(jd) \
+    ((jd)->flags & JITDATA_FLAG_VERBOSECALL)
+
+
+/* stack element structure ****************************************************/
 
 /* flags */
 
@@ -142,6 +183,13 @@ struct jitdata {
                                 /* using the same register/memory location    */
 #define STKEEP    32            /* to prevent reg_mark_copy to free this      */
                                 /* stackslot */
+#define PREALLOC  64            /* preallocated var like for ARGVARS. Used    */
+                                /* with the new var system */
+#define OUTVAR   128            /* STACKVR flag for new var system */
+
+#define IS_SAVEDVAR(x)    ((x) & SAVEDVAR)
+#define IS_INMEMORY(x)    ((x) & INMEMORY)
+
 
 /* variable kinds */
 
@@ -184,16 +232,25 @@ typedef struct {
 /*** s1 operand ***/
 
 typedef union {
+#if defined(NEW_VAR)
+       s4                         varindex;
+#else
     stackptr                   var;
     s4                         localindex;
+#endif
     s4                         argcount;
 } s1_operand_t;
 
 /*** s2 operand ***/
 
 typedef union {
+#if defined(NEW_VAR)
+       s4                         varindex;
+       s4                         *args;
+#else
     stackptr                   var;
     stackptr                  *args;
+#endif
     classref_or_classinfo      c;
     unresolved_class          *uc;
     ptrint                     constval;         /* for PUT*CONST             */
@@ -204,7 +261,11 @@ typedef union {
 /*** s3 operand ***/
 
 typedef union {
+#if defined(NEW_VAR)
+       s4                         varindex;
+#else
     stackptr                   var;
+#endif
     ptrint                     constval;
     classref_or_classinfo      c;
     constant_FMIref           *fmiref;
@@ -232,13 +293,21 @@ typedef union {
 /*** dst operand ***/
 
 typedef union {
+#if defined(NEW_VAR)
+       s4                         varindex;
+#else
     stackptr                   var;
     s4                         localindex;
+#endif
     basicblock                *block;       /* valid after stack analysis     */
     branch_target_t           *table;       /* for TABLESWITCH                */
     lookup_target_t           *lookup;      /* for LOOKUPSWITCH               */
     s4                         insindex;    /* used between parse and stack   */
+#if defined(NEW_VAR)
+       s4                        *dupslots;    /* for SWAP, DUP* except DUP      */
+#else
        stackptr                  *dupslots;    /* for SWAP, DUP* except DUP      */
+#endif
 } dst_operand_t;
 
 /*** flags (32 bits) ***/
@@ -246,7 +315,8 @@ typedef union {
 #define INS_FLAG_UNRESOLVED    0x01    /* contains unresolved field/meth/class*/
 #define INS_FLAG_CLASS         0x02    /* for ACONST with class               */
 #define INS_FLAG_ARRAY         0x04    /* for CHECKCAST/INSTANCEOF with array */
-#define INS_FLAG_NOCHECK       0x08
+#define INS_FLAG_CHECK         0x08    /* for *ALOAD|*ASTORE: check index     */
+                                       /* for BUILTIN: check exception        */
 
 typedef union {
     u4                  bits;
@@ -277,9 +347,9 @@ typedef union {
 
 /*** instruction ***/
 
-/* The new instruction format for the intermediate representation: */
+/* The instruction format for the intermediate representation: */
 
-struct new_instruction {
+struct instruction {
     u2                      opc;    /* opcode       */
     u2                      line;   /* line number  */
 #if SIZEOF_VOID_P == 8
@@ -299,26 +369,17 @@ struct new_instruction {
 #endif
 };
 
-/* XXX This instruction format will become obsolete. */
-
-struct instruction {
-       stackptr    dst;            /* stack index of destination operand stack   */
-       u2          opc;            /* opcode of intermediate code command        */
-       s4          op1;            /* first operand, usually variable number     */
-       imm_union   val;            /* immediate constant                         */
-       void       *target;         /* used for targets of branches and jumps     */
-                                   /* and as address for list of targets for     */
-                                   /* statements                                 */
-       u2          line;           /* line number in source file                 */
-};
 
 #define INSTRUCTION_IS_RESOLVED(iptr) \
-       (!((ptrint)(iptr)->target & 0x01)) /* XXX target used temporarily as flag */
+       (!((iptr)->flags.bits & INS_FLAG_UNRESOLVED))
 
 #define INSTRUCTION_IS_UNRESOLVED(iptr) \
-       ((ptrint)(iptr)->target & 0x01) /* XXX target used temporarily as flag */
+       ((iptr)->flags.bits & INS_FLAG_UNRESOLVED)
 
-#define NEW_INSTRUCTION_GET_FIELDREF(iptr,fref) \
+#define INSTRUCTION_MUST_CHECK(iptr) \
+       ((iptr)->flags.bits & INS_FLAG_CHECK)
+
+#define INSTRUCTION_GET_FIELDREF(iptr,fref) \
        do { \
                if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
                        fref = iptr->sx.s23.s3.uf->fieldref; \
@@ -326,15 +387,7 @@ struct instruction {
                        fref = iptr->sx.s23.s3.fmiref; \
        } while (0)
 
-#define INSTRUCTION_GET_FIELDREF(iptr,fref) \
-       do { \
-               if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
-                       fref = ((unresolved_field *) (iptr)->val.a)->fieldref; \
-               else \
-                       fref = ((constant_FMIref *)(iptr)->val.a); \
-       } while (0)
-
-#define NEW_INSTRUCTION_GET_METHODREF(iptr,mref) \
+#define INSTRUCTION_GET_METHODREF(iptr,mref) \
        do { \
                if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
                        mref = iptr->sx.s23.s3.um->methodref; \
@@ -342,23 +395,7 @@ struct instruction {
                        mref = iptr->sx.s23.s3.fmiref; \
        } while (0)
 
-#define INSTRUCTION_GET_METHODREF(iptr,mref) \
-       do { \
-               if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
-                       mref = ((unresolved_method *) (iptr)->val.a)->methodref; \
-               else \
-                       mref = ((constant_FMIref *)(iptr)->val.a); \
-       } while (0)
-
-#define INSTRUCTION_GET_FIELDDESC(iptr,fd) \
-       do { \
-               if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
-                       fd = ((unresolved_field *)(iptr)->val.a)->fieldref->parseddesc.fd; \
-               else \
-                       fd = ((constant_FMIref *)(iptr)->val.a)->parseddesc.fd; \
-       } while (0)
-
-#define NEW_INSTRUCTION_GET_METHODDESC(iptr, md) \
+#define INSTRUCTION_GET_METHODDESC(iptr, md) \
        do { \
                if (iptr->flags.bits & INS_FLAG_UNRESOLVED) \
                        md = iptr->sx.s23.s3.um->methodref->parseddesc.md; \
@@ -366,58 +403,6 @@ struct instruction {
                        md = iptr->sx.s23.s3.fmiref->parseddesc.md; \
        } while (0)
 
-#define INSTRUCTION_GET_METHODDESC(iptr,md) \
-       do { \
-               if (INSTRUCTION_IS_UNRESOLVED(iptr)) \
-                       md = ((unresolved_method *) (iptr)->val.a)->methodref->parseddesc.md; \
-               else \
-                       md = ((constant_FMIref *)(iptr)->val.a)->parseddesc.md; \
-       } while (0)
-
-#define INSTRUCTION_UNRESOLVED_METHOD(iptr) \
-       ((unresolved_method *) (iptr)->val.a)
-
-#define INSTRUCTION_UNRESOLVED_FIELD(iptr) \
-       ((unresolved_field *) (iptr)->val.a)
-
-#define INSTRUCTION_RESOLVED_FMIREF(iptr) \
-    ((constant_FMIref *)(iptr)->val.a)
-
-#define INSTRUCTION_RESOLVED_FIELDINFO(iptr) \
-    (INSTRUCTION_RESOLVED_FMIREF(iptr)->p.field)
-
-#define INSTRUCTION_RESOLVED_METHODINFO(iptr) \
-    (INSTRUCTION_RESOLVED_FMIREF(iptr)->p.method)
-
-#define INSTRUCTION_PUTCONST_TYPE(iptr) \
-       ((iptr)[0].op1)
-
-#define INSTRUCTION_PUTCONST_VALUE_ADR(iptr) \
-       ((iptr)[0].val.a)
-
-#define INSTRUCTION_PUTCONST_FIELDINFO(iptr) \
-       ((fieldinfo *)((iptr)[1].val.a))
-
-#define INSTRUCTION_PUTCONST_FIELDINFO_PTR(iptr) \
-       ((fieldinfo **) &((iptr)[1].val.a))
-
-#define INSTRUCTION_PUTCONST_FIELDREF(iptr) \
-       ((unresolved_field *)((iptr)[1].target))
-
-/* for ICMD_ACONST */
-
-#define ICMD_ACONST_IS_CLASS(iptr) \
-       ((ptrint)(iptr)->target & 0x02) /* XXX target used temporarily as flag */
-
-#define ICMD_ACONST_CLASSREF_OR_CLASSINFO(iptr) \
-(CLASSREF_OR_CLASSINFO((iptr)->val.a))
-
-#define ICMD_ACONST_RESOLVED_CLASSINFO(iptr) \
-       ((classinfo *) (iptr)->val.a)
-
-#define ICMD_ACONST_UNRESOLVED_CLASSREF(iptr) \
-       ((constant_classref *) (iptr)->val.a)
-
 
 /* additional info structs for special instructions ***************************/
 
@@ -455,43 +440,53 @@ struct insinfo_inline {
 /* the others by using bitfields.                                             */
 
 struct basicblock {
-       s4           debug_nr;      /* basic block number                         */
-       s4           flags;         /* used during stack analysis, init with -1   */
-       s4           bitflags;      /* OR of BBFLAG_... constants, init with 0    */
-       s4           type;          /* basic block type (std, xhandler, subroutine*/
-       instruction *iinstr;        /* pointer to intermediate code instructions  */
-       s4           icount;        /* number of intermediate code instructions   */
-       s4           mpc;           /* machine code pc at start of block          */
-       stackptr     instack;       /* stack at begin of basic block              */
-       stackptr     outstack;      /* stack at end of basic block                */
-       s4           indepth;       /* stack depth at begin of basic block        */
-       s4           outdepth;      /* stack depth end of basic block             */
-       s4           pre_count;     /* count of predecessor basic blocks          */
-       branchref   *branchrefs;    /* list of branches to be patched             */
-
-       basicblock  *next;          /* used to build a BB list (instead of array) */
-       s4           lflags;        /* used during loop copying, init with 0      */
-       basicblock  *copied_to;     /* points to the copy of this basic block     */
+       s4            nr;           /* basic block number                         */
+       s4            flags;        /* used during stack analysis, init with -1   */
+       s4            bitflags;     /* OR of BBFLAG_... constants, init with 0    */
+       s4            type;         /* basic block type (std, xhandler, subroutine*/
+       instruction  *iinstr;       /* pointer to intermediate code instructions  */
+       s4            icount;       /* number of intermediate code instructions   */
+       s4            mpc;          /* machine code pc at start of block          */
+       stackptr      instack;      /* stack at begin of basic block              */
+       stackptr      outstack;     /* stack at end of basic block                */
+#if defined(NEW_VAR)
+       s4           *invars;       /* array of in-variables at begin of block    */
+       s4           *outvars;      /* array of out-variables at end of block     */
+#else
+       stackptr     *invars;       /* array of in-variables at begin of block    */
+       stackptr     *outvars;      /* array of out-variables at end of block     */
+#endif
+       s4            indepth;      /* stack depth at begin of basic block        */
+       s4            outdepth;     /* stack depth end of basic block             */
+
+       s4            predecessorcount;
+       s4            successorcount;
+       basicblock  **predecessors; /* array of predecessor basic blocks          */
+       basicblock  **successors;   /* array of successor basic blocks            */
+
+       branchref    *branchrefs;   /* list of branches to be patched             */
+
+       basicblock   *next;         /* used to build a BB list (instead of array) */
+       s4            lflags;       /* used during loop copying, init with 0      */
+       basicblock   *copied_to;    /* points to the copy of this basic block     */
                                 /* when loop nodes are copied                 */
-       stackptr     stack;         /* start of stack array for this block        */
+       stackptr      stack;        /* start of stack array for this block        */
                                    /* (see doc/stack.txt)                        */
-       methodinfo  *method;        /* method this block belongs to               */
+       methodinfo   *method;       /* method this block belongs to               */
 };
 
-/* macro for initializing newly allocated basicblock:s                        */
-
-#define BASICBLOCK_INIT(bptr,m)                            \
-               do {                                               \
-                       bptr->mpc = -1;                                \
-                       bptr->flags = -1;                              \
-                       bptr->bitflags = 0;                            \
-                       bptr->lflags = 0;                              \
-                       bptr->type = BBTYPE_STD;                       \
-                       bptr->branchrefs = NULL;                       \
-                       bptr->pre_count = 0;                           \
-                       bptr->method = (m);                            \
-                       bptr->debug_nr = (m)->c_debug_nr++;            \
-               } while (0)
+
+/* Macro for initializing newly allocated basic block's. It does not
+   need to zero fields, as we zero out the whole basic block array. */
+
+#define BASICBLOCK_INIT(bptr,m)                        \
+       do {                                               \
+               bptr->mpc    = -1;                             \
+               bptr->flags  = -1;                             \
+               bptr->type   = BBTYPE_STD;                     \
+               bptr->method = (m);                            \
+               bptr->nr     = (m)->c_debug_nr++;              \
+       } while (0)
                        
 
 /* branchref *****************************************************************/
@@ -551,28 +546,21 @@ extern int jcommandsize[256];
 #define JAVA_FCONST_1         12
 
 #define JAVA_FCONST_2         13
-#define ICMD_ELSE_ICONST      13
 
 #define JAVA_DCONST_0         14
 #define ICMD_DCONST           14        /* val.d = constant                   */
 
 #define JAVA_DCONST_1         15
-#define ICMD_IFEQ_ICONST      15
 
 #define JAVA_BIPUSH           16
-#define ICMD_IFNE_ICONST      16
 
 #define JAVA_SIPUSH           17
-#define ICMD_IFLT_ICONST      17
 
 #define JAVA_LDC1             18
-#define ICMD_IFGE_ICONST      18
 
 #define JAVA_LDC2             19
-#define ICMD_IFGT_ICONST      19
 
 #define JAVA_LDC2W            20
-#define ICMD_IFLE_ICONST      20
 
                                            /* order of LOAD instructions must be */
                                            /* equal to order of TYPE_* defines   */
@@ -1160,11 +1148,6 @@ extern int jcommandsize[256];
 
 #define ICMD_BUILTIN          255       /* internal opcode                    */
 
-/* define some ICMD masks *****************************************************/
-
-#define ICMD_OPCODE_MASK      0x00ff    /* mask to get the opcode             */
-#define ICMD_CONDITION_MASK   0xff00    /* mask to get the condition          */
-
 
 /******************* description of JavaVM instructions ***********************/
 
@@ -1188,7 +1171,14 @@ extern int jcommandsize[256];
 /***************************** register info block ****************************/
 
 extern int stackreq[256];
-
+/* extern int op_needs_saved[256];  */
+/* extern int op_is_pei[256];       */
+#define NEEDS_SAVED  0
+#define PEI          1
+#define OP_DATA_SIZE 2
+extern int op_data[256][OP_DATA_SIZE]; 
+/* [0..255][NEEDS_SAVED] ... if ICMD needs a SAVEDVAR         */
+/* [0..255][PEI]         ... if ICMD could throw an exception */
 
 /* function prototypes ********************************************************/
 
@@ -1200,10 +1190,13 @@ void jit_close(void);
 
 /* compile a method with jit compiler */
 u1 *jit_compile(methodinfo *m);
+u1 *jit_recompile(methodinfo *m);
 
 /* patch the method entrypoint */
 u1 *jit_asm_compile(methodinfo *m, u1 *mptr, u1 *sp, u1 *ra);
 
+s4 jit_complement_condition(s4 opcode);
+
 /* machine dependent functions */
 #if defined(ENABLE_JIT)
 void md_init(void);