Dynamically choosing a register

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Dynamically choosing a register

J J-6
Hello list,

I have a question that is probably silly, but I couldn't find anything on the internet that answered it exactly.

I am looking at a register machine version of Squeak, and one thought I had to make the number of operations per method even less was that the send opcode would put the location that the result should be stored into a variable in the new active context.

My question was, in some cases I would like this to be a literal hardware, but is that even possible?  Do all register names have to already be in code or can a memory location refer to a register and the CPU use it (e.g. x86store_op [some memory location that points to a register]  ; double indirection)?

Thanks,
Jason


PC Magazine’s 2007 editors’ choice for best web mail—award-winning Windows Live Hotmail. Check it out!
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically choosing a register

Igor Stasenko
On 24/07/07, J J <[hidden email]> wrote:

>
>  Hello list,
>
> I have a question that is probably silly, but I couldn't find anything on
> the internet that answered it exactly.
>
> I am looking at a register machine version of Squeak, and one thought I had
> to make the number of operations per method even less was that the send
> opcode would put the location that the result should be stored into a
> variable in the new active context.
>
> My question was, in some cases I would like this to be a literal hardware,
> but is that even possible?  Do all register names have to already be in code
> or can a memory location refer to a register and the CPU use it (e.g.
> x86store_op [some memory location that points to a register]  ; double
> indirection)?
i designed a bytecode, and interpreter which puts message results in
#result register.
this simply reduces a stack operations by a half maybe.

as i understood, you want to do similar by telling a send oop, where
to store a result.
well, you may point to stack index, or point to address of memory with
given stack index.
but i'm unsure, is stack in squeak are subject for GC relocations. if
so, then better use index rather than pointers.

>
> Thanks,
> Jason
>
> ________________________________
> PC Magazine's 2007 editors' choice for best web mail—award-winning Windows
> Live Hotmail. Check it out!
> _______________________________________________
> Exupery mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
>
>

--
Best regards,
Igor Stasenko AKA sig.

_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

RE: Dynamically choosing a register

J J-6
In reply to this post by J J-6
> Date: Tue, 24 Jul 2007 20:37:12 +0300

> From: [hidden email]
> To: [hidden email]
> Subject: Re: Dynamically choosing a register
>
> as i understood, you want to do similar by telling a send oop, where
> to store a result.
> well, you may point to stack index, or point to address of memory with
> given stack index.
> but i'm unsure, is stack in squeak are subject for GC relocations. if
> so, then better use index rather than pointers.

Ok, I sent this mail in a rush because I didn't want to still be on the train when it left my station, so I figured it wouldn't end up making sense. :)

What I mean is, right now MethodConext's have various fields in them (BlockContexts as well, but they point to MethodContexts for most information).  What I was thinking of doing was adding an addition field "returnLocation".  This way the compiler can simply ensure the value that is to be returned stores it's value to that area directly.

Example (I means instance variable location, O means Object for the general purpose registers, S is a special and L is the literal frame):

center
  ^ origin + corner / 2

might be translated to:

send2 #+ I1 I2 O1         ; Send the message #+ with the first instance slot as the receiver (first object) and the second instance slot as the argument. Store results in GP register O1
send2 #/ O1 S(2) RET   ; Send #/ with O1 as the receiver and the special number 2 as the argument.  store the result into what ever place *our caller* expects it to be stored
ret                               ; Destroy this context and reactivate the previous one

So note above that when the receiver in O1 receives the #/ message the RET field in *his* activation context will be the same as *ours (i.e. center's)*.  So when he stores the answer we don't have to do anything, as it is in the right place already.

The complexity comes from the fact that RET might be an instance variable, a temp variable location, a GP register *or* it may be an actual hardware register.  But I'm not sure if that's even doable without making self-modifying code, which lead to my question:  Can I have some value that I pass around dynamically that "points" to a hardware register?

I can easily have a special encoding that says "the 3rd general purpose hardware register" or even the literal x86 value that maps to e.g. "eax", but how would one use this value at runtime?  C, et al don't have this problem because the compiler explicitly states what values are going into which registers at build time.  I have never heard of passing around a register "address".

Of course I could do something like (note: the following pseudo code is intended to be a low level lisp-like language that compiles directly to machine code):

