[Pkg] The Trunk: Compiler-eem.231.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue May 15 17:04:27 UTC 2012
Eliot Miranda uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-eem.231.mcz
==================== Summary ====================
Name: Compiler-eem.231
Author: eem
Time: 15 May 2012, 10:04:02.174 am
UUID: d4dbfdb6-fea7-4583-b07a-e1e2fad7f090
Ancestors: Compiler-eem.230
Fix decompilation of inlined to:do: loops whose value is used
(e.g. ^55 to: 57 do: [:i| self]). Avoid using the sugared checkBlock:as:
in the ifnil transformers that also use the unsugared checkBlock:as:maxArgs:
=============== Diff against Compiler-eem.230 ===============
Item was changed:
----- Method: Decompiler>>convertToDoLoop (in category 'private') -----
convertToDoLoop
"If statements contains the pattern
var := startExpr.
[var <= limit] whileTrue: [...statements... var := var + incConst]
then replace this by
startExpr to: limit by: incConst do: [:var | ...statements...]"
| initStmt toDoStmt limitStmt |
+ statements size < 2
+ ifTrue:
+ [(statements size = 1
+ and: [stack notEmpty
+ and: [stack last isAssignmentNode]]) ifFalse:
+ [^self].
+ initStmt := stack last.
+ (toDoStmt := statements last toDoFromWhileWithInit: initStmt) ifNil: [^self].
+ stack removeLast; addLast: toDoStmt.
+ statements removeLast]
+ ifFalse:
+ [initStmt := statements at: statements size-1.
+ (toDoStmt := statements last toDoFromWhileWithInit: initStmt) ifNil: [^self].
+ statements removeLast; removeLast; addLast: toDoStmt].
- statements size < 2 ifTrue: [^ self].
- initStmt := statements at: statements size-1.
- (toDoStmt := statements last toDoFromWhileWithInit: initStmt)
- == nil ifTrue: [^ self].
initStmt variable scope: -1. "Flag arg as block temp"
- statements removeLast; removeLast; addLast: toDoStmt.
"Attempt further conversion of the pattern
limitVar := limitExpr.
startExpr to: limitVar by: incConst do: [:var | ...statements...]
to
startExpr to: limitExpr by: incConst do: [:var | ...statements...]"
statements size < 2 ifTrue: [^ self].
limitStmt := statements at: statements size-1.
((limitStmt isMemberOf: AssignmentNode)
and: [limitStmt variable isTemp
and: [limitStmt variable == toDoStmt arguments first
and: [self blockScopeRefersOnlyOnceToTemp: limitStmt variable fieldOffset]]])
ifFalse: [^ self].
toDoStmt arguments at: 1 put: limitStmt value.
limitStmt variable scope: -2. "Flag limit var so it won't print"
+ statements removeLast; removeLast; addLast: toDoStmt
- statements removeLast; removeLast; addLast: toDoStmt.
!
Item was changed:
----- Method: MessageNode>>transformIfNil: (in category 'macro transformations') -----
transformIfNil: encoder
"vb: Removed the original transformBoolean: which amounds to a test we perform in each of the branches below."
(MacroSelectors at: special) = #ifNotNil: ifTrue:
[(self checkBlock: arguments first as: 'ifNotNil arg' from: encoder maxArgs: 1) ifFalse:
[^false].
"Transform 'ifNotNil: [stuff]' to 'ifNil: [nil] ifNotNil: [stuff]'.
Slightly better code and more consistent with decompilation."
self noteSpecialSelector: #ifNil:ifNotNil:.
selector := SelectorNode new key: (MacroSelectors at: special) code: #macro.
arguments := Array
with: ((BlockNode withJust: NodeNil) noteOptimizedIn: self)
with: (arguments first noteOptimizedIn: self).
(self transform: encoder) ifFalse:
[self error: 'compiler logic error'].
^true].
+ (self checkBlock: arguments first as: 'ifNil arg' from: encoder maxArgs: 0) ifFalse:
- (self checkBlock: arguments first as: 'ifNil arg' from: encoder) ifFalse:
[^false].
arguments first noteOptimizedIn: self.
^true!
Item was changed:
----- Method: MessageNode>>transformIfNilIfNotNil: (in category 'macro transformations') -----
transformIfNilIfNotNil: encoder
"vb: Changed to support one-argument ifNotNil: branch. In the 1-arg case we
transform the receiver to
(var := receiver)
which is further transformed to
(var := receiver) == nil ifTrue: .... ifFalse: ...
This does not allow the block variable to shadow an existing temp, but it's no different
from how to:do: is done."
| ifNotNilArg |
ifNotNilArg := arguments at: 2.
+ ((self checkBlock: (arguments at: 1) as: 'Nil arg' from: encoder maxArgs: 0)
- ((self checkBlock: (arguments at: 1) as: 'Nil arg' from: encoder)
and: [self checkBlock: ifNotNilArg as: 'NotNil arg' from: encoder maxArgs: 1]) ifFalse:
[^false].
ifNotNilArg numberOfArguments = 1 ifTrue:
[receiver := AssignmentNode new
variable: ifNotNilArg firstArgument
value: receiver].
selector := SelectorNode new key: #ifTrue:ifFalse: code: #macro.
receiver := MessageNode new
receiver: receiver
selector: #==
arguments: (Array with: NodeNil)
precedence: 2
from: encoder.
arguments do: [:arg| arg noteOptimizedIn: self].
^true!
Item was changed:
----- Method: MessageNode>>transformIfNotNilIfNil: (in category 'macro transformations') -----
transformIfNotNilIfNil: encoder
"vb: Changed to support one-argument ifNotNil: branch. In the 1-arg case we
transform the receiver to
(var := receiver)
which is further transformed to
(var := receiver) == nil ifTrue: .... ifFalse: ...
This does not allow the block variable to shadow an existing temp, but it's no different
from how to:do: is done."
| ifNotNilArg |
ifNotNilArg := arguments at: 1.
((self checkBlock: ifNotNilArg as: 'NotNil arg' from: encoder maxArgs: 1)
+ and: [self checkBlock: (arguments at: 2) as: 'Nil arg' from: encoder maxArgs: 0]) ifFalse:
- and: [self checkBlock: (arguments at: 2) as: 'Nil arg' from: encoder]) ifFalse:
[^false].
ifNotNilArg numberOfArguments = 1 ifTrue:
[receiver := AssignmentNode new
variable: ifNotNilArg firstArgument
value: receiver].
selector := SelectorNode new key: #ifTrue:ifFalse: code: #macro.
receiver := MessageNode new
receiver: receiver
selector: #==
arguments: (Array with: NodeNil)
precedence: 2
from: encoder.
arguments swap: 1 with: 2.
arguments do: [:arg| arg noteOptimizedIn: self].
^true!
More information about the Packages
mailing list