[erlang-questions] Pattern matching of literal small/big/bignum integers and binary search

Björn Gustavsson bjorn@REDACTED
Mon Jun 17 07:45:24 CEST 2019

On Sun, Jun 16, 2019 at 10:28 AM Edmond Begumisa
<ebegumisa@REDACTED> wrote:
> Hello all,
> I have some questions about how pattern matches on integer literals are
> evaluated by the emulator.
> As an example, say I have the following function which expects an integer
> that's a power of 2 and returns corresponding position of the lone "on"
> bit...
>          single_cardinalty_to_pos(2#1) -> 1;
>          single_cardinalty_to_pos(2#10) -> 2;
>          single_cardinalty_to_pos(2#100) -> 3;
>          ...
>          single_cardinalty_to_pos(2#100...0) -> 128.

The easiest way to determine what the loader will do with the code is
to disassemble the loaded code by calling erts_debug:df/1. If your
module is called 'foo', erts_debug:df('foo') will disassemble the
loaded coded for the module into the file foo.dis.

In the case of your example, the loader will split up the select_val
instruction into multiple instructions. There will be a
select_val_bins instruction that will do a binary search of all
integers that fit into one word. If that instruction fails, there will
be one i_is_ne_exact_literal instruction for comparing each of the
bignum values. Here are the three last instructions from your example
(matching 2^126, 2^127, 2^128):

0000000018E150B8: i_is_ne_exact_literal_fxc f(0000000018E15160) x(0)
0000000018E150D0: i_is_ne_exact_literal_fxc f(0000000018E15150) x(0)
0000000018E150E8: i_is_ne_exact_literal_fxc f(0000000018E15140) x(0)
0000000018E15160: move_return_c 126
0000000018E15170: move_return_c 127
0000000018E15180: move_return_c 128


P.S. In OTP 22 documentation, there is internal documentation for the
beam_makeops script and the loader:


Björn Gustavsson, Erlang/OTP, Ericsson AB

More information about the erlang-questions mailing list