(def store-to-register (reg val)
  (cond (reg)
    ((number-that-means-eax) (store eax val)
    .....

But if it's going to be the expensive I may as well just store into memory.  I was hoping I could do something like (example in pseudo assembly this time):

movRegAt %ebx, $val   ; the ebx register somehow has a reference to another register and stores $val there instead of ebx or memory or anywhere else.

I suppose, since I have to have different functions for each addressing mode anyway, I can just have the routine that detects the type overwrite the register in the register store routine directly every time. :)

Hopefully that makes a little more sense. :)

Thanks,
Jason


Don't get caught with egg on your face.    Play Chicktionary! 
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically choosing a register

Igor Stasenko
On 25/07/07, J J <[hidden email]> wrote:

>
>  > Date: Tue, 24 Jul 2007 20:37:12 +0300
> > From: [hidden email]
> > To: [hidden email]
> > Subject: Re: Dynamically choosing a register
> >
> > as i understood, you want to do similar by telling a send oop, where
> > to store a result.
> > well, you may point to stack index, or point to address of memory with
> > given stack index.
> > but i'm unsure, is stack in squeak are subject for GC relocations. if
> > so, then better use index rather than pointers.
>
> Ok, I sent this mail in a rush because I didn't want to still be on the
> train when it left my station, so I figured it wouldn't end up making sense.
> :)
>
> What I mean is, right now MethodConext's have various fields in them
> (BlockContexts as well, but they point to MethodContexts for most
> information).  What I was thinking of doing was adding an addition field
> "returnLocation".  This way the compiler can simply ensure the value that is
> to be returned stores it's value to that area directly.
>
> Example (I means instance variable location, O means Object for the general
> purpose registers, S is a special and L is the literal frame):
>
> center
>   ^ origin + corner / 2
>
> might be translated to:
>
> send2 #+ I1 I2 O1         ; Send the message #+ with the first instance slot
> as the receiver (first object) and the second instance slot as the argument.
> Store results in GP register O1
> send2 #/ O1 S(2) RET   ; Send #/ with O1 as the receiver and the special
> number 2 as the argument.  store the result into what ever place *our
> caller* expects it to be stored
> ret                               ; Destroy this context
> and reactivate the previous one
>
Now take a look how bytecode will look like with using #result register.
Assuming that any message always puts evaluation result into this
register (not stack) we have:

push I1 (origin)
push I2 (corner)
send #+
push #result (after message sent, we have result in #result register)
push S(2)
send #/
ret (after #/ message sent, we have result in #result register, since
its already there, all we need is just return)

same as yours, but not caring about letting message know, where to store result,
because messages always store it in same register (#result).
It can be a simple global memory location or, if you insist, it can be
always an eax register on x86 architecture :)

