Re: [perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-08-02 Thread Leopold Toetsch
Kenneth Graves wrote:

   From: Leopold Toetsch <[EMAIL PROTECTED]>
[ optimized register allocation ]


Is there a stub of this functionality in the code somewhere?
(Or some notes about how it might be approached?)
No, not yet. Currently local variables (and parameters if a sub calls 
another sub) are allocated registers from #16 up. A subroutine call (as 
well as your yield code) does savetop/restoretop to preserve these 
registers.
So this should work for now, if no more then 16 registers are needed, 
that is for not too complicated code.


I'm either going to have to put this in the CLU compiler, or in IMCC.
I think its up to imcc to handle that stuff. If e.g. a parameter doesn't 
live beyond a subroutine call, it can get register numbers in the low 
range. If then no registers of this kind have to be preserved, imcc can 
change the register save opcode accordingly. A HL can hardly emit that 
kind of code.


--kag
leo




Re: [perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-08-01 Thread Kenneth Graves
   From: Leopold Toetsch <[EMAIL PROTECTED]>
   Date: Fri, 1 Aug 2003 14:50:05 +0200

   Kenneth A Graves <[EMAIL PROTECTED]> wrote:
   > Inside the iterator, there are three differences compared to a function:
   > 1) Every register in use needs to be saved to the user stack.  (Anyone
   > have a clean way to do this?)

   Its the same thing as calling a subroutine in the first place. Imcc has
   to figure out, which registers are used (and which are persistent over
   the function call). With this info the register allocation as well as
   the necessary register save/restore opcodes can be optimized.

   When this is done, the same logic applies to the .pcc_*_yield block.

Is there a stub of this functionality in the code somewhere?
(Or some notes about how it might be approached?)

I'm either going to have to put this in the CLU compiler, or in IMCC.
Advantage of the first is that I'm working in Perl instead of C.  (My
C is *way* rusty.)  Advantage of the second is that someone else will
get use out of it.

--kag


Re: [perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-08-01 Thread Leopold Toetsch
Kenneth A Graves <[EMAIL PROTECTED]> wrote:

> Inside the iterator, there are three differences compared to a function:
> 1) Every register in use needs to be saved to the user stack.  (Anyone
> have a clean way to do this?)

Its the same thing as calling a subroutine in the first place. Imcc has
to figure out, which registers are used (and which are persistent over
the function call). With this info the register allocation as well as
the necessary register save/restore opcodes can be optimized.

When this is done, the same logic applies to the .pcc_*_yield block.

> --kag

leo


Re: [perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-08-01 Thread Leopold Toetsch
Kenneth A Graves <[EMAIL PROTECTED]> wrote:

> The .pcc_* directives are working for me in terms of implementing
> function calls.  I want to do something similar for iterator calls.
> I've decided to implement iterators using coroutines.

I have applied it. The test program foo.pir is now a test in t/syn/pcc.t

Thanks for the patch,
leo


Re: [perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-07-31 Thread Leopold Toetsch
Kenneth A Graves (via RT) wrote:

The .pcc_* directives are working for me in terms of implementing
function calls.  I want to do something similar for iterator calls. 
I've decided to implement iterators using coroutines.
Seems very well done and clean to me. Albeit further comments of 
lanugage gurus WRT coroutines & iterators might be helpful/welcome. If 
tha patch gets warnocked, I'll commit.
 Additionally some tests would be fine: a source code thingy like 
t/imcpasm/pcc.t[1] (or a separate file) and some running examples with 
output to be compared.

[1] I know that these are a PITA to maintain. A simple change in e.g. 
the register allocator changes allocated Parrot register numbers and 
breaks mostly all tests. OTOH its IMHO unavoidable to consolidate a 
desired output, what code actually is spit out. - At least for now, 
until all the specs are carved in granite and a functional test giving 
just a test result will suffice.

leo



[perl #23186] [PATCH] adding "yield" semantics to IMCC

2003-07-31 Thread via RT
# New Ticket Created by  Kenneth A Graves 
# Please include the string:  [perl #23186]
# in the subject line of all future correspondence about this issue. 
# http://rt.perl.org/rt2/Ticket/Display.html?id=23186 >


The .pcc_* directives are working for me in terms of implementing
function calls.  I want to do something similar for iterator calls. 
I've decided to implement iterators using coroutines.

The initial call to the iterator (sending in the parameters) is
identical to a function call, except P0 is a Coroutine PMC instead of a
Sub, and there is an implicit Continuation argument to mark where the
caller wants control to go after the iterator is complete.

Subsequent calls to the iterator are just savetop, invoke, loop around
to the return_from_subroutine label.

Inside the iterator, there are three differences compared to a function:
1) Every register in use needs to be saved to the user stack.  (Anyone
have a clean way to do this?)
2) Returning control to the caller is via "invoke", not "invoke P1".
3) When finished, invoke the implicit Continuation mentioned above.

