<br><br><div class="gmail_quote">On Tue, Sep 7, 2010 at 4:36 PM,  <span dir="ltr">&lt;<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
Nicolas Cellier uploaded a new version of Compiler to project The Trunk:<br>
<a href="http://source.squeak.org/trunk/Compiler-nice.173.mcz" target="_blank">http://source.squeak.org/trunk/Compiler-nice.173.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: Compiler-nice.173<br>
Author: nice<br>
Time: 8 September 2010, 1:36:04.973 am<br>
UUID: f40f6937-a88a-4f85-b0b0-f68b310a1d92<br>
Ancestors: Compiler-eem.172<br>
<br>
Compiler fix for <a href="http://bugs.squeak.org/view.php?id=7093" target="_blank">http://bugs.squeak.org/view.php?id=7093</a><br>
Avoid optimizing a to:do: loop that does modify its limit inside the loop. Thanks Eliot!<br>
<br>
Note: an alternate solution would be to create a shadow variable, assign it with the limit, and optimize the block.<br></blockquote><div><br></div><div>Right.  I considered this and immediately rejected it on the grounds that, because it uses an extra temp and we&#39;re severely limited on the max number of temps, therefore the shadow variable approach would very likely cause failed compilations.  Since assigning to the loop variable is an edge case anyway I think the approach I&#39;ve taken is the better one.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
Note 2: the bug report also has a so far uncorrected Decompiler part and cannot be closed yet.<br>
<br>
=============== Diff against Compiler-eem.172 ===============<br>
<br>
Item was changed:<br>
  ----- Method: MessageNode&gt;&gt;transformToDo: (in category &#39;macro transformations&#39;) -----<br>
  transformToDo: encoder<br>
        &quot; var := rcvr. L1: [var &lt;= arg1] Bfp(L2) [block body. var := var + inc]<br>
  Jmp(L1) L2: &quot;<br>
+       | limit increment block initStmt test incStmt limitInit blockVar myRange blockRange limitIsAssignedTo |<br>
-       | limit increment block initStmt test incStmt limitInit blockVar myRange blockRange |<br>
        &quot;First check for valid arguments&quot;<br>
        ((arguments last isMemberOf: BlockNode)<br>
          and: [arguments last numberOfArguments = 1<br>
          and: [arguments last firstArgument isVariableReference &quot;As with debugger remote vars&quot;]]) ifFalse:<br>
                [^false].<br>
        arguments size = 3<br>
                ifTrue: [increment := arguments at: 2.<br>
                                (increment isConstantNumber<br>
+                                and: [increment literalValue ~= 0]) ifFalse: [^false]]<br>
-                                and: [increment literalValue ~= 0]) ifFalse: [^ false]]<br>
                ifFalse: [increment := encoder encodeLiteral: 1].<br>
+       (limit := arguments at: 1) isVariableReference ifTrue:<br>
+               [limitIsAssignedTo := false.<br>
+                arguments last nodesDo:<br>
+                       [:node|<br>
+                       (node isAssignmentNode and: [node variable = limit]) ifTrue:<br>
+                               [limitIsAssignedTo := true]].<br>
+                limitIsAssignedTo ifTrue:<br>
+                       [^false]].<br>
        arguments size &lt; 3 ifTrue:   &quot;transform to full form&quot;<br>
                [selector := SelectorNode new key: #to:by:do: code: #macro].<br>
<br>
        &quot;Now generate auxiliary structures&quot;<br>
        myRange := encoder rawSourceRanges at: self ifAbsent: [1 to: 0].<br>
        block := arguments last.<br>
        blockRange := encoder rawSourceRanges at: block ifAbsent: [1 to: 0].<br>
        blockVar := block firstArgument.<br>
        initStmt := AssignmentNode new variable: blockVar value: receiver.<br>
-       limit := arguments at: 1.<br>
        limit isVariableReference | limit isConstantNumber<br>
                ifTrue: [limitInit := nil]<br>
                ifFalse:  &quot;Need to store limit in a var&quot;<br>
                        [limit := encoder bindBlockArg: blockVar key, &#39;LimiT&#39; within: block.<br>
                         limit scope: -2.  &quot;Already done parsing block; flag so it won&#39;t print&quot;<br>
                         block addArgument: limit.<br>
                         limitInit := AssignmentNode new<br>
                                                        variable: limit<br>
                                                        value: arguments first].<br>
        test := MessageNode new<br>
                                receiver: blockVar<br>
                                selector: (increment key &gt; 0 ifTrue: [#&lt;=] ifFalse: [#&gt;=])<br>
                                arguments: (Array with: limit)<br>
                                precedence: precedence from: encoder<br>
                                sourceRange: (myRange first to: blockRange first).<br>
        incStmt := AssignmentNode new<br>
                                variable: blockVar<br>
                                value: (MessageNode new<br>
                                                        receiver: blockVar selector: #+<br>
                                                        arguments: (Array with: increment)<br>
                                                        precedence: precedence from: encoder)<br>
                                from: encoder<br>
                                sourceRange: (myRange last to: myRange last).<br>
        arguments := (Array with: limit with: increment with: block),<br>
                                        (Array with: initStmt with: test with: incStmt with: limitInit).<br>
        block noteOptimizedIn: self.<br>
        ^true!<br>
<br>
<br>
</blockquote></div><br>