<br><br><div class="gmail_quote">On Tue, Sep 7, 2010 at 4:36 PM, <span dir="ltr"><<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>></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'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'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>>transformToDo: (in category 'macro transformations') -----<br>
transformToDo: encoder<br>
" var := rcvr. L1: [var <= arg1] Bfp(L2) [block body. var := var + inc]<br>
Jmp(L1) L2: "<br>
+ | limit increment block initStmt test incStmt limitInit blockVar myRange blockRange limitIsAssignedTo |<br>
- | limit increment block initStmt test incStmt limitInit blockVar myRange blockRange |<br>
"First check for valid arguments"<br>
((arguments last isMemberOf: BlockNode)<br>
and: [arguments last numberOfArguments = 1<br>
and: [arguments last firstArgument isVariableReference "As with debugger remote vars"]]) 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 < 3 ifTrue: "transform to full form"<br>
[selector := SelectorNode new key: #to:by:do: code: #macro].<br>
<br>
"Now generate auxiliary structures"<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: "Need to store limit in a var"<br>
[limit := encoder bindBlockArg: blockVar key, 'LimiT' within: block.<br>
limit scope: -2. "Already done parsing block; flag so it won't print"<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 > 0 ifTrue: [#<=] ifFalse: [#>=])<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>