[squeakdev] here's a curio for compiler mavens...
Igor Stasenko
siguctua at gmail.com
Mon Feb 13 21:08:07 UTC 2012
On 13 February 2012 22:38, Nicolas Cellier
<nicolas.cellier.aka.nice at gmail.com> wrote:
> Le 13 février 2012 21:27, Igor Stasenko <siguctua at gmail.com> a écrit :
>> On 13 February 2012 20:58, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>>> 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
>>>
>>> whereas 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
>>>
>>
>> [ (a) ifTrue:[ b] ifFalse: [c] ] value
>> should answer b or c (depending on a)
>> now if you use pop instead of store, it will break.
>>
>
> Yes but we always know whether we want to emit code forValue or just for effect.
>
>> Of course in while loop, the [ loopbody closure ] value is always
>> discarded, so yes we can
>> eliminate extra pop.
>> But you can do even more:
>>
>> 1. loop head
>> ...
>> ....
>> 61 <9B> jumpFalse: 66
>> 62 <13> pushTemp: 3
>> 63 <82 42> popIntoTemp: 2
>> ** 65 <92> jumpTo: 1
>> 66 <13> pushTemp: 3
>> 67 <82 44> popIntoTemp: 4
>> 69 ... jumpTo: 1
>>
>> so, we can have 1 less jump when code enters first branch.
>>
>
> Very good!
> I think however that hacking the Decompiler will be a challenge!
>
Well, in this case it is easy to hide hints for decompiler directly in
a bytecode:
1. loop head
...
100. jumpTo: 106
101. push ...
102. pop
103. jumpTo: 1
104. hint
105. more hints
106. ... section start for false branch
n+1 ...

same actually for loops. instead of writing sophisticated detection
code , we can simply read hints:
1. loop head
...
10. jumpIfFalse: 101 (leaving the loop )
... loop body
99. jumpTo: 1 (loop head)
100. hint for loop
101. ... rest of method's bytecode
As you can see , it doesn't affects the performance, since its
unreachable code, just the size of bytecode.
just don't put me on fire for suggesting that :)

Best regards,
Igor Stasenko.
More information about the Squeakdev
mailing list
