<div dir="ltr"><div><div><div>(I'm moving this thread to the developers list.)<br><br></div>I'm not opposed to making more of the compiler operate on lists of expressions.<br></div>I think the place where the giant expression gets made is in con_to_dec, so that's where most of the work would be.<br></div>Scott designed the way it currently works, if I recall correctly.<br></div><div class="gmail_extra"><br><div class="gmail_quote">On 7 July 2017 at 17:58, Magnus Myreen <span dir="ltr"><<a href="mailto:magnus.myreen@gmail.com" target="_blank">magnus.myreen@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">You are right, and I think the idea to split expressions in closLang<br>
phases sounds good.<br>
<br>
There could be a very simple way of splitting them there: split the<br>
main expression at every top-level Seq (note that Seq in closLang is<br>
Let [x; y] (Var 1)), and just chain them together with tail-calls.<br>
<br>
At one point, I was arguing for not composing the main program into<br>
one giant Seq-composed expression, instead I argued that we should<br>
have a list of expressions in languages from closLang and above and<br>
the semantics is that one runs through all of them in order. Such a<br>
setup would make it easy to make a tail-calling chain of all<br>
expressions in closLang. This would mean that there would only be<br>
giant functions in the call table if the user actually wrote a giant<br>
function. I remember that my suggestion was shot down and that I went<br>
on to implement the expression splitting in bvl_to_bvi, because it's a<br>
part of the compiler where I don't need to build a consensus before<br>
being able to change it.<br>
<br>
I think we should revisit whether it's a good idea to compose the<br>
entire program into one giant expression in the early phases of the<br>
compiler. I think the early phases should produce a list of<br>
expressions.<br>
<br>
Cheers,<br>
Magnus<br>
<div class="HOEnZb"><div class="h5"><br>
<br>
On 7 July 2017 at 09:45, Yong Kiam <<a href="mailto:tanyongkiam@gmail.com">tanyongkiam@gmail.com</a>> wrote:<br>
> Hmm, but the offending LocValues that I'm getting so far are the ones<br>
> generated by Fn and Letrec in clos_to_bvi when it's creating the closure<br>
> value for them, and presumably saving the Label.<br>
><br>
> The situation you describe seems like it will only occur if we managed to<br>
> inline the call to something like:<br>
><br>
> ...<br>
> append x y<br>
> ...<br>
><br>
> becomes<br>
><br>
> ...<br>
> r <- Label append<br>
> call r<br>
> ...<br>
><br>
> But in that situation, wouldn't we have already generated Call (...)<br>
> directly and not required a LocValue?<br>
><br>
><br>
> On Fri, Jul 7, 2017 at 5:38 PM, Magnus Myreen <<a href="mailto:magnus.myreen@gmail.com">magnus.myreen@gmail.com</a>><br>
> wrote:<br>
>><br>
>> Hi Yong Kiam and Anthony,<br>
>><br>
>> My worry is that there is no good place to put some of the code table<br>
>> entries, i.e. even if you reorder them you will end up with some very<br>
>> long LocValue offsets. I'm thinking of common functions, such as<br>
>> list-append, which are defined as one of the first functions in the<br>
>> basis library, but are used through out most applications.<br>
>><br>
>> (I note that the clos_call optimisation reduces the number of LocValue<br>
>> instances with long offsets.)<br>
>><br>
>> I think there are essentially two options:<br>
>><br>
>>  a) make LocValue allow for larger offsets on ARM (and any other arch<br>
>>     necessary)<br>
>><br>
>>  b) populate and use a new lookup table for location values -- I note<br>
>>     that the population of the lookup table would need to be<br>
>>     distributed so that we again avoid referring to locations that are<br>
>>     too far away.<br>
>><br>
>> I would expect (a) to be a bit faster and better, even if the LocValue<br>
>> instruction expands to, say, 4 instructions for larger offsets.<br>
>><br>
>> Cheers,<br>
>> Magnus<br>
>><br>
>><br>
>><br>
>> On 7 July 2017 at 06:24, Yong Kiam <<a href="mailto:tanyongkiam@gmail.com">tanyongkiam@gmail.com</a>> wrote:<br>
>> > Hi Anthony,<br>
>> ><br>
>> > Ramana and I have been looking at running the arm6 compiler in the<br>
>> > logic,<br>
>> > but we are running into the loc_offset limit in the asm_ok check when<br>
>> > the<br>
>> > basis is included. The list of instructions failing asm_ok is attached.<br>
>> ><br>
>> > I investigated a bit further, and these LocValues are coming from the<br>
>> > body<br>
>> > of the main stub, and I guess they're pointers for Fn and Letrec (so,<br>
>> > for<br>
>> > every function decl).<br>
>> ><br>
>> > Is it possible to extend the range of loc_offset?<br>
>> ><br>
>> > @Magnus, two other suggestions we have are:<br>
>> ><br>
>> > 1) Move the main expression splitting up from bvl_to_bvi into closLang<br>
>> > so<br>
>> > that the entries are forced to be closer to each other e.g.<br>
>> ><br>
>> > Code Table 0:<br>
>> >   let fun f = ...<br>
>> >   let fun g = ...<br>
>> >   let fun h = ...<br>
>> ><br>
>> > becomes<br>
>> ><br>
>> > Code Table 0:<br>
>> >   let fun f = ...<br>
>> >   let fun g = ...<br>
>> >   Call 1<br>
>> ><br>
>> > Code Table 1:<br>
>> >   let fun h = ...<br>
>> ><br>
>> > Then clos_to_bvl should generate entries for 0,f,g,1,h in that order so<br>
>> > that<br>
>> > f,g are now closer to 0, which will contain Labels for them. Ramana and<br>
>> > I<br>
>> > prefer doing it this way, because we can still see Letrecs at closLang.<br>
>> ><br>
>> > 2) The alternative is to keep the splitting where it is, and introduce a<br>
>> > new<br>
>> > pass that re-orders code table entries after it. So the above example<br>
>> > would<br>
>> > initially be:<br>
>> ><br>
>> > Code Table 0<br>
>> > let fun f = ... Label f'<br>
>> > let fun g = ... Label g'<br>
>> > let fun h = ... Label h'<br>
>> ><br>
>> > Code Table f'<br>
>> > Code Table g'<br>
>> > Code Table h'<br>
>> ><br>
>> > Then splitting might make it:<br>
>> > Code Table 0<br>
>> > let fun f = ... Label f'<br>
>> > let fun g = ... Label g'<br>
>> ><br>
>> > Code Table 1<br>
>> > let fun h = ... Label h'<br>
>> ><br>
>> > Code Table f'<br>
>> > Code Table g'<br>
>> > Code Table h'<br>
>> ><br>
>> > Then the new pass would heuristically (?) reorder the entries to force<br>
>> > Labels to be closer:<br>
>> ><br>
>> > Code Table 0<br>
>> > let fun f = ... Label f'<br>
>> > let fun g = ... Label g'<br>
>> > Code Table f'<br>
>> > Code Table g'<br>
>> ><br>
>> > Code Table 1<br>
>> > let fun h = ... Label h'<br>
>> > Code Table h'<br>
>> ><br>
>> > The disadvantage to this approach, I think, is that we can't really<br>
>> > control<br>
>> > the splits properly, e.g. what happens if a Letrec gets compiled to a<br>
>> > split<br>
>> > across two code table entries?<br>
>> ><br>
>> > In any case, I am going to try and manually do 2) now to see if it<br>
>> > actually<br>
>> > helps.<br>
>> ><br>
><br>
><br>
</div></div></blockquote></div><br></div>