Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

semi-stack code

3 views
Skip to first unread message

Dan Sugalski

unread,
Jul 14, 2004, 10:20:04 AM7/14/04
to perl6-i...@perl.org
Okay, here's a really, really evil idea. (And yes, bluntly, it's
triggered by the pie-thon bytecode translator's needs) I need a
stack, and one that's faster than our current stack which, while
snappy for what it does, is still burdened by generality. I also need
a stack that's generally not very big. So...

The fake stack. The idea is this. PMC registers 18-29 are used as a
12 element stack. PMC register 31 is used as a stack overflow array.
Integer register I31 is used as the stack depth register. We add in
the ops:

fakepush [Px|Ix]

This pushes the contents of Px onto the top of the stack, or pushes
the stack down by Ix entries. Note that the Ix form does *not* set
these new slots to anything! They're left as-is, which can be an
issue for the GC.

fakepop [ix]

This pops Ix entries off the stack, default of one. Note that there's
no need for any destination--if you're popping the TOS into a
register then just do a set first.

iset Px, Iy

This does a set of register Px to PMC register #Y.

iset Ix, Py

This sets the PMC register #X to Py.

The last two are pretty standard indirect register access. If someone
wants to propose a more generic syntax for it we might want to
generalize on, that's fine--do it *after* OSCON, thanks. :)

The reason for the odd register count and register number usage is
twofold. First, it leaves some of the top-half registers free for
other things. Second, the registers used will be 8-byte aligned and a
multiple of 8 bytes on systems with 4-byte pointers. Not likely a
huge deal, but it may shave a cycle off here or there, and it does
mean we have a few spare registers in the upper half.

Note that this stack does *not* need rot, swap, dup, or other funky
'move the things around' ops, since that can already be done. For
example:

dup:
fakepush 1

dup2 (the top two entries are duplicated)
fakepush 2

swap:
exchange P18, P19

rot3:
exchange P18, P20
exchange P19, P20

And it means that stack based ops turn to:

add (pop the top two entries, add them, and push the result):
new P17
add P17, P18, P19
fakepop
set P18, P17

and something like add-in-place (new TOS = oldTOS+1 + oldTOS):
add P18, P19, P18
fakepop

It seems sensible, which of course worries me, as do so many things I
think are sensible, but I think we should do this--it'll be useful
for other languages that like being stack based. (If I'd any sense,
I'd have done this ages ago as it'd have made the forth
implementation nicer) We should get x86 JIT code for the new ops,
since I expect they'll be used rather a lot.

Full-fledged tracking of used stack slots within basic blocks with
register coloring and cross-block register exchanges would, of
course, make a lot of sense and be faster, but I'm a bit pressed for
time here, so we'll make do. Only the fake push and pop ops are at
all odd, so I'll put those in experimental.ops for now. iset will go
into set.ops, though if we decide that we want a more general
indirect register access scheme we can see about renaming them. (We
probably should put in an opname aliasing feature to the pir and pasm
compilers, but we'll deal with that later, unless someone's feeling
like a project)
--
Dan

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

Leopold Toetsch

unread,
Jul 14, 2004, 1:43:54 PM7/14/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:
> Okay, here's a really, really evil idea. (And yes, bluntly, it's
> triggered by the pie-thon bytecode translator's needs) I need a
> stack,

Do you? I've converted all stack stuff at compile time, till now. I
don't see the point, why this might not work for all opcodes.

> ... and one that's faster than our current stack which, while


> snappy for what it does, is still burdened by generality. I also need
> a stack that's generally not very big. So...

Generally. Have a look at BUILD_TUPLE or BUILD_LIST. The limited stack
will not work, you have to do overflow checking all the time and you'll
have 2 addressing modes, one in registers and one in overflow.

> iset Px, Iy

> This does a set of register Px to PMC register #Y.

C<setp_ind> *is* in set.ops. If above is the other direction, then that
should be named accordingly.

leo

Dan Sugalski

unread,
Jul 14, 2004, 2:44:22 PM7/14/04
to l...@toetsch.at, perl6-i...@perl.org
At 7:43 PM +0200 7/14/04, Leopold Toetsch wrote:
>Dan Sugalski <d...@sidhe.org> wrote:
>> Okay, here's a really, really evil idea. (And yes, bluntly, it's
>> triggered by the pie-thon bytecode translator's needs) I need a
>> stack,
>
>Do you? I've converted all stack stuff at compile time, till now. I
>don't see the point, why this might not work for all opcodes.

There's the issue of basic block analysis which, bluntly, I'm not
comfortable counting on being able to do in the time I've got. I may
do a quick scan tonight, if I have time to hack it up, to see what
the stack looks like going into the blocks. If a block's got multiple
entry points then I need to coordinate register usage across all the
places that could call it, which I'm not sure I've time for.

> > ... and one that's faster than our current stack which, while
>> snappy for what it does, is still burdened by generality. I also need
>> a stack that's generally not very big. So...
>
>Generally. Have a look at BUILD_TUPLE or BUILD_LIST. The limited stack
>will not work, you have to do overflow checking all the time and you'll
>have 2 addressing modes, one in registers and one in overflow.

I know there are a few nasty ones. I'm sorely tempted to toss the
alignment bit and make the stack the same number of registers as we
use for calling conventions, and turn those two into subs, in which
case the setup for the call is a quick copy of the stack registers to
the calling registers, with the overflow array matching for both.

> > iset Px, Iy
>
>> This does a set of register Px to PMC register #Y.
>
>C<setp_ind> *is* in set.ops. If above is the other direction, then that
>should be named accordingly.

I thought that was in there, but I missed that one. I'll add in its complement.

Leopold Toetsch

unread,
Jul 14, 2004, 4:09:52 PM7/14/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski wrote:
> At 7:43 PM +0200 7/14/04, Leopold Toetsch wrote:
>
>> Dan Sugalski <d...@sidhe.org> wrote:
>>
>>> Okay, here's a really, really evil idea. (And yes, bluntly, it's
>>> triggered by the pie-thon bytecode translator's needs) I need a
>>> stack,
>>
>>
>> Do you? I've converted all stack stuff at compile time, till now. I
>> don't see the point, why this might not work for all opcodes.
>
>
> There's the issue of basic block analysis which,

AFAIK not. The branch opcodes have a POP_TOP to get rid of the TOS, when
its not consumed by the compare. I've no indication so far, that this is
a problem. Please look (again) at pie-thon.pl. Check the code in CVS.
Look at the tests. A lot is already there. Function calls (_VAR, _KW)
need work *and* classes, objects, classes, objects ... Did I already
mention objects?

leo

0 new messages