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. Anyway, adding extra tempvars for accessing the method arguments seems to be a bug. > > > (* 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 ? >>> >>> >> >
