Author: leo
Date: Thu Feb  9 07:29:55 2006
New Revision: 11485

Modified:
   trunk/include/parrot/pic.h
   trunk/src/jit/i386/jit_emit.h
   trunk/src/pic.c
   trunk/src/pic_jit.c
Log:
PIC/JIT - verfiy, if sub is JITtable 1

* add sanity checks
  - if jit_arch can compile to registers
  - if register usage of sub allows that
  - if caller args and sub params are matching and arg passing
    is simple aka JITtable


Modified: trunk/include/parrot/pic.h
==============================================================================
--- trunk/include/parrot/pic.h  (original)
+++ trunk/include/parrot/pic.h  Thu Feb  9 07:29:55 2006
@@ -80,6 +80,7 @@ void * parrot_pic_opcode(Interp *, INTVA
 typedef int (*arg_pass_f)(Interp *, PMC *sig,
         char *src_base, void **src_pc, char *dest_base, void **dest_pc);
 
+int parrot_pic_check_sig(Interp *, PMC *sig1, PMC *sig2, int *type);
 int parrot_pic_is_save_to_jit(Interp *, PMC *sub,
        PMC *sig_args, PMC *sig_results);
 

Modified: trunk/src/jit/i386/jit_emit.h
==============================================================================
--- trunk/src/jit/i386/jit_emit.h       (original)
+++ trunk/src/jit/i386/jit_emit.h       Thu Feb  9 07:29:55 2006
@@ -3788,6 +3788,7 @@ static const jit_arch_info arch_info = {
             0,                  /* ABI sez it's not preserved */
             floatval_map
         },
+        /* unused */
         {
             Parrot_jit_begin_sub,   /* emit code prologue */
             4,                  /* 4 mapped ints */
@@ -3796,12 +3797,21 @@ static const jit_arch_info arch_info = {
             4,                  /* 4 mapped float regs */
             0,                  /* ABI sez it's not preserved */
             floatval_map
-        },{
+        },
+        /*
+         * compile a sub to registers only
+         * if a mapped count is 0, code containing this register kind
+         * will not be created
+         *
+         * TODO implement FLOATVAL arg passing and set mapped
+         * register count.
+         */
+        {
             Parrot_jit_begin_sub_regs,   /* emit code prologue */
-            4,                  /* 4 mapped ints */
+            5,                  /* 5 mapped ints */
             2,                  /* first 2 are *non*preserved */
             i_map_sub,
-            4,                  /* 4 mapped float regs */
+            0,                  /* TODO 0 mapped float regs */
             0,                  /* ABI sez it's not preserved */
             floatval_map
         }

Modified: trunk/src/pic.c
==============================================================================
--- trunk/src/pic.c     (original)
+++ trunk/src/pic.c     Thu Feb  9 07:29:55 2006
@@ -374,8 +374,8 @@ pass_mixed(Interp *interpreter, PMC *sig
  * return argument count and type of the signature or -1 if not pic-able
  * the type PARROT_ARG_CONSTANT stands for mixed types or constants
  */
-static int
-pic_check_sig(Interp *interpreter, PMC *sig1, PMC *sig2, int *type)
+int
+parrot_pic_check_sig(Interp *interpreter, PMC *sig1, PMC *sig2, int *type)
 {
     int i, n, t0, t1, t2;
 
@@ -443,7 +443,7 @@ is_pic_param(Interp *interpreter, void *
         const_nr = args[1];
         /* check current_args signature */
         sig2 = caller_ctx->constants[const_nr]->u.key;
-        n = pic_check_sig(interpreter, sig1, sig2, &type);
+        n = parrot_pic_check_sig(interpreter, sig1, sig2, &type);
         if (n == -1)
             return 0;
     }

Modified: trunk/src/pic_jit.c
==============================================================================
--- trunk/src/pic_jit.c (original)
+++ trunk/src/pic_jit.c Thu Feb  9 07:29:55 2006
@@ -1,6 +1,6 @@
 /*
 Copyright: 2006 The Perl Foundation.  All Rights Reserved.
-$Id:$
+$Id$
 
 =head1 NAME
 
@@ -72,13 +72,98 @@ pic_test_func(Interp *interpreter, INTVA
 }
 #endif
 
+static int
+jit_can_compile_sub(Interp *interpreter, PMC *sub)
+{
+    const jit_arch_info *info;
+    const jit_arch_regs *regs;
+    INTVAL *n_regs_used;
+          
+    info = Parrot_jit_init(interpreter);
+
+    regs = info->regs + JIT_CODE_SUB_REGS_ONLY;
+    n_regs_used = PMC_sub(sub)->n_regs_used;
+
+    /* if the sub is using more regs than the arch has
+     * we don't JIT it at all
+     */
+    if (n_regs_used[REGNO_INT] > regs->n_mapped_I)
+        return 0;
+    if (n_regs_used[REGNO_NUM] > regs->n_mapped_F)
+        return 0;
+    /* if the Sub is using S regs, we can't JIT it yet */
+    if (n_regs_used[REGNO_STR])
+        return 0;
+    /* if the Sub is using more than 1 P reg, we can't JIT it yet 
+     * the P reg could be a (recursive) call to a sub 
+     */
+    if (n_regs_used[REGNO_PMC] > 1)
+        return 0;
+    return 1;
+}
+
+        
+static int
+args_match_params(Interp *interpreter, PMC *sig_args,
+        struct PackFile_ByteCode *seg, opcode_t *start)
+{
+    PMC *sig_params;
+    int n, type;
+    
+    if (*start != PARROT_OP_get_params_pc)
+        return 0;
+    sig_params = seg->const_table->constants[start[1]]->u.key;
+    /* verify that we actually can pass arguments */
+    ASSERT_SIG_PMC(sig_params);
+
+    n = parrot_pic_check_sig(interpreter, sig_args, sig_params, &type);
+    if (n == -1) {
+        /* arg count mismatch */
+        return 0;
+    }
+    if (!n) {
+        /* no args - this would be save, if the JIT code could already
+         * deal with no args
+         * TODO
+         */
+        return 0;
+    }
+    type &= ~PARROT_ARG_CONSTANT;
+    switch (type) {
+        case PARROT_ARG_INTVAL:
+        case PARROT_ARG_FLOATVAL:
+            return 1;
+    }
+    return 0;
+}
+
 int
 parrot_pic_is_save_to_jit(Interp *interpreter, PMC *sub,
        PMC *sig_args, PMC *sig_results)
 {
     STRING *name;
 
+    opcode_t *base, *start, *end;
+
+    /* simplify debugging */
     name = VTABLE_get_string(interpreter, sub);
+
+    /* 1) if the JIT system can't JIT_CODE_SUB_REGS_ONLY
+     *    or the sub is using too many registers
+     */ 
+    if (!jit_can_compile_sub(interpreter, sub))
+        return 0;
+    /*
+     * 2) check if get_params is matching set_args
+     */
+
+    base = PMC_sub(sub)->seg->base.data;
+    start = base + PMC_sub(sub)->start_offs;
+    end   = base + PMC_sub(sub)->end_offs;
+
+    if (!args_match_params(interpreter, sig_args, PMC_sub(sub)->seg, start))
+        return 0;
+
     /* XXX test code */
     if (memcmp((char*) name->strstart, "__pic_test", 10) != 0)
        return 0;
@@ -98,7 +183,7 @@ parrot_pic_JIT_sub(Interp *interpreter, 
     Parrot_jit_info_t *jit_info;
     opcode_t *base, *start, *end;
 
-    base = interpreter->code->base.data;
+    base = PMC_sub(sub)->seg->base.data;
     start = base + PMC_sub(sub)->start_offs;
     end   = base + PMC_sub(sub)->end_offs;
     /* TODO pass Sub */

Reply via email to