Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ERL-452: Unnecessary stack allocation in map matches #3683

Closed
OTP-Maintainer opened this issue Jul 9, 2017 · 2 comments
Closed

ERL-452: Unnecessary stack allocation in map matches #3683

OTP-Maintainer opened this issue Jul 9, 2017 · 2 comments
Assignees
Labels
bug Issue is reported as a bug priority:low team:VM Assigned to OTP team VM
Milestone

Comments

@OTP-Maintainer
Copy link

Original reporter: michalmuskala
Affected version: OTP-20.0
Fixed in version: OTP-21.0
Component: compiler
Migrated from: https://bugs.erlang.org/browse/ERL-452


Given a module like the following:

{code:erlang}
-module(test).

-export([test/1]).

test(Map) ->
    X = case Map of
            #{x := X0} ->
                X0;
            #{} ->
                erlang:error({badkey, Map, x})
        end,
    Y = case Map of
            #{y := Y0} ->
                Y0;
            #{} ->
                erlang:error({badkey, Map, y})
        end,
    {X, Y}.
{code}

The compiler will emit the following code:

{code:asm}
{function, test, 1, 2}.
  {label,1}.
    {line,[{location,"test.erl",5}]}.
    {func_info,{atom,test},{atom,test},1}.
  {label,2}.
    {allocate_zero,2,1}.
    {move,{x,0},{y,1}}.
    {test,is_map,{f,4},[{x,0}]}.
    {get_map_elements,{f,3},{x,0},{list,[{atom,x},{x,1}]}}.
    {move,{x,1},{x,0}}.
    {move,{x,0},{y,0}}.
    {test,is_map,{f,6},[{y,1}]}.
    {get_map_elements,{f,5},{y,1},{list,[{atom,y},{x,1}]}}.
    {move,{x,1},{x,0}}.
    {test_heap,3,1}.
    {put_tuple,2,{x,1}}.
    {put,{y,0}}.
    {put,{x,0}}.
    {move,{x,1},{x,0}}.
    {deallocate,2}.
    return.
  {label,3}.
    {test_heap,4,0}.
    {put_tuple,3,{x,0}}.
    {put,{atom,badkey}}.
    {put,{y,1}}.
    {put,{atom,x}}.
    {line,[{location,"test.erl",10}]}.
    {call_ext,1,{extfunc,erlang,error,1}}.
  {label,4}.
    {line,[{location,"test.erl",6}]}.
    {case_end,{y,1}}.
  {label,5}.
    {test_heap,4,0}.
    {put_tuple,3,{x,0}}.
    {put,{atom,badkey}}.
    {put,{y,1}}.
    {put,{atom,y}}.
    {line,[{location,"test.erl",16}]}.
    {call_ext,1,{extfunc,erlang,error,1}}.
  {label,6}.
    {line,[{location,"test.erl",12}]}.
    {case_end,{y,1}}.
{code}

There are extra move isntructions that could be removed by https://github.com/erlang/otp/pull/1506.

What is more concerning is the extra, seemingly completely unnecessary, stack allocation of 2 slots. The function should be able to be compiled without any allocation.

Similar code is emitted by the Elixir compiler faced with the {{map.key}} syntax.
@OTP-Maintainer
Copy link
Author

raimo said:

This will have to wait to after the summer vacations.

@OTP-Maintainer
Copy link
Author

bjorn said:

https://github.com/erlang/otp/pull/1528

@OTP-Maintainer OTP-Maintainer added bug Issue is reported as a bug team:VM Assigned to OTP team VM priority:low labels Feb 10, 2021
@OTP-Maintainer OTP-Maintainer added this to the OTP-21.0 milestone Feb 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue is reported as a bug priority:low team:VM Assigned to OTP team VM
Projects
None yet
Development

No branches or pull requests

2 participants