Variadic functions questions

0 views
Skip to first unread message

Ilya Martynov

unread,
Mar 22, 2004, 4:44:47 AM3/22/04
to perl6-i...@perl.org

Hello all,

1) First question is how to tell if variadic function recieved 11 or
12 or more params (for simplicity let's suppose that we use only
pmc parameters).

According calling conventions (pdd03) first 11 params end up in P5-P15
registers and leftover goes into array in P3. The problem is that
there is no indication (unless I'm missing something) if function was
called with more than 11 params other than register P3 being
initialized with some array PMC. But it may be as well that function
was called with just 11 params and P3 contains some array by accident
(it could be for example some array from previous sub call).

2) Second question if there is an op to access registers by their
number (it is quite troublesome to write code to retrieve
parameters in variadic function from P5-P15 registeres without such
op).

ops/set.ops has setp_ind op which allows to write to register by its
number but it seems there is no op to read register by its number.

3) Not really a question but a feature request for IMCC to provide
some support for variadic functions to avoid writing same code
again and again to read parameters of variadic function from either
P5-P15 registers or from array in P3 register as necessary. Not
sure about syntax though. It could look for example like this:

# calculates sum of all parameters
.sub _sum
new $P1, .PerlInt
$P1 = 0
# generates code which sets $I1 to a number of parameters
$I1 = .param_num
loop:
if $I1 == 0 goto return
# retrieves a parameter by its number
$P2 = .param($I1)
add $P1, $P2
dec $I1
goto loop
return:
.pcc_begin_return
.return $P1
.pcc_end_return
.end


--
Ilya Martynov, il...@iponweb.net
CTO IPonWEB (UK) Ltd
Quality Perl Programming and Unix Support
UK managed @ offshore prices - http://www.iponweb.net
Personal website - http://martynov.org

Leopold Toetsch

unread,
Mar 22, 2004, 6:13:44 AM3/22/04
to Ilya Martynov, perl6-i...@perl.org
Ilya Martynov <il...@iponweb.net> wrote:

> Hello all,

> 1) First question is how to tell if variadic function recieved 11 or
> 12 or more params (for simplicity let's suppose that we use only
> pmc parameters).

> According calling conventions (pdd03) first 11 params end up in P5-P15
> registers and leftover goes into array in P3. The problem is that
> there is no indication (unless I'm missing something) if function was
> called with more than 11 params other than register P3 being
> initialized with some array PMC. But it may be as well that function
> was called with just 11 params and P3 contains some array by accident
> (it could be for example some array from previous sub call).

11 arguments passed: P5..P15, P3 is NULL (is_null P3 ...)
12 arguments passed: P5..P15, Ix = P3, Ix := 1

But I'm not sure if P3 actually is cleared (rather not :)

> 2) Second question if there is an op to access registers by their
> number (it is quite troublesome to write code to retrieve
> parameters in variadic function from P5-P15 registeres without such
> op).

You are probably looking for C<foldup>. s. t/op/calling.t

> 3) Not really a question but a feature request for IMCC to provide
> some support for variadic functions to avoid writing same code
> again and again to read parameters of variadic function from either
> P5-P15 registers or from array in P3 register as necessary. Not
> sure about syntax though. It could look for example like this:

C<foldup> again.

leo

Jens Rieks

unread,
Mar 22, 2004, 6:50:09 AM3/22/04
to perl6-i...@perl.org, Ilya Martynov
Hi,

On Monday 22 March 2004 10:44, Ilya Martynov wrote:
> Hello all,
>
> 1) First question is how to tell if variadic function recieved 11 or
> 12 or more params (for simplicity let's suppose that we use only
> pmc parameters).
>
> According calling conventions (pdd03) first 11 params end up in P5-P15
> registers and leftover goes into array in P3. The problem is that
> there is no indication (unless I'm missing something) if function was
> called with more than 11 params other than register P3 being
> initialized with some array PMC. But it may be as well that function
> was called with just 11 params and P3 contains some array by accident
> (it could be for example some array from previous sub call).

I0=1 => prototyped I0=0 => unprototyped
I1=number of INT parameters
I2=number of STRING parameters
I3=number of PMC parameters
I4=number of NUM parameters

Leo, is it easy to alias them as argc[ISPN]?

> 2) Second question if there is an op to access registers by their
> number (it is quite troublesome to write code to retrieve
> parameters in variadic function from P5-P15 registeres without such
> op).
>
> ops/set.ops has setp_ind op which allows to write to register by its
> number but it seems there is no op to read register by its number.

I had the same problem, too.

> 3) Not really a question but a feature request for IMCC to provide
> some support for variadic functions to avoid writing same code
> again and again to read parameters of variadic function from either
> P5-P15 registers or from array in P3 register as necessary. Not
> sure about syntax though. It could look for example like this:
>
> # calculates sum of all parameters
> .sub _sum
> new $P1, .PerlInt
> $P1 = 0
> # generates code which sets $I1 to a number of parameters
> $I1 = .param_num

$I1 = I3

