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 */