> So note above that when the receiver in O1 receives the #/ message the RET
> field in *his* activation context will be the same as *ours (i.e.
> center's)*.  So when he stores the answer we don't have to do anything, as
> it is in the right place already.
>
> The complexity comes from the fact that RET might be an instance variable, a
> temp variable location, a GP register *or* it may be an actual hardware
> register.  But I'm not sure if that's even doable without making
> self-modifying code, which lead to my question:  Can I have some value that
> I pass around dynamically that "points" to a hardware register?
>
> I can easily have a special encoding that says "the 3rd general purpose
> hardware register" or even the literal x86 value that maps to e.g. "eax",
> but how would one use this value at runtime?  C, et al don't have this
> problem because the compiler explicitly states what values are going into
> which registers at build time.  I have never heard of passing around a
> register "address".
>
> Of course I could do something like (note: the following pseudo code is
> intended to be a low level lisp-like language that compiles directly to
> machine code):
>
> (def store-to-register (reg val)
>   (cond (reg)
>     ((number-that-means-eax) (store eax val)
>     .....
>
> But if it's going to be the expensive I may as well just store into memory.
> I was hoping I could do something like (example in pseudo assembly this
> time):
>

Yes, in this case, you need a self-modifying code, so you need to
write something to some memory location, before CPU gets to that code.
Then this is not faster than simply writing result to some well known
memory location rather than modifying code to store result into
particular machine register and executing it.
Also, consider that writing to code location invalidates a CPU
instruction cache for this location and forces it to reread
instructions from memory.


> movRegAt %ebx, $val   ; the ebx register somehow has a reference to another
> register and stores $val there instead of ebx or memory or anywhere else.
>
> I suppose, since I have to have different functions for each addressing mode
> anyway, I can just have the routine that detects the type overwrite the
> register in the register store routine directly every time. :)
>
> Hopefully that makes a little more sense. :)
>
I see, you want to make bytecode to use as many registers as it can to
reduce stack usage, so unary or binary send can be sent using machine
registers..

Well, you putting in RET some code , indicating where to store result.
What prevents you to translate it like bytecode? You can build a jump
table and perform different operations depending of RET code for
storing result at pointed place.

So, you can divide RET byte in two hexes, lower will indicate an
index, higher - place to store.
(00 << 4) + x   - store result in machine register , x - register index.
(01 << 4) + x  - store result to ivar of receiver of parent context, x
- ivar index
.... e.t.c



> Thanks,
> Jason
>
> ________________________________
> Don't get caught with egg on your face.    Play Chicktionary!
> _______________________________________________
> Exupery mailing list
> [hidden email]
> http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
>
>

--
Best regards,
Igor Stasenko AKA sig.
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

RE: Dynamically choosing a register

Bryce Kampjes
In reply to this post by J J-6

Do you mean for the cond to be evaluated at compile time in the
following?

   (def store-to-register (reg val)
  (cond (reg)
         ((number-that-means-eax) (store eax val)

If so you could just generate:
   (mov t1 eax)

Then the register allocator will try to allocate t1 in eax
and remove that move.

Bryce
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

RE: Dynamically choosing a register

J J-6
In reply to this post by J J-6
> From: [hidden email]

> Date: Thu, 26 Jul 2007 11:43:43 +0100
> To: [hidden email]
> Subject: RE: Dynamically choosing a register
>
>
> Do you mean for the cond to be evaluated at compile time in the
> following?
>
> (def store-to-register (reg val)
>   (cond (reg)
>     ((number-that-means-eax) (store eax val)

No, it can't be compile time since val will live in a field in instances of MethodContext.  I can't know what val is until runtime.  What I really want is a way to store in memory or another register some kind of reference to a register so that I would have the option in my VM that a caller can request the answer put right into the literal register of his choice.

> If so you could just generate:
> (mov t1 eax)
>
> Then the register allocator will try to allocate t1 in eax
> and remove that move.
>
> Bryce

Is there any documentation on your mid and low level code generator?  I would like to make a lisp-like language that targets it.  This way I wouldn't have to make a compiler for every processor type, but I would have full power of the CPU and no dependencies on C.


See what you’re getting into…before you go there. Check it out!
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

Re: Dynamically choosing a register

Klaus D. Witzel
On Thu, 26 Jul 2007 20:24:06 +0200, J J wrote:

>
>> From: [hidden email]> Date: Thu, 26 Jul 2007 11:43:43 +0100>  
>> To: [hidden email]> Subject: RE: Dynamically  
>> choosing a register> > > Do you mean for the cond to be evaluated at  
>> compile time in the> following?> >    (def store-to-register (reg  
>> val)>   (cond (reg)>          ((number-that-means-eax) (store eax val)
> No, it can't be compile time since val will live in a field in instances  
> of MethodContext.  I can't know what val is until runtime.  What I  
> really want is a way to store in memory or another register some kind of  
> reference to a register so that I would have the option in my VM that a  
> caller can request the answer put right into the literal register of his  
> choice.

If you use some form of the traditional call/return sequence, have the  
caller reserve a #return slot at a fixed location (offset). There the  
callee can store its return value (you mentioned a way to store in  
memory). Then the caller can pop/move the value into any register it  
likes, dynamically and independent of the callee.

Cheers
Klaus

>> If so you could just generate:>    (mov t1 eax)> > Then the register  
>> allocator will try to allocate t1 in eax> and remove that move.> >  
>> BryceIs there any documentation on your mid and low level code  
>> generator?  I would like to make a lisp-like language that targets it.  
>> This way I wouldn't have to make a compiler for every processor type,  
>> but I would have full power of the CPU and no dependencies on C.
> _________________________________________________________________
> See what you’re getting into…before you go there.
> http://newlivehotmail.com


_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery
Reply | Threaded
Open this post in threaded view
|

RE: Dynamically choosing a register

Bryce Kampjes
In reply to this post by J J-6
J J writes:
 >
 > > From: [hidden email]> Date: Thu, 26 Jul 2007 11:43:43 +0100> To: [hidden email]> Subject: RE: Dynamically choosing a register> > > Do you mean for the cond to be evaluated at compile time in the> following?> >    (def store-to-register (reg val)>   (cond (reg)>          ((number-that-means-eax) (store eax val)No, it can't be compile time since val will live in a field in instances of MethodContext.  I can't know what val is until runtime.  What I really want is a way to store in memory or another register some kind of reference to a register so that I would have the option in my VM that a caller can request the answer put right into the literal register of his choice.> If so you could just generate:>    (mov t1 eax)> > Then the register allocator will try to allocate t1 in eax> and remove that move.> > BryceIs there any documentation on your mid and low level code generator?  I would like to make a lisp-like language that targets it.  This way I wouldn't have to make a compiler for every processor type, but I would have full power of the CPU and no dependencies on C.
 > _________________________________________________________________

The best documentation about Exupery's internals is:

    http://www.kampjes.demon.co.uk/articles/exuperyDesign.pdf

Beyond that you're best looking at the source. If you're planning
on running your Lisp inside Squeak then I'd probably subclass and
adapt IntermediateSimplifier as it contains useful code to access
the object memory.

I'd also recommend writing test first using the Mocks provided,
the learning curve will be a little steeper initially but testing
pays of surprising quickly.

Bryce
_______________________________________________
Exupery mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/exupery