freenode/#sicl - IRC Chatlog
Search
13:04:09
shka__
beach: non-local control transfer translates basicly into condition handling, right?
13:06:44
beach
OK, so the register allocator decides where each lexical variable is to be found at every program point.
13:08:35
beach
And if there is an instruction that can be reached from two different directions, some incoming control arcs must be augmented with code that adapts the register state from what it is at one end of the control arc to what it must be at the other end.
13:11:52
beach
So the simplest thing to do would be to have each GO or RETURN from just go ahead and restore the state that the register allocator has determined for the target instruction.
13:13:25
beach
Because the register allocator works on each function independently, at least in the simplest case.
13:13:57
shka__
and this is possible because go and return-from still operate in the known lexical env, right? how about a fringe case where (defun fun () (lambda () (return-from fun nil)) ?
13:17:56
beach
In the SICL specification I mention a time stamp for unique identification of an entry.
13:27:26
beach
For GO and RETURN-FROM in a different function, we have the frame pointer (I haven't figured out the stack pointer yet) stored in the BLOCK/TAGBODY entry in the dynamic environment.
13:28:25
beach
We have no callee-saves registers to restore, because when the call was made, the register allocated had made sure that all registers are saved in the stack frame.
13:29:40
beach
But, the register allocator may have determine that, for the target of the GO or RETURN-FROM, some lexical variables are in registers.
13:31:00
beach
So, the result of the GO or the RETURN-FROM is to restore the registers from the stack frame, using the frame pointer in the dynamic environment entry and also to restore the frame pointer.
13:37:09
beach
Of course, in the initial version that I am planning, there is no register allocator.
13:37:46
beach
So every lexical variable is always on the stack, except for a short moment during the execution of an instruction.
13:42:56
beach
Oh, so the purpose of this exercise was to determine what information needs to be saved in a BLOCK/TAGBODY entry in the dynamic environment.
13:46:27
beach
So that, in turn, means that I can implement a CATCH instruction by a function call, passing the stack pointer, the frame pointer, and a unique ID as arguments.
13:47:52
beach
And if I make sure that each target of a GO or RETURN from has no active registers, I can also implement UNWIND as a function call.
13:55:43
beach
So now I have this situation where the CATCH-INSTRUCTION and the UNWIND-INSTRUCTION can both be turned into function calls, and it can be done early because we don't need any low-level machinery like the frame pointer in the caller.
14:06:56
beach
It also means that I can turn the CATCH-INSTRUCTION and the UNWIND-INSTRUCTION into function calls early on, so that neither the HIR interpreter nor HIR-to-MIR-to-LIR need to deal with them.
14:10:41
beach
Oh, and I think I have a simple solution to the difference between unwinding in the case of a RETURN-FROM (where the BLOCK/TAGBODY entry should be popped off of the dynamic environment) and unwinding in the case of GO (where the BLOCK/TAGBODY entry should remain on top of the dynamic environment).
14:11:52
beach
Just have UNWIND not pop it off, and for a CATCH-INSTRUCTION generated from a BLOCK, have the top entry popped off in successor 1 of the CATCH-INSTRUCTION.
15:26:52
beach
So, either I try to simulate it, or I can't translate the CATCH-INSTRUCTION and the UNWIND-INSTRUCTION until HIR-to-MIR.