Hi Nicolai, On Sat, Nov 21, 2015 at 10:40 AM, Nicolai Hess <[email protected]> wrote:
> > > 2015-11-20 9:58 GMT+01:00 Eliot Miranda <[email protected]>: > >> Hi Nicolai, >> >> On Nov 20, 2015, at 12:33 AM, Nicolai Hess <[email protected]> wrote: >> >> Thanks eliot, Clement, >> >> but if the argument for to:do: is not an expression but one of the method >> argument, this >> transformation is not needed. Or still? >> >> >> That's the corollary to what I said. Since method (*) arguments are >> read-only it is safe to use them directly and avoid the transformation. >> One could implement this quickly in the Squeak compiler too :-). How many >> cases have you identified where this matters? Is it very common? >> > > I don't know, but I don't think so. > Recompiling all ~90000 compiled methods, once with opal and once with the > other compiler and comparing > the numbers of tempVars gives a difference of about 400 methods. > Not all 400 differences came from the extra tempvars for the to:do: > transform, and sometimes opal generates code with less temp vars. > Well it's a nice surprise to find out that the Squeak compiler does use a variable directly if it's not assigned to in the block. Thanks to your observation I've simplified the test a little, not scanning for assignments if the variable is a method argument or a block argument and the assignment to block arg preference is not in effect. Anyway, adding extra tempvars for accessing the method arguments seems to > be a bug. > Agreed ;-) (* and with the right preference, block) >> _,,,^..^,,,_ (phone) >> >> >> >> >> >> 2015-11-20 8:31 GMT+01:00 Clément Bera <[email protected]>: >> >>> You can use whileTrue: if it's a problem for you not to evaluate the >>> limit at each iteration of the loop. >>> >> >> I don't need this. I just compared some compiled methods bytecodes after >> the latest fix for the wrong frame size calculation. >> For this, I compared opal compilers result with that of the old compiler. >> And I noticed that some methods compiled with >> opal had some "hidden" temps and couldn't explain way:) >> >> >> >>> >>> If you look at OrderedCollection for example, there are implemented >>> differently in Pharo/VW and Squeak. Pharo and VW use to:do: whereas Squeak >>> uses whileTrue: to iterate over the collection. Hence, if you remove >>> elements from the OrderedCollection while iterating over it, the behavior >>> is different. >>> >>> >>> 2015-11-20 1:34 GMT+01:00 Eliot Miranda <[email protected]>: >>> >>>> Because were to:do: not inlined the expression passed as the to: actual >>>> argument would be evaluated exactly once (bound to the formal argument for >>>> to:) and so assigning to a temporary preserves the semantics in the most >>>> direct way. If the expression has side effects then those side effects >>>> must occur only once. >>>> >>>> Note that were the to: expression merely another variable then the >>>> compiler could only substitute the original variable if it's value could >>>> not change, e.g. in >>>> >>>> exampleToDoArgumentLimitIsExpression >>>> | count sum | >>>> count := 10. >>>> sum := 0. >>>> 1 to: count do: [ :each | sum := sum + each]. >>>> ^sum >>>> >>>> It is ok to use count directly as the limit variable, but in this it is >>>> not: >>>> >>>> exampleToDoArgumentLimitIsExpression >>>> | count sum | >>>> count := 10. >>>> sum := 0. >>>> 1 to: count do: [ :each | sum := sum + each. count := >>>> #somethingElseEntirely]. >>>> ^sum >>>> >>>> _,,,^..^,,,_ (phone) >>>> >>>> > On Nov 19, 2015, at 1:14 PM, Nicolai Hess <[email protected]> >>>> wrote: >>>> > >>>> > What is the purpose of replacing expressions, used as limits in a >>>> > to:do: call with by a new temporary variable? >>>> > >>>> > For example: >>>> > >>>> > OCOpalExamples>>#exampleToDoArgumentLimitIsExpression >>>> > the code is >>>> > >>>> > exampleToDoArgumentLimitIsExpression >>>> > | count sum | >>>> > count := 10. >>>> > sum := 0. >>>> > 1 to: count - 1 do: [ :each | sum := sum + each]. >>>> > ^sum >>>> > >>>> > the decompiled bytecode : >>>> > >>>> > exampleToDoArgumentLimitIsExpression >>>> > | tmp1 tmp2 tmp3 | >>>> > tmp1 := 10. >>>> > tmp2 := 0. >>>> > tmp3 := tmp1 - 1. >>>> > 1 to: tmp3 do: [ :tmp4 | tmp2 := tmp2 + tmp4 ]. >>>> > ^ tmp2 >>>> > >>>> > So, the expression (count - 1) in the to:do: loop is replaced by a new >>>> > temporay (tmp3). >>>> > >>>> > Ok, but why ? >>>> >>>> >>> >> > -- _,,,^..^,,,_ best, Eliot