> loop:
> if $I1 == 0 goto return
> # retrieves a parameter by its number
> $P2 = .param($I1)

I vote for
getreg $P1, $I1 # put Px (x=I1) into $P1
and/or
getarg $P1, $I1 # put PMC arg number I1 into $P1 (P5..P14, then P3[I-11])


> add $P1, $P2
> dec $I1
> goto loop
> return:
> .pcc_begin_return
> .return $P1
> .pcc_end_return
> .end

Good idea. I second that.

jens

Dan Sugalski

unread,
Mar 22, 2004, 7:58:13 AM3/22/04
to Jens Rieks, perl6-i...@perl.org, Ilya Martynov
At 12:50 PM +0100 3/22/04, Jens Rieks wrote:
> > ops/set.ops has setp_ind op which allows to write to register by its
>> number but it seems there is no op to read register by its number.
>I had the same problem, too.

That needs fixing. If you want to throw together a patch, by all
means go for it.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Leopold Toetsch

unread,
Mar 22, 2004, 8:08:57 AM3/22/04
to Ilya Martynov, perl6-i...@perl.org
Ilya Martynov wrote:

>
> Prints 'P3 is not NULL'

Yep, some minutes ago I've fixed it. Thanks for the test, I've added it
plus another one to CVS.


leo


Leopold Toetsch

unread,
Mar 22, 2004, 7:54:23 AM3/22/04
to Jens Rieks, perl6-i...@perl.org
Jens Rieks <par...@jensbeimsurfen.de> wrote:

First a note: P3 is now cleared, if P15 is reached. So havin 11 args can
be distinguished from having more then 11 arguments.

> Leo, is it easy to alias them as argc[ISPN]?

Yes. It's the same as aliasing C<self> to P2. If we can agree on the
variable names, this is done in a minute.

if argcP > 2 goto more_then_2_Pargs

looks quite good.

And P3 := overflow_args ?
P0 := the_sub ??
P1 := return_continuation ?
S0 := method_name ?

>> # retrieves a parameter by its number
>> $P2 = .param($I1)
> I vote for
> getreg $P1, $I1 # put Px (x=I1) into $P1

This is all not really good. The register allocator can't track the
usage of Px.

> jens

leo

Ilya Martynov

unread,
Mar 22, 2004, 7:07:37 AM3/22/04
to l...@toetsch.at, perl6-i...@perl.org
>>>>> "LT" == Leopold Toetsch <l...@toetsch.at> writes:

LT> Ilya Martynov <il...@iponweb.net> wrote:
>> Hello all,

>> 1) First question is how to tell if variadic function recieved 11 or
>> 12 or more params (for simplicity let's suppose that we use only
>> pmc parameters).

>> According calling conventions (pdd03) first 11 params end up in P5-P15
>> registers and leftover goes into array in P3. The problem is that
>> there is no indication (unless I'm missing something) if function was
>> called with more than 11 params other than register P3 being
>> initialized with some array PMC. But it may be as well that function
>> was called with just 11 params and P3 contains some array by accident
>> (it could be for example some array from previous sub call).

LT> 11 arguments passed: P5..P15, P3 is NULL (is_null P3 ...)
LT> 12 arguments passed: P5..P15, Ix = P3, Ix := 1

LT> But I'm not sure if P3 actually is cleared (rather not :)

It is not.

.sub _main
P3 = new .PerlArray
# call with 11 parameters
_foo($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, $P9, $P10, $P11)
end
.end

.sub _foo
isnull P3, p3_is_null
print "P3 is not NULL\n"
goto return
p3_is_null:
print "P3 is NULL\n"
return:
.end

Prints 'P3 is not NULL'

>> 2) Second question if there is an op to access registers by their


>> number (it is quite troublesome to write code to retrieve
>> parameters in variadic function from P5-P15 registeres without such
>> op).

LT> You are probably looking for C<foldup>. s. t/op/calling.t

Thanks, I'll take a look.

>> 3) Not really a question but a feature request for IMCC to provide
>> some support for variadic functions to avoid writing same code
>> again and again to read parameters of variadic function from either
>> P5-P15 registers or from array in P3 register as necessary. Not
>> sure about syntax though. It could look for example like this:

LT> C<foldup> again.

LT> leo

Ilya Martynov

unread,
Mar 22, 2004, 7:11:24 AM3/22/04
to Jens Rieks, perl6-i...@perl.org
>>>>> "JR" == Jens Rieks <par...@jensbeimsurfen.de> writes:

JR> Hi,