To get this to work with IMCC, the only change I need is to get (2) to
happen.  So I added ".pcc_begin_yield" and ".pcc_end_yield", which do
the exact same thing as ".pcc_begin_return" and ".pcc_end_return",
except leaving off the " P1".  (For now.  Moving the save/restore of (1)
sub into the yield would be nice if I can figure out a way to do it.)

Example code and patch (relative to languages/imcc) attached.  If I'm
off in left field compared to how coroutines/iterators were planned to
be supported, someone please say so.

--kag





-- attachment  1 --
url: http://rt.perl.org/rt2/attach/62028/45719/dee7e8/pcc_yield.patch

-- attachment  2 --
url: http://rt.perl.org/rt2/attach/62028/45720/422adf/foo.pir

--- imcc.l.~1.40.~  2003-07-30 11:00:29.0 -0400
+++ imcc.l  2003-07-31 12:38:42.0 -0400
@@ -153,6 +153,8 @@
 ".pcc_sub"  return(PCC_SUB);
 ".pcc_begin_return"return(PCC_BEGIN_RETURN);
 ".pcc_end_return"  return(PCC_END_RETURN);
+".pcc_begin_yield"return(PCC_BEGIN_YIELD);
+".pcc_end_yield"  return(PCC_END_YIELD);
 "prototyped"return PROTOTYPED;
 "non_prototyped"return NON_PROTOTYPED;
 
--- imcc.y.~1.71.~  2003-07-30 19:00:18.0 -0400
+++ imcc.y  2003-07-31 13:01:50.0 -0400
@@ -409,13 +409,14 @@
 %token  GLOBAL ADDR CLONE RESULT RETURN POW SHIFT_RIGHT_U LOG_AND LOG_OR
 %token  COMMA ESUB
 %token  PCC_BEGIN PCC_END PCC_CALL PCC_SUB PCC_BEGIN_RETURN PCC_END_RETURN
+%token  PCC_BEGIN_YIELD PCC_END_YIELD
 %token  PROTOTYPED NON_PROTOTYPED
 %token  LABEL
 %token  EMIT EOM
 %token  IREG NREG SREG PREG IDENTIFIER STRINGC INTC FLOATC REG MACRO ENDM
 %token  PARROT_OP
 %type  type
-%type  program sub sub_start emit nsub pcc_sub sub_body pcc_ret
+%type  program sub sub_start emit nsub pcc_sub sub_body pcc_ret pcc_yield
 %type  classname relop
 %type  labels _labels label statements statement
 %type  pcc_sub_call
@@ -582,6 +583,22 @@
 PCC_END_RETURN '\n' { $$ = 0; }
 ;
 
+pcc_yield: PCC_BEGIN_YIELD '\n' {
+Instruction *i, *ins = instructions;
+char name[128];
+if (!ins || !ins->r[1] || ins->r[1]->type != VT_PCC_SUB)
+fataly(EX_SOFTWARE, "pcc_yield", line,
+"pcc_yield not inside pcc subroutine\n");
+$$ = ins->r[1];
+sprintf(name, "#pcc_sub_yield_%d:", line - 1);
+i = _mk_instruction("", name, NULL, 0);
+i = emitb(i);
+i->type = ITPCCSUB | ITLABEL | ITPCCYIELD;
+}
+pcc_returns
+PCC_END_YIELD '\n' { $$ = 0; }
+;
+
 pcc_returns: /* empty */{ $$ = 0; }
 |   pcc_returns '\n'{ if($1) add_pcc_return($0, $1); }
 | pcc_returns pcc_return '\n'   { if($2) add_pcc_return($0, $2); }
@@ -599,6 +616,7 @@
 | MACRO '\n'  { $$ = 0; }
 | pcc_sub_call{ $$ = 0; }
 | pcc_ret
+| pcc_yield
 ;
 
 labels:/* none */ { $$ = NULL; }
--- instructions.h.~1.24.~  2003-07-29 11:00:15.0 -0400
+++ instructions.h  2003-07-31 12:53:29.0 -0400
@@ -11,7 +11,8 @@
 ITSPILL = 0x40, /*   set P31,x ; set x, p31 spilling */
 ITEXT   = 0x80, /*   instruction is extcall in JIT */
 ITSAVES = 0x100,  /*   saveall/restoreall in a bsr */
-ITPCCSUB = 0x200  /*  PCC sub call */
+ITPCCSUB = 0x200,  /*  PCC sub call */
+ITPCCYIELD = 0x400 /* yield from PCC call instead of return */
 };
 
 
--- pcc.c.~1.1.~2003-07-30 09:42:48.0 -0400
+++ pcc.c   2003-07-31 13:22:15.0 -0400
@@ -48,9 +48,10 @@
 expand_pcc_sub_ret(Parrot_Interp interpreter, Instruction *ins)
 {
 SymReg *