<div dir="ltr">Hi Henrik,<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Dec 7, 2015 at 2:07 AM, Henrik Johansen <span dir="ltr">&lt;<a href="mailto:henrik.s.johansen@veloxit.no" target="_blank">henrik.s.johansen@veloxit.no</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> <br><div style="word-wrap:break-word">Will the permutations/call chains you end up having to change if explicitly splitting the cases<div><br></div><div>someMethod</div><div>someMethodUsingReg:</div><div><br></div><div>genTrampoline:reg:reg</div><div>genTrampoline:const:const:</div><div><br></div><div>be too many?</div><div>At least AFAICT, the cases where consts are actually used in trampoline generation is rather limited, and all have types determined by the caller directly, not somewhere far up the call chain...</div></div></blockquote><div><br></div><div>oh the wheels of my brain turn so slowly and creakily.  One can always use the same hack for constants.  If registers are in the range 0-N and constants need to be in the range 0-M, then constants can be passed by mapping 0-M onto -1 to -(M+1).  So it&#39;s a non-issue.  Doh!</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Cheers,</div><div>Henry</div><div><br><div><blockquote type="cite"><div>On 06 Dec 2015, at 9:02 , Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt; wrote:</div><br><div><div dir="ltr">Hi Clément,<div><br></div><div>    you&#39;re thinking at the higher level of doing good register allocation, and I agree with you that that&#39;s all about basic block size.  In normal Malltalk code there are too many sends for us to be able to allocate lots of registers.  But in Sista code there will be much more opportunity.  But I m thinking about a much smaller issue that will make writing the better register allocation code for Sista easier.  What I&#39;m suggesting is that we replace</div><div><br></div><div><div>CogIA32Compiler class initialize</div><div>    ...</div><div>    EAX := 0.</div><div>    ECX := 2.</div><div>    EDX := 3.</div><div>    EBX := 4.</div><div>    …</div><div><br></div><div>CogRTLOpcodes class&gt;&gt;initialize</div><div>    ...</div><div><div>    TempReg := -1.</div><div>    ClassReg := -2.</div><div>    ReceiverResultReg := -3.</div></div><div><br></div><div>with this:</div><div><br></div><div>CogIA32Compiler class initialise</div><div>    ...</div><div>    TempReg := EAX := 0.</div><div>    ClassReg := ECX := 2.</div><div>    ReceiverResultReg := EDX := 3.</div><div>    EBX := 4.</div><div>    …</div></div><div><br></div><div>So now all the nonsense with converting between the abstract register vales and concrete register values disappears.  [Clément and just talked on Skype].  There are at least two issues.  One is that 0 = nil in C and so anywhere that uses nil to say &quot;no register&quot; won&#39;t work.  But the bigger issue is as you point out the code for generating calls from trampolines where non-negative values are interpreted as constants and negative values as abstract registers.  This will have to change and each parameter will have to become two, one the value and one a flag saying whether the value is a register or a constant.  e.g. this</div><div><br></div><div><div>genTrampolineFor: aRoutine called: aString arg: regOrConst0 arg: regOrConst1</div><div><span style="white-space:pre-wrap">        </span>&quot;Generate a trampoline with two arguments.</div><div><span style="white-space:pre-wrap">        </span> Hack: a negative value indicates an abstract register, a non-negative value indicates a constant.&quot;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #aRoutine type: #&#39;void *&#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #aString type: #&#39;char *&#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>^self</div><div><span style="white-space:pre-wrap">                </span>genTrampolineFor: aRoutine</div><div><span style="white-space:pre-wrap">                </span>called: aString</div><div><span style="white-space:pre-wrap">                </span>numArgs: 2</div><div><span style="white-space:pre-wrap">                </span>arg: regOrConst0</div><div><span style="white-space:pre-wrap">                </span>arg: regOrConst1</div><div><span style="white-space:pre-wrap">                </span>arg: nil</div><div><span style="white-space:pre-wrap">                </span>arg: nil</div><div><span style="white-space:pre-wrap">                </span>saveRegs: false</div><div><span style="white-space:pre-wrap">                </span>pushLinkReg: true</div><div><span style="white-space:pre-wrap">                </span>resultReg: nil</div><div><span style="white-space:pre-wrap">                </span>appendOpcodes: false</div></div><div><br></div><div>needs to change to</div><div><br></div><div><div>genTrampolineFor: aRoutine called: aString reg: reg0 reg: reg1</div><div><span style="white-space:pre-wrap">        </span>&quot;Generate a trampoline with two register arguments.&quot;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #aRoutine type: #&#39;void *&#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>&lt;var: #aString type: #&#39;char *&#39;&gt;</div><div><span style="white-space:pre-wrap">        </span>^self</div><div><span style="white-space:pre-wrap">                </span>genTrampolineFor: aRoutine</div><div><span style="white-space:pre-wrap">                </span>called: aString</div><div><span style="white-space:pre-wrap">                </span>numArgs: 2</div><div><span style="white-space:pre-wrap">                </span>arg: reg0 isReg: true</div><div><span style="white-space:pre-wrap">                </span>arg: reg1 isReg: true</div><div><span style="white-space:pre-wrap">                </span>arg: nil isReg: nil</div><div><span style="white-space:pre-wrap">                </span>arg: nil isReg: nil</div><div><span style="white-space:pre-wrap">                </span>saveRegs: false</div><div><span style="white-space:pre-wrap">                </span>pushLinkReg: true</div><div><span style="white-space:pre-wrap">                </span>resultReg: nil</div><div><span style="white-space:pre-wrap">                </span>appendOpcodes: false</div></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sun, Dec 6, 2015 at 11:26 AM, Clément Bera <span dir="ltr">&lt;<a href="mailto:bera.clement@gmail.com" target="_blank">bera.clement@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hello Eliot,<div><br></div><div>I was thinking a lot about the problem and it is not an easy one.</div><div><br></div><div>I believe it&#39;s fine to let a fixed number of registers with a direct mapping from abstract register to concrete register so they can be used for calling convention (smalltalk sends &amp; trampolines). The registers directly mapped are Arg1Reg Arg0Reg ReceiverResultReg TempReg ClassReg SendNumArgsReg FPReg SPReg, and maybe LinkReg and PCReg.</div><div><br></div><div>I think the main issue is how to use efficiently the extra registers. For that I started to build some fancier register allocation. Typically, you can do:</div><div><br></div><div><font face="monospace, monospace">allocateRegNotConflictingWith: regMask </font></div><div><font face="monospace, monospace">&quot;This answers a free register not conflicting with the mask. If a free reg is available, answers it, else scan the sim stack and find the cheapest register to free, free it, answer it.&quot;<br></font></div><font face="monospace, monospace"><br>allocateRegForStackEntryAt: index notConflictingWith: regMask</font><div><font face="monospace, monospace">&quot;Same think but allocates the register for a simStack entry, index 0 for stack top, if sim stack entry is already in a reg answers the reg.&quot;</font><br><div><br></div><div>The implementation uses this method that should be overriden in subclasses of AbstractInstruction:</div><div><font face="monospace, monospace">availableRegisterOrNilFor: liveRegsMask</font><br></div></div><div><br></div><div>For example, in x64, assuming you have in ExtraRegs a list of registers from R8 to R15, you could have:</div><div><font face="monospace, monospace">availableRegisterOrNilFor: liveRegsMask<br></font></div><div><font face="monospace, monospace">    1 to: NumExtraRegs do: [:i |</font></div><div><font face="monospace, monospace">         (cogit register: (ExtraRegs at: i) isInMask: liveRegsMask) ifFalse:</font></div><div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">                </span>[^ExtraRegs at: i] ]</font></div></div><div><font face="monospace, monospace">    ^ super availableRegisterOrNilFor: liveRegsMask</font></div><div><br></div><div>so the register allocation would look up the extra registers before the named ones when possible.</div><div><br></div><div>The main problem then consists in using much more the register allocation API instead of just picking named registers, as I tried to do with stores (for example in genStorePop:RemoteTemp:At:). This is not possible currently because of the calling convention (smalltalk sends and trampolines) which require specific registers at specific places. I believe the smalltalk sends convention should not be changed. However, trampolines that are rarely called but frequent on machine code could be rewritten to pass arguments on stack instead of by registers to be able to use much more register allocation (mustBeBool, contextInstVar, remember, scheduleScavenge, etc.). Another issue is to be able to save register state register state across branches.</div><div><br></div><div>I am just a bit confused by how to handle correctly VarBaseReg.</div><div><br></div><div>Maybe we could talk on skype Eliot.</div><div><br></div><div><br></div><div><br></div></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">2015-12-06 19:17 GMT+01:00 Eliot Miranda <span dir="ltr">&lt;<a href="mailto:eliot.miranda@gmail.com" target="_blank">eliot.miranda@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi All,<br>
<br>
    when I started the Cogit I made the decision to have the notion of abstract registers (ReceiverResultReg, ClassReg, Arg0Reg et al) separate from concrete registers (EAX et al on x86, etc).  I used negative indices for abstract and non-negative indices for concrete.  But this means the back end has to map from one to the other and with much better register allocation being a priority for Clément and I to deliver in April next year I&#39;m thinking that this was a mistake.  After all, the important things are the names, and the relevant back end can simply initialize the abstract registers with the concrete induces and then the napping could go away.<br>
<br>
The only issue I see is that in some circumstances nil is passed to a method expecting an optional abstract register, but nil maps to 0 in C and so would be confused for e.g. EAX, which has the value 0.  For this I guess we could use -1, named e.g. NoRegister.<br>
<br>
Before doing this I thought I&#39;d ask y&#39;all to think about the implications and see if we think it makes sense collectively.  So over the next few weeks, in working with the code, consider the issue, and I&#39;ll prompt you to state your conclusions then.<br>
<br>
_,,,^..^,,,_ (phone)</blockquote></div><br></div>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div>
</div></blockquote></div><br></div></div><br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><span style="font-size:small;border-collapse:separate"><div>_,,,^..^,,,_<br></div><div>best, Eliot</div></span></div></div></div>
</div></div>