JR> On Monday 22 March 2004 10:44, Ilya Martynov wrote:
>> Hello all,
>>
>> 1) First question is how to tell if variadic function recieved 11 or
>> 12 or more params (for simplicity let's suppose that we use only
>> pmc parameters).
>>
>> According calling conventions (pdd03) first 11 params end up in P5-P15
>> registers and leftover goes into array in P3. The problem is that
>> there is no indication (unless I'm missing something) if function was
>> called with more than 11 params other than register P3 being
>> initialized with some array PMC. But it may be as well that function
>> was called with just 11 params and P3 contains some array by accident
>> (it could be for example some array from previous sub call).

JR> I0=1 => prototyped I0=0 => unprototyped
JR> I1=number of INT parameters
JR> I2=number of STRING parameters
JR> I3=number of PMC parameters
JR> I4=number of NUM parameters

These registers contain number of parameters stored in *registers*. It
doesn't include left-over parameters in array in P3. It is always 11
if you have more than 11 parameters.

>> [..snip..]

Jens Rieks

unread,
Mar 22, 2004, 8:31:45 AM3/22/04
to l...@toetsch.at, perl6-i...@perl.org
Hi,

On Monday 22 March 2004 13:54, Leopold Toetsch wrote:
> Jens Rieks <par...@jensbeimsurfen.de> wrote:
>
> First a note: P3 is now cleared, if P15 is reached. So havin 11 args can
> be distinguished from having more then 11 arguments.
>
> > Leo, is it easy to alias them as argc[ISPN]?
>
> Yes. It's the same as aliasing C<self> to P2. If we can agree on the
> variable names, this is done in a minute.
>
> if argcP > 2 goto more_then_2_Pargs
>
> looks quite good.
>
> And P3 := overflow_args ?
> P0 := the_sub ??
> P1 := return_continuation ?
> S0 := method_name ?

Sounds okay. Maybe its better to either alias return_continuation to the
register where P1 has been saved to? Or add another alias for it?

> >> # retrieves a parameter by its number
> >> $P2 = .param($I1)
> >
> > I vote for
> > getreg $P1, $I1 # put Px (x=I1) into $P1
>
> This is all not really good. The register allocator can't track the
> usage of Px.

That is a strong argument. "setp_ind" on the other hand is also not tracked.
getp_ind might by a reasonable tradeoff.

> leo
jens

Ilya Martynov

unread,
Mar 22, 2004, 8:16:15 AM3/22/04
to Leopold Toetsch, perl6-i...@perl.org
>>>>> "LT" == Leopold Toetsch <l...@toetsch.at> writes:

LT> Ilya Martynov wrote:
>> Prints 'P3 is not NULL'

LT> Yep, some minutes ago I've fixed it. Thanks for the test, I've added
LT> it plus another one to CVS.

There is a small typo in comment for second test case:

Index: imcc/t/syn/pcc.t
===================================================================
RCS file: /cvs/public/parrot/imcc/t/syn/pcc.t,v
retrieving revision 1.38
diff -u -d -r1.38 pcc.t
--- imcc/t/syn/pcc.t 22 Mar 2004 13:09:32 -0000 1.38
+++ imcc/t/syn/pcc.t 22 Mar 2004 13:15:17 -0000
@@ -1297,7 +1297,7 @@
output_is(<<'CODE', <<'OUT', "P3 isnt NULL - 12 args");


.sub _main
P3 = new .PerlArray

- # call with 11 parameters
+ # call with 12 parameters
_foo($P1, $P2, $P3, $P4, $P5, $P6, $P7, $P8, $P9, $P10, $P11, $P12)
end
.end

Leopold Toetsch

unread,
Mar 22, 2004, 9:22:16 AM3/22/04
to Jens Rieks, perl6-i...@perl.org
Jens Rieks <par...@jensbeimsurfen.de> wrote:
> Hi,

> On Monday 22 March 2004 13:54, Leopold Toetsch wrote:

>> And P3 := overflow_args ?
>> P0 := the_sub ??
>> P1 := return_continuation ?
>> S0 := method_name ?
> Sounds okay. Maybe its better to either alias return_continuation to the
> register where P1 has been saved to? Or add another alias for it?

I'll very likely change the code, so that P1 is restored immediately
after a function call (like P2 now). OTOH it shouldn't matter.
C<return_continuation> or C<self> alias whatever the *actual* thing is.

>> This is all not really good. The register allocator can't track the
>> usage of Px.
> That is a strong argument. "setp_ind" on the other hand is also not tracked.
> getp_ind might by a reasonable tradeoff.

Imcc starts allocating registers at 16. If more then 16 regs are
needed, current code will wrap around and start allocating in the low
range, e.g. it'll use P4. Then *if* there is no sign, that P5 is used,
this will be allocated. If the only reference to P5 is an indirect
register access, things will break, horribly.

We can of course just define, that {g,s]etp_ind will only use registers
0..15 and the register allocator only uses 16..31. All is safe then
again. 16 registers of one kind ougth to be enough. If it still comes to
spilling, first lexicals and globals should be used - these already have
a store somewhere. This still needs some PIR syntax extension:

.lexical foo # pmc is implied
.global bar

> jens

leo

Leopold Toetsch

unread,
Mar 22, 2004, 9:30:50 AM3/22/04
to P6I
Ilya Martynov wrote:

>
> There is a small typo in comment for second test case:

Thanks, fixed.
Plus another test and checks that I3 is really 11.


leo


Reply all
Reply to author
Forward
0 new messages