[squeak-dev] Re: here's a curio for compiler mavens...
Eliot Miranda
eliot.miranda at gmail.com
Tue Feb 14 00:27:16 UTC 2012
OK, I fixed this (a pleasant Monday afternoon distraction) (at least I
*think* I've fixed it; I still have to check the decompiler). But... in
doing so I realised I had to fix CompiledMethod>>#= since I needed to see
exactly which methods the compiler change affected (just committed as
Kernel-eem.669). In doing this I noticed that recent compiler changes have
not been applied by recompiling affected methods in the system. If you
look at Behavior>>#sourceMatchesBytecodeAt: it uses CompiledMethod>>#= to
check that the compiler's output remains unchanged. In the 4.3 trunk image
with CompiledMethod>>#= fixed, sourceMatchesBytecodeAt: reports that
some 19654 methods need recompiling:
(SystemNavigation new allSelect: [:m| (m methodClass
sourceMatchesBytecodeAt: m selector) not]) size 19654
Being selective in recompiling, via e.g.
SystemNavigation new allSelect: [:m| (m methodClass
sourceMatchesBytecodeAt: m selector) ifFalse: [m methodClass recompile: m
selector]. false]
one gets to the desired
(SystemNavigation new allSelect: [:m| (m methodClass
sourceMatchesBytecodeAt: m selector) not]) size 0
So the question is should we add an update that does the selective
recompile? I think we should, e.g. by committing a version of Compiler
that contains the selective recompile as a post-script. Agreed?
On Mon, Feb 13, 2012 at 11:58 AM, 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
>
> 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
>
>
--
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20120213/864ba971/attachment.htm
More information about the Squeak-dev
mailing list
|