Skip to content

Inefficient binary pattern compilation #10493

@michalmuskala

Description

@michalmuskala

Describe the bug
Given the following code:

-module(test).

-export([config_value/1]).

config_value(<<"0">>) ->
    <<"0">>;
config_value(<<"1">>) ->
    <<"1">>;
config_value(Bin) when is_binary(Bin) ->
    Bin.

compiled with erlc +to_asm test.erl we can see the following output:

  {label,2}.
    {'%',{var_info,{x,0},[accepts_match_context]}}.
    {test,bs_start_match3,{f,6},1,[{x,0}],{x,1}}.
    {bs_get_position,{x,1},{x,0},2}.
    {bs_match,{f,5},
              {x,1},
              {commands,[{ensure_at_least,8,1},
                         {integer,2,{literal,[]},8,1,{x,2}}]}}.
    {select_val,{tr,{x,2},{t_integer,{0,255}}},
                {f,5},
                {list,[{integer,48},{f,4},{integer,49},{f,3}]}}.
  {label,3}.
    {bs_match,{f,5},{x,1},{commands,[{ensure_exactly,0}]}}.
    {move,{literal,<<"1">>},{x,0}}.
    return.
  {label,4}.
    {bs_match,{f,5},{x,1},{commands,[{ensure_exactly,0}]}}.
    {move,{literal,<<"0">>},{x,0}}.
    return.
  {label,5}.
    {bs_set_position,{x,1},{x,0}}.
    {bs_get_tail,{x,1},{x,0},2}.
    {test,is_binary,{f,1},[{tr,{x,0},{t_bitstring,1,false}}]}.
    return.
  {label,6}.
    {test,is_binary,{f,1},[{x,0}]}.
    return.

There are multiple inefficiencies in this code:

  1. The bs_match instructions are split. Rather than {ensure_at_least,8,1} and then {ensure_exactly,0} in branch 3 and 4, I would have expected to see {ensure_exactly,8} in the initial match and no bs_match in the 3 and 4 branch at all.
  2. The bs_set_position and bs_get_tail operations in label 5 are entirely redundant - the resulting {x,1} register is not used further down.
  3. Fixing 2. will likely allow the compiler to combine the 6th and 5th label into just one, reducing code size.

Affected versions
Tested on 27.1, 28.0.2, and 28.1.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugIssue is reported as a bugteam:VMAssigned to OTP team VM

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions