2014-10-22 0:45 GMT+02:00 Eliot Miranda <[email protected]>:

>
>
> On Tue, Oct 21, 2014 at 1:02 PM, Nicolai Hess <[email protected]> wrote:
>
>>
>> The more I tried to change/fix the compiler and checking the failing
>> testcases,
>> the more I learn about it.
>> Finally I think the compiler and testcases are mostly right and my
>> understanding was wrong.
>>
>> My (wrong) assumptions were:
>> - the "numTemps" in the method header is always the number of declared
>> temps, regardless whether they end up in an indirection vector
>>
>
> Ah, no.  It is the sum of the arguments and the local temporaries.  So it
> is the position to set the stack pointer to on activating a method.
>
>
>> - the inlined ifTrue: and the inlined whileTrue: blocks are handled the
>> same way,
>>
>> both assumptions are wrong:
>> A method that starts with
>> foo
>> | a b c|
>>
>> and all temps end up in an indirect vector has only 1 tempvar, the
>> "indirection vector" and even "numTemps" in the method header is 1.
>>
>> ifTrue and whileTrue are handled differently for example in this case
>>
>> |a|
>> a:=1.
>> (...) ifTrue:[
>> ... assign to  "a"
>> ... create a block which uses "a"
>> ]
>>
>> the block only needs a copy of "a", as it is not changed after the
>> creation of the block
>>
>
> Right.
>
>
>>
>> |a|
>> a:=1.
>> [...] whileTrue:[
>> ... assign to  "a"
>> ... create a block which uses "a"
>> ]
>>
>> here we need a indirection vector, because the while-block *can* loop
>> repeatedly and change the value of "a" after
>> an block was created.
>>
>
> Right.  In general the compiler cannot tell whether the whileTrue: will be
> executed 0, 1 or many times.  In cases where it can tell it would take lots
> of machinery to do so and only be able to tell in relatively few cases.  So
> the compiler always assumes the whileTrue: is evaluated more than once, and
> hence that it is possible for a block to be created and a modified in a
> subsequent iteration of the loop.  Hence it must put a in an indirection
> vector.
>
>
>> If this is all correct, there is only one problem in this special case
>> (my example above):
>> If there is no assignment within the loop at all, there is no need to
>> create a indirection vector and
>> all used vars (a b c) can just be copied.
>>
>>
>> Or am I still confused ?!
>>
>
> No you're not.  You get it now :-).  One question is whether you can
> explain it all better than I did on my blog, because people seem to find
> this area of teh system hard and take a while to "get it".
>

@eliot
Your blog contains all the information needed. But if someone don't have
already a deep knowledge of the compiler and VM-internals, it can be a bit
overwhelming.
And I must admit I have overread or skipped some parts, because I thought
they are not important or because I didn't understand :)

And now I found the place in the (old) compiler, where the blocks in
optimized loops are handled. You search for assignments in a loop
and if one is found, restart the "analyseClosure" as if the write had
happened after the close over.

Now I need to find a way to do the same with opal compiler. It is (and
looks a lot) different than the old compiler.
It tags the variables with a usage marker #write, #read and an "escaping"
flag. And it does only one pass over the
tree.
But this way, it can not distinguish between a write that happens before
entering the loop from a write happening within
the loop.

@marcus
I propese an extra usage tag #writeInLoop, that is only set on assignments
within a loop.
And then, mark an "escaping" var in an optimized loop only as
"escapingWrite", if it is marked as "writeInLoop".












>
> nicolai
>>
> --
> best,
> Eliot
>

Reply via email to