Uploaded image for project: 'Erlang/OTP'
  1. Erlang/OTP
  2. ERL-1277

receive disappearing from Core Erlang?

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Minor
    • Resolution: Not a Bug
    • Affects Version/s: 23.0
    • Fix Version/s: None
    • Component/s: compiler
    • Labels:
      None

      Description

      To our surprise, yesterday we confirmed that the behavior of the (undocumented) to_core and to_core0 compiler options in 23.x do not produce Core Erlang as we used to know it (and expect it).  In particular, receive seems to have disappeared and is substituted with a bunch of primops whose definition and/or semantics we can only guess – and it's not clear whether one can rely on.

      For example, for the following function:

      test() ->
        receive
          ok -> ok
        end.
      

      the 21.x (and 22.x) compilers produce the following Core Erlang code:

      'test'/0 =
          %% Line 5
          fun () ->
              %% Line 6
              receive
                %% Line 7
                <'ok'> when 'true' ->
                    'ok'
              after 'infinity' ->
                'true'
      

      while the 23.0 compiler produces this monster:

      'test'/0 =
          %% Line 5
          ( fun () ->
                ( letrec
                      'recv$^0'/0 =
                          fun () ->
                              let <_2,_0> =
                                  primop 'recv_peek_message'
                                      ()
                              in  case _2 of
                                    <'true'> when 'true' ->
                                        %% Line 6
                                        case _0 of
                                          %% Line 7
                                          <'ok'> when 'true' ->
                                              do  primop 'remove_message'
                                                      ()
                                                  'ok'
                                          ( <Other> when 'true' ->
                                                do  primop 'recv_next'
                                                        ()
                                                    ( apply 'recv$^0'/0
                                                          ()
                                                      -| ['dialyzer_ignore'] )
                                            -| ['compiler_generated','dialyzer_ignore'] )
                                        end
                                    ( <'false'> when 'true' ->
                                          let <_1> =
                                              primop 'recv_wait_timeout'
                                                  ('infinity')
                                          in  case _1 of
                                                <'true'> when 'true' ->
                                                    do  primop 'timeout'
                                                            ()
                                                        'true'
                                                ( <'false'> when 'true' ->
                                                      ( apply 'recv$^0'/0
                                                            ()
                                                        -| ['dialyzer_ignore'] )
                                                  -| ['dialyzer_ignore'] )
                                              end
                                      -| ['dialyzer_ignore'] )
                                  end
                  in  ( apply 'recv$^0'/0
                            ()
                        -| ['dialyzer_ignore'] )
                  -| ['letrec_goto'] )
            -| [{'function',{'test',0}}] )
      

      Of course, I very much realize the desire to micro-optimize stuff in the Compiler and the benefits that such rewrites can offer, but such changes are really problematic for all Erlang tool builders out there, and for some of the tools that I/my group maintains in particular. More importantly, receive is so fundamental for the language that I would not possibly imagine a Core Erlang without it.

      IMO, the to_core compiler option (or similar) needs to be documented (to our surprise, we found out that it is not!) and its behavior to generate proper Core Erlang needs to be restored.  Afterwards, the BEAM compiler is of course free to do whatever rewrites and/or optimizations it feels like.  But there should be something that generates Core Erlang.

        Attachments

          Activity

            People

            Assignee:
            bjorn Björn Gustavsson
            Reporter:
            kostis kostis
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: