Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Erlang compiler optimizations

I'm no compiler optimization expert. I'm not even sure what's "reasonable" to expect as far as compilers or optimizations. I'm just curious and asking questions is all.

At any rate, I was coding up some Erlang in a basic form such as this:

% TOY EXAMPLE 1
test(X) ->
    if
        X-1 > 0 ->
            yes;
        X-1 == 0 ->
            maybe;
        true -> no
    end.

Then I then optimized it in order not to do the subtract twice:

% TOY EXAMPLE 2
test(X) ->
    Z = X-1,
    if
        Z > 0 ->
            yes;
        Z == 0 ->
            maybe;
        true -> no
    end.

Then I thought "a waste of time - surely the compiler optimizes the first example into the second anyway." So I decided to check by running compile:file with 'S' option for both. Here is output:

% TOY EXAMPLE 1
{function, test, 1, 15}.
  {label,14}.
    {func_info,{atom,exchange},{atom,test},1}.
  {label,15}.
    {gc_bif,'-',{f,16},1,[{x,0},{integer,1}],{x,1}}.
    {test,is_lt,{f,16},[{integer,0},{x,1}]}.
    {move,{atom,yes},{x,0}}.
    return.
  {label,16}.
    {gc_bif,'-',{f,17},1,[{x,0},{integer,1}],{x,1}}.
    {test,is_eq,{f,17},[{x,1},{integer,0}]}.
    {move,{atom,maybe},{x,0}}.
    return.
  {label,17}.
    {move,{atom,no},{x,0}}.
    return.

% TOY EXAMPLE 2
{function, test, 1, 15}.
  {label,14}.
    {func_info,{atom,exchange},{atom,test},1}.
  {label,15}.
    {gc_bif,'-',{f,0},1,[{x,0},{integer,1}],{x,0}}.
    {test,is_lt,{f,16},[{integer,0},{x,0}]}.
    {move,{atom,yes},{x,0}}.
    return.
  {label,16}.
    {test,is_eq,{f,17},[{x,0},{integer,0}]}.
    {move,{atom,maybe},{x,0}}.
    return.
  {label,17}.
    {move,{atom,no},{x,0}}.
    return.

They aren't the same. If I'm reading this right (maybe I'm not), the optimization isn't performed.

I can see a few possibilities:

  1. The optimization can be performed, I'm just not enabling the optimizations because I'm using the wrong function to compile, or not using the correct flags, etc.

  2. The optimization just isn't performed.

  3. Other.

Which is it?

Note: Please don't get bogged down with talk of "if you use a case statement you can do such-and-such" or "you can avoid this by doing blah-blah." The point is simply to test which optimizations the erlang compiler does or doesn't do, and why or why not.

Thanks.

like image 335
X Z Avatar asked Feb 08 '12 12:02

X Z


People also ask

Does Erlang compile?

Erlang programs must be compiled to object code. The compiler can generate a new file that contains the object code. The current abstract machine, which runs the object code, is called BEAM, therefore the object files get the suffix . beam.

Which function is used to compile an Erlang file?

compile:file(File, Options). File is a file name, and Options is a list of compiler options. Refer to the Reference Manual for a complete list of Options . You can also enter the command c(File) from the Erlang shell.

What type of language is Erlang?

Erlang (/ˈɜːrlæŋ/ UR-lang) is a general-purpose, concurrent, functional programming language, and a garbage-collected runtime system.


1 Answers

You're quite right - the Beam compiler doesn't do any common subexpression elimination. The reason is probably that in the kind of programs that Erlang is typically used for, this would not have any noticeable effect, so nobody has bothered to implement it. (For the rare cases of computationally intensive Erlang code, it's usually easy for the programmer to take care of this, as you did in the second example.)

If you compile to native code, you might get this kind of optimization - the HiPE compiler puts in a greater effort to generate good low level code.

like image 95
RichardC Avatar answered Oct 02 '22 07:10

RichardC