[squeak-dev] here's a curio for compiler mavens...

Eliot Miranda eliot.miranda at gmail.com
Mon Feb 13 19:58:35 UTC 2012


Hi All,

    (whitewash alert)  I just had occasion to look at the bytecode
generated by the standard compiler for HashedCollection
class>>#goodPrimeAtLeast:.  Here's the source, with the issue in bold:

goodPrimeAtLeast: lowerLimit
"Answer the next good prime >= lowerlimit.
If lowerLimit is larger than the largest known good prime,
just make it odd."
 | primes low mid high prime |
primes := self goodPrimes.
low := 1.
high := primes size.
lowerLimit > (primes at: high) ifTrue: [
^lowerLimit bitOr: 1 ].
[ high - low <= 1 ] whileFalse: [
mid := high + low // 2.
prime := primes at: mid.
prime = lowerLimit ifTrue: [ ^prime ].
*prime < lowerLimit*
* ifTrue: [ low := mid ]*
* ifFalse: [ high := mid ]* ].
(primes at: low) >= lowerLimit ifTrue: [ ^primes at: low ].
^primes at: high

The code for this sequence is
58 <15> pushTemp: 5
59 <10> pushTemp: 0
60 <B2> send: <
61 <9B> jumpFalse: 66
62 <13> pushTemp: 3
*63 <81 42> storeIntoTemp: 2*
65 <92> jumpTo: 69
66 <13> pushTemp: 3
*67 <81 44> storeIntoTemp: 4*
*69 <87> pop*

where-as the following would be better:

58 <15> pushTemp: 5
59 <10> pushTemp: 0
60 <B2> send: <
61 <9B> jumpFalse: 66
62 <13> pushTemp: 3
63 <82 42> popIntoTemp: 2
65 <92> jumpTo: 69
66 <13> pushTemp: 3
67 <82 44> popIntoTemp: 4

The reason is that the code generator favours using a single pop for both
arms of the if:

MessageNode>>sizeCodeForIf: encoder value: forValue
| thenExpr elseExpr branchSize thenSize elseSize |
thenExpr := arguments at: 1.
elseExpr := arguments at: 2.
(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].
...

MessageNode>>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].

It would be nice if this only happened if doing so actually reduced the
size of the generated code.
-- 
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20120213/6168ec55/attachment.htm


More information about the Squeak-dev mailing list