[squeak-dev] 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
>>>
>>> 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
>>>
>>
>> [ (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 [ loop-body 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 Squeak-dev mailing list