Skip to content

Instantly share code, notes, and snippets.

@hansihe
Created February 9, 2021 11:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hansihe/29f710143e010140457a5834b5613aa8 to your computer and use it in GitHub Desktop.
Save hansihe/29f710143e010140457a5834b5613aa8 to your computer and use it in GitHub Desktop.
SSA Compile
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index b8921573d4..f2efe725a0 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -29,7 +29,7 @@
-export([env_compiler_options/0]).
%% Erlc interface.
--export([compile/3,compile_asm/3,compile_core/3,compile_abstr/3]).
+-export([compile/3,compile_asm/3,compile_core/3,compile_abstr/3,compile_ssaetf/3]).
%% Utility functions for compiler passes.
-export([run_sub_passes/2]).
@@ -39,6 +39,7 @@
-include("erl_compile.hrl").
-include("core_parse.hrl").
+-include("beam_ssa.hrl").
-import(lists, [member/2,reverse/1,reverse/2,keyfind/3,last/1,
map/2,flatmap/2,flatten/1,foreach/2,foldr/3,any/2]).
@@ -610,6 +611,8 @@ pass(from_core) ->
{".core",[?pass(parse_core)|core_passes(non_verified_core)]};
pass(from_asm) ->
{".S",[?pass(beam_consult_asm)|asm_passes()]};
+pass(from_ssaetf) ->
+ {".ssaetf", [?pass(parse_ssaetf)|ssa_passes()]};
pass(_) -> none.
%% For compilation from forms, replace the first pass with a pass
@@ -622,6 +625,8 @@ fix_first_pass([{parse_core,_}|Passes]) ->
[?pass(get_module_name_from_core)|Passes];
fix_first_pass([{beam_consult_asm,_}|Passes]) ->
[?pass(get_module_name_from_asm)|Passes];
+fix_first_pass([{parse_ssaetf, _}|Passes]) ->
+ [?pass(get_module_name_from_ssaetf)|Passes];
fix_first_pass([_|Passes]) ->
%% When compiling from abstract code, the module name
%% will be set after running the v3_core pass.
@@ -857,7 +862,12 @@ kernel_passes() ->
?pass(v3_kernel),
{iff,dkern,{listing,"kernel"}},
{iff,'to_kernel',{done,"kernel"}},
- {pass,beam_kernel_to_ssa},
+ {pass,beam_kernel_to_ssa}
+ | ssa_passes()].
+
+ssa_passes() ->
+ [{iff,'to_ssaetf',?pass(write_ssaetf)},
+ {iff,'to_ssaetf',done},
{iff,dssa,{listing,"ssa"}},
{iff,ssalint,{pass,beam_ssa_lint}},
{delay,
@@ -1096,6 +1106,32 @@ get_module_name_from_core(Core, St) ->
{ok,Core,St}
end.
+parse_ssaetf(_Code, St) ->
+ case file:read_file(St#compile.ifile) of
+ {ok,Bin} ->
+ Mod = erlang:binary_to_term(Bin),
+ Name = Mod#b_module.name,
+ {ok,Mod,St#compile{module=Name}};
+ {error,E} ->
+ Es = [{St#compile.ifile,[E]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
+ end.
+
+get_module_name_from_ssaetf(Mod, St) ->
+ Name = Mod#b_module.name,
+ {ok,Mod,St#compile{module=Name}}.
+
+write_ssaetf(Ssa, St) ->
+ Outfile = outfile(St#compile.base, "ssaetf", St#compile.options),
+ Bin = erlang:term_to_binary(Ssa),
+ case file:write_file(Outfile, Bin) of
+ ok ->
+ {ok,Ssa,St};
+ {error,E} ->
+ Es = [{Outfile,[E]}],
+ {error,St#compile{errors=St#compile.errors ++ Es}}
+ end.
+
compile_options([{attribute,_L,compile,C}|Fs]) when is_list(C) ->
C ++ compile_options(Fs);
compile_options([{attribute,_L,compile,C}|Fs]) ->
@@ -1579,6 +1615,8 @@ keep_compile_option(from_core, _Deterministic) ->
false;
keep_compile_option(from_abstr, _Deterministic) ->
false;
+keep_compile_option(from_ssaetf, _Deterministic) ->
+ false;
%% Parse transform and macros have already been applied.
keep_compile_option({parse_transform, _}, _Deterministic) ->
false;
@@ -2005,6 +2043,15 @@ compile_abstr(File0, _OutFile, Opts) ->
Other -> Other
end.
+-spec compile_ssaetf(file:filename(), _, #options{}) -> 'ok' | 'error'.
+
+compile_ssaetf(File0, _OutFile, Opts) ->
+ File = shorten_filename(File0),
+ case file(File, [from_ssaetf|make_erl_options(Opts)]) of
+ {ok,_Mod} -> ok;
+ Other -> Other
+ end.
+
shorten_filename(Name0) ->
{ok,Cwd} = file:get_cwd(),
case lists:prefix(Cwd, Name0) of
diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl
index f072bcc6eb..2629bbe206 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.erl
@@ -32,6 +32,7 @@ compiler(".erl") -> {compile, compile};
compiler(".S") -> {compile, compile_asm};
compiler(".abstr") -> {compile, compile_abstr};
compiler(".core") -> {compile, compile_core};
+compiler(".ssaetf") -> {compile, compile_ssaetf};
compiler(".mib") -> {snmpc, compile};
compiler(".bin") -> {snmpc, mib_to_hrl};
compiler(".xrl") -> {leex, compile};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment