Compilation and how to check the final executable code - beam file (inline, dead code, optimization)

Question 1: Coming from C, what could be the nearest thing to inspect the assembly code generated by -O0 or -O2, for instance, in Elixir/Erlang?

Take a look at erlc options in this script: eplaypen/priv/scripts/compile.sh at master · seriyps/eplaypen · GitHub. You can see that to compile something into one of the IRs you can pass an erlc option. To do this with elixir code, you can use something like

ERL_COMPILER_OPTIONS="dkern" elixir x.ex

For more information about IRs you can refer to: The BEAM Book: Understanding the Erlang Runtime System

Question 2: Does Mix perform any code optimization when doing MIX_ENV=prod mix compile compared with mix compile?

Only optimizations which erlang does + protocol consolidation.

The former builds in _build/prod, while the latter in _build/dev but when decompiling the final beam files I don’t see any differences. Can be a problem regarding my decompilation tools? or the optimizations are not produced at the beam level?

Yeah, they’re basically the same, because all erlang optimizations are lightweight, therefore both dev and prod use full set of optimizations.

Question 3: My purpose is to know if a code like this is inlined by default:

Private functions are inlined in the module when their size is small enough. You can force inlining using @compile {:inline, function: arity} module attribute. As I said, this works only for private functions

Question 4: Can the compiler detect and eliminate dead code?

It can, and it does, but Erlang and Elixir runtime assumes that modules can be recompiled in runtime, therefore it can’t perform on inter-module calls optimizations.