[squeakdev] here's a curio for compiler mavens...
Nicolas Cellier
nicolas.cellier.aka.nice at gmail.com
Mon Feb 13 21:23:27 UTC 2012
Le 13 février 2012 22:08, Igor Stasenko <siguctua at gmail.com> a écrit :
> 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.
>
Huh, reserving plenty byte codes for nop or intermixing instructions and text,
whatever you choose might lead you directly to the stake ;)
You invented an old new idea: literate bytecode programming
Nicolas
> just don't put me on fire for suggesting that :)
>
>
> 
> Best regards,
> Igor Stasenko.
>
More information about the Squeakdev
mailing list
