Front page | perl.perl6.internals |
Postings from May 2001
Re: Stacks & registers
From: Uri Guttman
May 23, 2001 10:26
Re: Stacks & registers
Message ID: 200105231726.NAA25831@home.sysarch.com.
>>>>> "DS" == Dan Sugalski <firstname.lastname@example.org> writes:
DS> Should Parrot be a register or stack-based system, and if a
DS> register-based one, should we go with typed registers?
first question: is this for the intermediate language or the back end
VM? they don't have to be the same.
since our goal is to support the polymorphic front/back end design, the
intermediate language (IL) should be easy to generate and easy to
compile to various targets. also it needs to have other features like
being modifiable for optimization, storable on disk, debuggable (for dev
this IL could be the VM we use in perl itself and it can also be
compiled to other VM's or c, etc.
also it could be processed/compiled to a faster perl VM for execution.
DS> My personal preference here is to make Parrot a register based
DS> system. I can wrap my head around that a lot easier than a stack
DS> system, it's something I'm comfortable with, there's lots of
DS> literature on optimizing this sort of system, and I just generally
DS> like it better. (I cut my programming teeth on 6502s... so sue me
DS> :) Stack based systems have a certain appeal--they're simpler
DS> generally, which is fine. I'm not too worried about simpler as
DS> much as I am faster, and I think we can get faster out of
DS> registers. (Or, if you prefer, "named temporaries" instead of
DS> registers. Whatever)
the PL/I compiler suite i hacked on used that style of IL. but is
allocated as many named temps as it needed by using N-tuples for each op
code. each OP would leave its result in a named temp which could be
referred to by later OPs. i think they were generic (as PL/I could mung
many more types of data than perl) but the compiler knew what held what
so that wasn't an issue.
DS> If (or when, I suppose, barring a Really Good Counter-Argument) we
DS> go the register route, then, should we have typed registers like
DS> most CPUs do? A set of PMC pointer registers, a set of integer
DS> registers, a set of floating-point registers, a set of string
DS> registers? And if we do go with typed registers, should they be
DS> linked together? (So that the int in Iregister 1 matches the
DS> integer value of the PMC in Pregister 1, and the float value in
DS> Fregister 1?) And if they're linked (And should they all be
DS> linked, or only some of them) should we guarantee consistency, or
DS> should the bytecode explicitly make various registers valid or
the problem with a fixed number of registers is register overflow. this
is true in all register based machines and VM's and is a pain. if we go
with a pure named temp architecture, you don't need to worry about
that. but it is slower to access and manage named temps than a fixed set
of registers (or even just a stack which is like a single reg machine).
DS> My current thoughts are this:
DS> We have a set of N registers. They're all linked. Nothing
DS> implicitly sets values in any of the registers (if you want an
DS> integer value, you need to make one). Each register has a set of
DS> validity markers for each type (int, flaot, string, PMC) that may
DS> or may not be bits. We have a stack of sorts that we can push the
DS> registers on to if we need.
that is a good start. the stack can handle the overflow but that means
more complexity in the compiler to deal with that. let's do some study
of various IL designs (including both compiled and interpreted) and see
their wins and losses. i think pure stack based is out as it is too
limiting. i have some experience with N-tuples and it does work well for
compiling as you don't care about the managing of registers at run time
then. you just keep a fat namespace table at compile time and throw it
out later. we have a compile and run phase so managing a large number of
N-tuples may be slow running but easy to generate and manipulate. that
is a typical tradeoff.
so my current best idea is a fixed size set of active N-tuples/registers
(any number larger than most long statements would work, say 100?) as
the registers. each N-tuple has its op code and argument register
indexes and which register it stores its result in. we have a stack for
the overflow handling and that is the hardest part.
we should have a small set of special registers to handle events,
booleans, the PC, signals, etc.
this makes compiling and optimization very easy. we just need to manage
the lifetime of registers for the N-tuples and deal with the (hopefully)
rare overflow. runtime interpretation is also fairly simple (not as easy
as a stack but not too bad) with decent speed. code generation to other
VM or storing to disk should be fairly straightforward.
DS> I'm definitely feeling unsure about this, so feel free (please!)
DS> to wade in with comments, criticisms, or personal attacks... :)
you are a doofus.
but a smart one. :)
Uri Guttman --------- email@example.com ---------- http://www.sysarch.com
SYStems ARCHitecture and Stem Development ------ http://www.stemsystems.com
Learn Advanced Object Oriented Perl from Damian Conway - Boston, July 10-11
Class and Registration info: http://www.sysarch.com/perl/OOP_class.html