<div class="gmail_quote">On 20 June 2012 01:07, Walter Bright <span dir="ltr"><<a href="mailto:newshound2@digitalmars.com" target="_blank">newshound2@digitalmars.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 6/19/2012 1:58 PM, Manu wrote:<br>
<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I find a thorough suite of architecture intrinsics are usually the fastest and<br>
cleanest way to the best possible code, although 'naked' may be handy in this<br>
circumstance too...<br>
</blockquote>
<br></div>
Do a grep for "naked" across the druntime library sources. For example, its use in druntime/src/rt/alloca.d, where it is very much needed, as alloca() is one of those "magic" functions.</blockquote><div>
<br></div><div>I never argued against naked... I agree it's mandatory.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Do a grep for "asm" across the druntime library sources. Can you justify all of that with some other scheme?</blockquote><div><br></div><div>I think almost all the blocks I just browsed through could be easily written with nothing more than the register alias feature I suggested, and perhaps a couple of opcode intrinsics.</div>
<div>And as a bonus, they would also be readable. I can imagine cases where the optimiser would have more freedom too.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Thinking more about the implications of removing the inline asm, what would<br>
REALLY roxors, would be a keyword to insist a variable is represented by a<br>
register, and by extension, to associate it with a specific register:<br>
</blockquote>
<br></div>
This was a failure in C.</blockquote><div><br></div><div>Really? This is the missing link between mandatory asm blocks, and being able to do it in high level code with intrinsics.</div><div>The 'register' keyword was similarly fail as 'inline'.. __forceinline was not fail, it is actually mandatory. I'd argue that __forceregister would be similarly useful in C aswell, but the real power would come from being able to specify the particular register to alias.</div>
<div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This would almost entirely eliminate the usefulness of an inline assembler.<br>
Better yet, this could use the 'new' attribute syntax, which most agree will<br>
support arguments:<br>
@register(rsp) int x;<br>
</blockquote>
<br></div>
Some C compilers did have such pseudo-register abilities. It was a failure in practice.<br></blockquote><div><br></div><div>Really? I've never seen that. What about it was fail?</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I really don't understand preferring all these rather convoluted enhancements to avoid something simple and straightforward like the inline assembler. The use of IA in the D runtime library, for example, has been quite successful.<br>
</blockquote><div><br></div><div>I agree, IA is useful and has been successful, but it has drawbacks too.</div><div>  * IA ruins optimisation around the IA block</div><div>  * IA doesn't inline well. intrinsics allow much greater opportunity for efficient integration into the calling context</div>
<div>  * most IA functions are small, and prime candidates for inlining (see points 1 and 2)</div><div>  * IA is difficult for the majority of programmers to follow/understand</div><div>  * even to experienced programmers, poorly commented asm takes a lot of time to mentally parse</div>
<div><br></div><div>It's a shame that there are IA constructs that can't be expressed any other way. I don't think it would take much to address that.</div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
For example, consider this bit from druntime/src/rt/lifetime.d:<br></blockquote><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
------------------------------<u></u>------------------------------<u></u>-------<br>
    auto isshared = ti.classinfo is TypeInfo_Shared.classinfo;<br>
    auto bic = !isshared ? __getBlkInfo((*p).ptr) : null;<br>
    auto info = bic ? *bic : gc_query((*p).ptr);<br>
    auto size = ti.next.tsize();<br>
    version (D_InlineAsm_X86)<br>
    {<br>
        size_t reqsize = void;<br>
<br>
        asm<br>
        {<br>
            mov EAX, newcapacity;<br>
            mul EAX, size;<br>
            mov reqsize, EAX;<br>
            jc  Loverflow;<br>
        }<br>
    }<br>
    else<br>
    {<br>
        size_t reqsize = size * newcapacity;<br>
<br>
        if (newcapacity > 0 && reqsize / newcapacity != size)<br>
            goto Loverflow;<br>
    }<br>
<br>
    // step 2, get the actual "allocated" size.  If the allocated size does not<br>
    // match what we expect, then we will need to reallocate anyways.<br>
<br>
    // TODO: this probably isn't correct for shared arrays<br>
    size_t curallocsize = void;<br>
    size_t curcapacity = void;<br>
    size_t offset = void;<br>
    size_t arraypad = void;<br>
------------------------------<u></u>----------------<br>
</blockquote></div><br><div>This one seems trivial, you just need one intrinsic:</div><div><br></div><div>  size_t reqsize = size * newcapacity;</div><div><div>  __jc(&Loverflow);</div><div><br></div><div>Although it depends on a '&codeLabel' mechanism to get the label address (GCC supports this in C, I'd love to see this in D too).</div>
</div>