<div dir="ltr">Hmmmm..... Thank you for pointing that out. I guess my tests should have included non-function calls. ;P<div><br></div><div>Well, I suppose I could get around it by ending each iteration of the loop with a call to erlang:yield(), at least if the loop doesn't contain any calls.</div><div><br></div><div>Does anyone know if anything other than calls and gc instructions can yield?</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 25, 2014 at 1:52 PM, Anthony Ramine <span dir="ltr"><<a href="mailto:n.oxyde@gmail.com" target="_blank">n.oxyde@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Last time I tried manually changing a map/2 function to a "native loop" with simple jumps, I couldn't compile using BEAM optimisation passes because liveness analysis currently cannot cope with a backwards jump (e.g. {label,2}. ... {jump,{f,2}}):<br>
<br>
$ bin/erlc foo.S<br>
Function: map/3<br>
foo.S: internal error in beam_block;<br>
crash reason: {case_clause,<br>
    {'EXIT',<br>
        {function_clause,<br>
            [{gb_trees,get_1,[10,nil],[{file,"gb_trees.erl"},{line,239}]},<br>
             {beam_utils,live_opt,4,[{file,"beam_utils.erl"},{line,687}]},<br>
             {beam_utils,live_opt,1,[{file,"beam_utils.erl"},{line,207}]},<br>
             {beam_block,function,2,[{file,"beam_block.erl"},{line,38}]},<br>
             {lists,mapfoldl,3,[{file,"lists.erl"},{line,1352}]},<br>
             {lists,mapfoldl,3,[{file,"lists.erl"},{line,1353}]},<br>
             {beam_block,module,2,[{file,"beam_block.erl"},{line,29}]},<br>
             {compile,'-select_passes/2-anonymous-2-',2,<br>
                 [{file,"compile.erl"},{line,495}]}]}}}<br>
<br>
  in function  compile:'-select_passes/2-anonymous-2-'/2 (compile.erl, line 495)<br>
  in call from compile:'-internal_comp/4-anonymous-1-'/2 (compile.erl, line 292)<br>
  in call from compile:fold_comp/3 (compile.erl, line 310)<br>
  in call from compile:internal_comp/4 (compile.erl, line 294)<br>
  in call from compile:'-do_compile/2-anonymous-0-'/2 (compile.erl, line 153)<br>
<br>
Without the BEAM optimisations (+no_postopt), compilation succeeds.<br>
<br>
foo.S, for reference:<br>
<br>
        <a href="https://gist.githubusercontent.com/nox/264ca631ef2d8b9d8ce1/raw/1421204b0f360af0f3abc372675d0b85dd455d1b/foo.S" target="_blank">https://gist.githubusercontent.com/nox/264ca631ef2d8b9d8ce1/raw/1421204b0f360af0f3abc372675d0b85dd455d1b/foo.S</a><br>
<br>
For the other points, see what Björn-Egil said. AFAIK only calls and gc-inducing instructions can yield.<br>
<br>
Le 25 sept. 2014 à 21:17, Samuel Barney <<a href="mailto:samjbarney@gmail.com">samjbarney@gmail.com</a>> a écrit :<br>
<div class="HOEnZb"><div class="h5"><br>
> 1. A native loop is a loop that is not emulated via function calls.<br>
> 2. I am planning on generating loops using plain jump instructions.<br>
> 3. It shouldn't hang the VM any since, if I understand correctly, the thread can yield after any instruction is called.<br>
> 4. What do you mean by, 'Did you measure that you actuall need such a thing?'<br>
> 5. I have checked that the erlc compiler can handle it, and still benefit.<br>
><br>
> 6. If I wanted to use HiPE, I would use it. Where's the fun in having HiPE do all my dirty work? I might integrate it into my language later on, but for right now I want pure BEAM.<br>
><br>
> On Thu, Sep 25, 2014 at 3:07 AM, Anthony Ramine <<a href="mailto:n.oxyde@gmail.com">n.oxyde@gmail.com</a>> wrote:<br>
> What do you call native loops? Are you planning to generate BEAM code that loops using plain jump instructions? What do you do in that loop? Can you be sure your process will still yield in a cooperative fashion to not hang the VM? Did you measure that you actually need such a thing? Did you check that you will still be able to feed that assembly to the erlc compiler to benefit from the other usual instructions? In the end couldn't you just use HiPE to take care of these loops?<br>
><br>
> Regards,<br>
><br>
> --<br>
> Anthony Ramine<br>
><br>
> Le 24 sept. 2014 à 23:36, Samuel Barney <<a href="mailto:samjbarney@gmail.com">samjbarney@gmail.com</a>> a écrit :<br>
><br>
>> I did look at targeting Core Erlang first, but it doesn't allow for native loops. I could emulate them with function calls, however, if I move down to the assembly level I can build loops with what is provided there.<br>
>><br>
>> Thank you for the information, I'll do some more searching to see what I can find.<br>
>><br>
>> Respectfully,<br>
>> Samuel Barney<br>
>><br>
>> On Wed, Sep 24, 2014 at 4:40 AM, Anthony Ramine <<a href="mailto:n.oxyde@gmail.com">n.oxyde@gmail.com</a>> wrote:<br>
>> Did you try targeting Core Erlang first? Which primitives do you want to access in BEAM?<br>
>><br>
>> There are 1024 X registers, and Y registers are used for locals in functions, to save them when calling other functions.<br>
>><br>
>> You can find such information by reading the source code or various talk slides made by the OTP team these last years, but I can't help you find the links right now.<br>
>><br>
>> Regards,<br>
>><br>
>> Le 24 sept. 2014 à 04:40, Samuel Barney <<a href="mailto:samjbarney@gmail.com">samjbarney@gmail.com</a>> a écrit :<br>
>><br>
>> > I'm developing a language on top of the Erlang VM, and there are a couple of flow-control constructs that I can't implement without skipping the Erlang AST and using the erlang assembly code.<br>
>> ><br>
>> > Is there a specific amount of X and Y registers? Or is there a way that I can find that out via Erlang?<br>
>> ><br>
>> > Also, what is the purpose of the Y registers?<br>
>> > _______________________________________________<br>
>> > erlang-questions mailing list<br>
>> > <a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
>> > <a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
>><br>
>><br>
><br>
<br>
</div></div></blockquote></div><br></div>