Hi All,<div><br></div><div>    (whitewash alert)  I just had occasion to look at the bytecode generated by the standard compiler for HashedCollection class&gt;&gt;#goodPrimeAtLeast:.  Here&#39;s the source, with the issue in bold:</div>
<div><br></div><div><div>goodPrimeAtLeast: lowerLimit</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot;Answer the next good prime &gt;= lowerlimit.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>If lowerLimit is larger than the largest known good prime,</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>just make it odd.&quot;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| primes low mid high prime |</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>primes := self goodPrimes.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>low := 1.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>high := primes size.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>lowerLimit &gt; (primes at: high) ifTrue: [</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>^lowerLimit bitOr: 1 ].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>[ high - low &lt;= 1 ] whileFalse: [</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>mid := high + low // 2.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>prime := primes at: mid.</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>prime = lowerLimit ifTrue: [ ^prime ].</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span><b>prime &lt; lowerLimit</b></div><div><b><span class="Apple-tab-span" style="white-space:pre">                        </span>ifTrue: [ low := mid ]</b></div><div><b><span class="Apple-tab-span" style="white-space:pre">                        </span>ifFalse: [ high := mid ]</b> ].</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>(primes at: low) &gt;= lowerLimit ifTrue: [ ^primes at: low ].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>^primes at: high</div>
<div><br></div><div>The code for this sequence is</div><div><div><span class="Apple-tab-span" style="white-space:pre">        </span>58 &lt;15&gt; pushTemp: 5</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>59 &lt;10&gt; pushTemp: 0</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>60 &lt;B2&gt; send: &lt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>61 &lt;9B&gt; jumpFalse: 66</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>62 &lt;13&gt; pushTemp: 3</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span><b>63 &lt;81 42&gt; storeIntoTemp: 2</b></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>65 &lt;92&gt; jumpTo: 69</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>66 &lt;13&gt; pushTemp: 3</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span><b>67 &lt;81 44&gt; storeIntoTemp: 4</b></div><div><span class="Apple-tab-span" style="white-space:pre">        </span><b>69 &lt;87&gt; pop</b></div></div><div><br>
</div><div>where-as the following would be better:</div><div><br></div><div><div><span class="Apple-tab-span" style="white-space:pre">        </span>58 &lt;15&gt; pushTemp: 5</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>59 &lt;10&gt; pushTemp: 0</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>60 &lt;B2&gt; send: &lt;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>61 &lt;9B&gt; jumpFalse: 66</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>62 &lt;13&gt; pushTemp: 3</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>63 &lt;82 42&gt; popIntoTemp: 2</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>65 &lt;92&gt; jumpTo: 69</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>66 &lt;13&gt; pushTemp: 3</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>67 &lt;82 44&gt; popIntoTemp: 4</div></div><div><br></div><div>The reason is that the code generator favours using a single pop for both arms of the if:</div>
<div><br></div><div>MessageNode&gt;&gt;sizeCodeForIf: encoder value: forValue</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| thenExpr elseExpr branchSize thenSize elseSize |</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>thenExpr := arguments at: 1.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>elseExpr := arguments at: 2.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(forValue</div><div><span class="Apple-tab-span" style="white-space:pre">        </span> or: [(thenExpr isJust: NodeNil)</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span> or: [elseExpr isJust: NodeNil]]) not</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>&quot;(...not ifTrue: avoids using ifFalse: alone during this compile)&quot;</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span>ifTrue:  <b>&quot;Two-armed IFs forEffect share a single pop&quot;</b></div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>[^super sizeCodeForEffect: encoder].</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>...</div><div><br></div><div>MessageNode&gt;&gt;emitCodeForIf: stack encoder: encoder value: forValue</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| thenExpr thenSize elseExpr elseSize |</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>thenSize := sizes at: 1.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>elseSize := sizes at: 2.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(forValue not and: [elseSize * thenSize &gt; 0]) ifTrue:</div>
<div><span class="Apple-tab-span" style="white-space:pre">                </span><b>&quot;Two-armed IFs forEffect share a single pop&quot;</b></div><div><span class="Apple-tab-span" style="white-space:pre">                </span>[^super emitCodeForEffect: stack encoder: encoder].</div>
<div><br></div><div>It would be nice if this only happened if doing so actually reduced the size of the generated code.</div>-- <br>best,<div>Eliot</div><br>
</div>