Nicolas Cellier uploaded a new version of Compiler to project The Trunk:
http://source.squeak.org/trunk/Compiler-nice.320.mcz ==================== Summary ==================== Name: Compiler-nice.320 Author: nice Time: 3 May 2016, 8:26:42.945884 am UUID: 2c61a7e6-7ce4-4ae9-ab01-21381e4a2e43 Ancestors: Compiler-mt.319 Minor change: avoid generating a pop after the inlined if when both branches return. While at it, avoid invoking super with a different selector. Note: statements following two returning branches are unreachable. Since we avoid the jump over else branch when then branch returns, the Decompiler sees a single then branch and is fooled by the return appearing in middle of statements. We could restore this jump over else when else branch also returns, but we should better generate a Compiler warning and eliminate dead code generation. =============== Diff against Compiler-mt.319 =============== Item was changed: ----- Method: MessageNode>>emitCodeForIf:encoder:value: (in category 'code generation') ----- emitCodeForIf: stack encoder: encoder value: forValue | thenExpr thenSize elseExpr elseSize | thenSize := sizes at: 1. elseSize := sizes at: 2. - (forValue not and: [elseSize * thenSize > 0]) ifTrue: - "Two-armed IFs forEffect share a single pop" - [^super emitCodeForEffect: stack encoder: encoder]. thenExpr := arguments at: 1. elseExpr := arguments at: 2. receiver emitCodeForValue: stack encoder: encoder. + elseSize * thenSize > 0 + ifTrue: "Code for two-armed" - forValue - ifTrue: "Code all forValue as two-armed" [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. thenExpr emitCodeForEvaluatedValue: stack encoder: encoder. stack pop: 1. "then and else alternate; they don't accumulate" + thenExpr returns ifFalse: - thenExpr returns not ifTrue: - "...not ifTrue: avoids using ifFalse: alone during this compile)" "Elide jump over else after a return" [self emitCodeForJump: elseSize encoder: encoder]. + elseExpr emitCodeForEvaluatedValue: stack encoder: encoder. + forValue + ifFalse: + ["Two-armed IFs forEffect share a single pop - except if both return" + (arguments allSatisfy: #returns) ifFalse: [encoder genPop]. + stack pop: 1]] + ifFalse: "One arm is empty here (this can only ever be for effect)" - elseExpr emitCodeForEvaluatedValue: stack encoder: encoder] - ifFalse: "One arm is empty here (two-arms code forValue)" [thenSize > 0 ifTrue: [self emitCodeForBranchOn: false dist: thenSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. thenExpr emitCodeForEvaluatedEffect: stack encoder: encoder] ifFalse: [self emitCodeForBranchOn: true dist: elseSize pop: stack encoder: encoder. pc := encoder methodStreamPosition. elseExpr emitCodeForEvaluatedEffect: stack encoder: encoder]]! Item was changed: ----- Method: MessageNode>>sizeCodeForIf:value: (in category 'code generation') ----- sizeCodeForIf: encoder value: forValue + | thenExpr elseExpr branchSize thenSize elseSize popSize requireTwoArms | - | thenExpr elseExpr branchSize thenSize elseSize | thenExpr := arguments at: 1. elseExpr := arguments at: 2. + popSize := 0. + requireTwoArms := forValue or: [ "Code all forValue as two-armed" + arguments noneSatisfy: [:expr | expr isJust: NodeNil]]. + requireTwoArms + ifTrue: - (forValue - or: [(thenExpr isJust: NodeNil) - or: [elseExpr isJust: NodeNil]]) not - "(...not ifTrue: avoids using ifFalse: alone during this compile)" - ifTrue: "Two-armed IFs forEffect share a single pop" - [^super sizeCodeForEffect: encoder]. - forValue - ifTrue: "Code all forValue as two-armed" [elseSize := elseExpr sizeCodeForEvaluatedValue: encoder. thenSize := (thenExpr sizeCodeForEvaluatedValue: encoder) + (thenExpr returns ifTrue: [0] "Elide jump over else after a return" ifFalse: [self sizeCode: encoder forJump: elseSize]). + branchSize := self sizeCode: encoder forBranchOn: false dist: thenSize. + "Two-armed IFs forEffect share a single pop - except if both branches return" + forValue ifFalse: [(arguments allSatisfy: #returns) ifFalse: [popSize := encoder sizePop]]] - branchSize := self sizeCode: encoder forBranchOn: false dist: thenSize] ifFalse: "One arm is empty here (two-arms code forValue)" [(elseExpr isJust: NodeNil) ifTrue: [elseSize := 0. thenSize := thenExpr sizeCodeForEvaluatedEffect: encoder. branchSize := self sizeCode: encoder forBranchOn: false dist: thenSize] ifFalse: [thenSize := 0. elseSize := elseExpr sizeCodeForEvaluatedEffect: encoder. branchSize := self sizeCode: encoder forBranchOn: true dist: elseSize]]. sizes := Array with: thenSize with: elseSize. ^(receiver sizeCodeForValue: encoder) + + branchSize + thenSize + elseSize + popSize! - + branchSize + thenSize + elseSize! |
Free forum by Nabble | Edit this page |