diff options
Diffstat (limited to 'lib/hipe')
-rw-r--r-- | lib/hipe/icode/hipe_beam_to_icode.erl | 61 | ||||
-rw-r--r-- | lib/hipe/main/hipe.erl | 137 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl.erl | 5 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_arch.erl | 27 | ||||
-rw-r--r-- | lib/hipe/rtl/hipe_rtl_lcm.erl | 21 | ||||
-rw-r--r-- | lib/hipe/tools/Makefile | 2 | ||||
-rw-r--r-- | lib/hipe/tools/hipe_ceach.erl | 74 |
7 files changed, 94 insertions, 233 deletions
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl index 45b390acbd..992f387bd5 100644 --- a/lib/hipe/icode/hipe_beam_to_icode.erl +++ b/lib/hipe/icode/hipe_beam_to_icode.erl @@ -31,7 +31,7 @@ -module(hipe_beam_to_icode). --export([module/2, mfa/3]). +-export([module/2]). %%----------------------------------------------------------------------- @@ -111,55 +111,6 @@ trans_beam_function_chunk(FunBeamCode, ClosureInfo) -> {MFA,Icode}. %%----------------------------------------------------------------------- -%% @doc -%% Translates the BEAM code of a single function into Icode. -%% Returns a tuple whose first argument is list of {{M,F,A}, ICode} -%% pairs, where the first entry is that of the given MFA, and the -%% following (in undefined order) are those of the funs that are -%% defined in the function, and recursively, in the funs. The -%% second argument of the tuple is the HiPE compiler options -%% contained in the file. -%% @end -%%----------------------------------------------------------------------- - --spec mfa(list(), mfa(), comp_options()) -> hipe_beam_to_icode_ret(). - -mfa(BeamFuns, {M,F,A} = MFA, Options) - when is_atom(M), is_atom(F), is_integer(A) -> - BeamCode0 = [beam_disasm:function__code(Fn) || Fn <- BeamFuns], - {ModCode, ClosureInfo} = preprocess_code(BeamCode0), - mfa_loop([MFA], [], sets:new(), ModCode, ClosureInfo, Options). - -mfa_loop([{M,F,A} = MFA | MFAs], Acc, Seen, ModCode, ClosureInfo, - Options) when is_atom(M), is_atom(F), is_integer(A) -> - case sets:is_element(MFA, Seen) of - true -> - mfa_loop(MFAs, Acc, Seen, ModCode, ClosureInfo, Options); - false -> - {Icode, FunMFAs} = mfa_get(M, F, A, ModCode, ClosureInfo, Options), - mfa_loop(FunMFAs ++ MFAs, [{MFA, Icode} | Acc], - sets:add_element(MFA, Seen), - ModCode, ClosureInfo, Options) - end; -mfa_loop([], Acc, _, _, _, _) -> - lists:reverse(Acc). - -mfa_get(M, F, A, ModCode, ClosureInfo, Options) -> - BeamCode = get_fun(ModCode, M,F,A), - pp_beam([BeamCode], Options), % cheat by using a list - Icode = trans_mfa_code(M,F,A, BeamCode, ClosureInfo), - FunMFAs = get_fun_mfas(BeamCode), - {Icode, FunMFAs}. - -get_fun_mfas([{patched_make_fun,{M,F,A} = MFA,_,_,_}|BeamCode]) - when is_atom(M), is_atom(F), is_integer(A) -> - [MFA|get_fun_mfas(BeamCode)]; -get_fun_mfas([_|BeamCode]) -> - get_fun_mfas(BeamCode); -get_fun_mfas([]) -> - []. - -%%----------------------------------------------------------------------- %% The main translation function. %%----------------------------------------------------------------------- @@ -1884,16 +1835,6 @@ find_mfa([{func_info,{atom,M},{atom,F},A}|_]) when is_atom(M), is_atom(F), is_integer(A), 0 =< A, A =< 255 -> {M, F, A}. -%%----------------------------------------------------------------------- - -%% Localize a particular function in a module -get_fun([[L, {func_info,{atom,M},{atom,F},A} | Is] | _], M,F,A) -> - [L, {func_info,{atom,M},{atom,F},A} | Is]; -get_fun([[_L1,_L2, {func_info,{atom,M},{atom,F},A} = MFA| _Is] | _], M,F,A) -> - ?WARNING_MSG("Consecutive labels found; please re-create the .beam file~n", []), - [_L1,_L2, MFA | _Is]; -get_fun([_|Rest], M,F,A) -> - get_fun(Rest, M,F,A). %%----------------------------------------------------------------------- %% Takes a list of arguments and returns the constants of them into diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index 570e4d9d17..7694b2fd95 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -47,9 +47,8 @@ %% %% <h3>Using the direct interface - for advanced users only</h3> %% -%% To compile a module or a specific function to native code and -%% automatically load the code into memory, call <a -%% href="#c-1"><code>hipe:c(Module)</code></a> or <a +%% To compile a module to native code and automatically load the code +%% into memory, call <a href="#c-1"><code>hipe:c(Module)</code></a> or <a %% href="#c-2"><code>hipe:c(Module, Options)</code></a>. Note that all %% options are specific to the HiPE compiler. See the <a %% href="#index">function index</a> for other compiler functions. @@ -221,11 +220,10 @@ %%------------------------------------------------------------------- -type mod() :: atom(). --type c_unit() :: mod() | mfa(). -type f_unit() :: mod() | binary(). -type ret_rtl() :: [_]. --type c_ret() :: {'ok', c_unit()} | {'error', term()} | - {'ok', c_unit(), ret_rtl()}. %% The last for debugging only +-type c_ret() :: {'ok', mod()} | {'error', term()} | + {'ok', mod(), ret_rtl()}. %% The last for debugging only -type compile_file() :: atom() | string() | binary(). -type compile_ret() :: {hipe_architecture(), binary()} | list(). @@ -278,47 +276,44 @@ load(Mod, BeamFileName) when is_list(BeamFileName) -> end. %% @spec c(Name) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Reason = term() %% %% @equiv c(Name, []) --spec c(c_unit()) -> c_ret(). +-spec c(mod()) -> c_ret(). c(Name) -> c(Name, []). %% @spec c(Name, options()) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% options() = [option()] %% option() = term() %% Reason = term() %% -%% @type mfa() = {M::mod(),F::fun(),A::arity()}. -%% A fully qualified function name. -%% %% @type fun() = atom(). A function identifier. %% %% @type arity() = integer(). A function arity; always nonnegative. %% %% @doc User-friendly native code compiler interface. Reads BEAM code -%% from the corresponding "Module<code>.beam</code>" file in the system -%% path, and compiles either a single function or the whole module to -%% native code. By default, the compiled code is loaded directly. See -%% above for documentation of options. +%% from the corresponding "Module<code>.beam</code>" file in the +%% system path, and compiles the whole module to native code. By +%% default, the compiled code is loaded directly. See above for +%% documentation of options. %% %% @see c/1 %% @see c/3 %% @see f/2 %% @see compile/2 --spec c(c_unit(), comp_options()) -> c_ret(). +-spec c(mod(), comp_options()) -> c_ret(). c(Name, Options) -> c(Name, beam_file(Name), Options). %% @spec c(Name, File, options()) -> {ok, Name} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% File = filename() | binary() %% Reason = term() %% @@ -329,7 +324,6 @@ c(Name, Options) -> %% @see f/2 c(Name, File, Opts) -> - %% No server if only one function is compiled Opts1 = user_compile_opts(Opts), case compile(Name, File, Opts1) of {ok, Res} -> @@ -359,8 +353,7 @@ f(File) -> %% Reason = term() %% %% @doc Like <code>c/3</code>, but takes the module name from the -%% specified <code>File</code>. This always compiles the whole module; -%% there is no possibility to compile just a single function. +%% specified <code>File</code>. %% %% @see c/3 @@ -381,26 +374,26 @@ user_compile_opts(Opts) -> %% @spec compile(Name) -> {ok, {Target,Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Binary = binary() %% Reason = term() %% %% @equiv compile(Name, []) --spec compile(c_unit()) -> {'ok', compile_ret()} | {'error', term()}. +-spec compile(mod()) -> {'ok', compile_ret()} | {'error', term()}. compile(Name) -> compile(Name, []). %% @spec compile(Name, options()) -> {ok, {Target,Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% Binary = binary() %% Reason = term() %% -%% @doc Direct compiler interface, for advanced use. This just compiles -%% the named function or module, reading BEAM code from the -%% corresponding "Module<code>.beam</code>" file in the system path. -%% Returns <code>{ok, Binary}</code> if successful, or <code>{error, +%% @doc Direct compiler interface, for advanced use. This just +%% compiles the module, reading BEAM code from the corresponding +%% "Module<code>.beam</code>" file in the system path. Returns +%% <code>{ok, Binary}</code> if successful, or <code>{error, %% Reason}</code> otherwise. By default, it does <em>not</em> load the %% binary to memory (the <code>load</code> option can be used to %% activate automatic loading). <code>File</code> can be either a file @@ -412,15 +405,13 @@ compile(Name) -> %% @see file/2 %% @see load/2 --spec compile(c_unit(), comp_options()) -> {'ok', compile_ret()} | {'error', _}. +-spec compile(mod(), comp_options()) -> {'ok', compile_ret()} | {'error', _}. compile(Name, Options) -> compile(Name, beam_file(Name), Options). --spec beam_file(mod() | mfa()) -> string(). +-spec beam_file(mod()) -> string(). -beam_file({M,F,A}) when is_atom(M), is_atom(F), is_integer(A), A >= 0 -> - beam_file(M); beam_file(Module) when is_atom(Module) -> case code:which(Module) of non_existing -> @@ -432,7 +423,7 @@ beam_file(Module) when is_atom(Module) -> %% @spec compile(Name, File, options()) -> %% {ok, {Target, Binary}} | {error, Reason} -%% Name = mod() | mfa() +%% Name = mod() %% File = filename() | binary() %% Binary = binary() %% Reason = term() @@ -442,18 +433,11 @@ beam_file(Module) when is_atom(Module) -> %% %% @see compile/2 --spec compile(c_unit(), compile_file(), comp_options()) -> +-spec compile(mod(), compile_file(), comp_options()) -> {'ok', compile_ret()} | {'error', term()}. -compile(Name, File, Opts0) -> - Opts1 = expand_kt2(Opts0), - Opts = - case Name of - {_Mod, _Fun, _Arity} -> - [no_concurrent_comp|Opts1]; - _ -> - Opts1 - end, +compile(Name, File, Opts0) when is_atom(Name) -> + Opts = expand_kt2(Opts0), case proplists:get_value(core, Opts) of true when is_binary(File) -> ?error_msg("Cannot get Core Erlang code from BEAM binary.",[]), @@ -486,23 +470,11 @@ compile(Name, File, Opts0) -> ?EXIT({cant_compile_source_code, Error}) end; Other when Other =:= false; Other =:= undefined -> - NewOpts = - case proplists:get_value(use_callgraph, Opts) of - No when No =:= false; No =:= undefined -> Opts; - _ -> - case Name of - {_M,_F,_A} -> - %% There is no point in using the callgraph or concurrent_comp - %% when analyzing just one function. - [no_use_callgraph, no_concurrent_comp|Opts]; - _ -> Opts - end - end, DisasmFun = fun (_) -> disasm(File) end, IcodeFun = fun (Code, Opts_) -> get_beam_icode(Name, Code, File, Opts_) end, - run_compiler(Name, DisasmFun, IcodeFun, NewOpts) + run_compiler(Name, DisasmFun, IcodeFun, Opts) end. -spec compile_core(mod(), cerl:c_module(), compile_file(), comp_options()) -> @@ -602,9 +574,13 @@ file(File, Options) when is_atom(File) -> disasm(File) -> case beam_disasm:file(File) of #beam_file{labeled_exports = LabeledExports, - compile_info = CompInfo, + compile_info = CompInfo0, code = BeamCode} -> - {options, CompOpts} = lists:keyfind(options, 1, CompInfo), + CompInfo = case CompInfo0 of + none -> []; + _ -> CompInfo0 + end, + CompOpts = proplists:get_value(options, CompInfo, []), HCompOpts = case lists:keyfind(hipe, 1, CompOpts) of {hipe, L} when is_list(L) -> L; {hipe, X} -> [X]; @@ -625,11 +601,6 @@ fix_beam_exports([{F,A,_}|BeamExports], Exports) -> fix_beam_exports([], Exports) -> Exports. -get_beam_icode({M,_F,_A} = MFA, {BeamCode, Exports}, _File, Options) -> - ?option_time({ok, Icode} = - (catch {ok, hipe_beam_to_icode:mfa(BeamCode, MFA, Options)}), - "BEAM-to-Icode", Options), - {{M, Exports, Icode}, false}; get_beam_icode(Mod, {BeamCode, Exports}, File, Options) -> ?option_time({ok, Icode} = (catch {ok, hipe_beam_to_icode:module(BeamCode, Options)}), @@ -899,7 +870,8 @@ maybe_load(Mod, Bin, WholeModule, Opts) -> do_load(Mod, Bin, WholeModule) end. -do_load(Mod, Bin, WholeModule) -> +do_load(Mod, Bin, BeamBinOrPath) when is_binary(BeamBinOrPath); + is_list(BeamBinOrPath) -> HostArch = get(hipe_host_arch), TargetArch = get(hipe_target_arch), %% Make sure we can do the load. @@ -907,29 +879,22 @@ do_load(Mod, Bin, WholeModule) -> ?EXIT({host_and_target_arch_differ, HostArch, TargetArch}); true -> ok end, - case WholeModule of + case code:is_sticky(Mod) of + true -> + %% We unpack and repack the Beam binary as a workaround to + %% ensure that it is not compressed. + {ok, _, Chunks} = beam_lib:all_chunks(BeamBinOrPath), + {ok, Beam} = beam_lib:build_module(Chunks), + %% Don't purge or register sticky mods; just load native. + code:load_native_sticky(Mod, Bin, Beam); false -> - %% In this case, the emulated code for the module must be loaded. - {module, Mod} = code:ensure_loaded(Mod), - code:load_native_partial(Mod, Bin); - BeamBinOrPath when is_binary(BeamBinOrPath) orelse is_list(BeamBinOrPath) -> - case code:is_sticky(Mod) of - true -> - %% We unpack and repack the Beam binary as a workaround to - %% ensure that it is not compressed. - {ok, _, Chunks} = beam_lib:all_chunks(WholeModule), - {ok, Beam} = beam_lib:build_module(Chunks), - %% Don't purge or register sticky mods; just load native. - code:load_native_sticky(Mod, Bin, Beam); - false -> - %% Normal loading of a whole module - Architecture = erlang:system_info(hipe_architecture), - ChunkName = hipe_unified_loader:chunk_name(Architecture), - {ok, _, Chunks0} = beam_lib:all_chunks(WholeModule), - Chunks = [{ChunkName, Bin}|lists:keydelete(ChunkName, 1, Chunks0)], - {ok, BeamPlusNative} = beam_lib:build_module(Chunks), - code:load_binary(Mod, code:which(Mod), BeamPlusNative) - end + %% Normal loading of a whole module + Architecture = erlang:system_info(hipe_architecture), + ChunkName = hipe_unified_loader:chunk_name(Architecture), + {ok, _, Chunks0} = beam_lib:all_chunks(BeamBinOrPath), + Chunks = [{ChunkName, Bin}|lists:keydelete(ChunkName, 1, Chunks0)], + {ok, BeamPlusNative} = beam_lib:build_module(Chunks), + code:load_binary(Mod, code:which(Mod), BeamPlusNative) end. assemble(CompiledCode, Closures, Exports, Options) -> diff --git a/lib/hipe/rtl/hipe_rtl.erl b/lib/hipe/rtl/hipe_rtl.erl index 29e9c8c8fe..4bf4eb6bd7 100644 --- a/lib/hipe/rtl/hipe_rtl.erl +++ b/lib/hipe/rtl/hipe_rtl.erl @@ -781,8 +781,11 @@ fstore_src_update(F, NewSrc) -> F#fstore{src=NewSrc}. %% fp %% + mk_fp(Dst, Src1, Op, Src2) -> - #fp{dst=Dst, src1=Src1, op=Op, src2=Src2}. + [#fp{dst=Dst, src1=Src1, op=Op, src2=Src2} + | hipe_rtl_arch:mk_fp_check_result(Dst)]. + fp_dst(#fp{dst=Dst}) -> Dst. fp_dst_update(Fp, NewDst) -> Fp#fp{dst=NewDst}. fp_src1(#fp{src1=Src1}) -> Src1. diff --git a/lib/hipe/rtl/hipe_rtl_arch.erl b/lib/hipe/rtl/hipe_rtl_arch.erl index 22cda57a3a..99eb80f3d1 100644 --- a/lib/hipe/rtl/hipe_rtl_arch.erl +++ b/lib/hipe/rtl/hipe_rtl_arch.erl @@ -65,7 +65,8 @@ %% alignment/0, nr_of_return_regs/0, log2_word_size/0, - word_size/0 + word_size/0, + mk_fp_check_result/1 ]). -include("hipe_literals.hrl"). @@ -558,6 +559,12 @@ eval_cond_bits(Cond, N, Z, V, C) -> %%---------------------------------------------------------------------- fwait() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> fwait_real() + end. + +fwait_real() -> case get(hipe_target_arch) of x86 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; amd64 -> [hipe_rtl:mk_call([], 'fwait', [], [], [], not_remote)]; @@ -573,6 +580,12 @@ fwait() -> %% Returns RTL code to restore the FPU after a floating-point exception. %% @end handle_fp_exception() -> + case ?ERTS_NO_FPE_SIGNALS of + 1 -> []; + 0 -> handle_real_fp_exception() + end. + +handle_real_fp_exception() -> case get(hipe_target_arch) of x86 -> ContLbl = hipe_rtl:mk_new_label(), @@ -655,3 +668,15 @@ nr_of_return_regs() -> 1 %% hipe_amd64_registers:nr_rets(); end. + + +mk_fp_check_result(Result) -> + case ?ERTS_NO_FPE_SIGNALS of + 0 -> + []; + 1 -> + [hipe_rtl:mk_fstore(proc_pointer(), + hipe_rtl:mk_imm(?P_FLOAT_RESULT), + Result), + hipe_rtl:mk_call([], emulate_fpe, [], [], [], not_remote)] + end. diff --git a/lib/hipe/rtl/hipe_rtl_lcm.erl b/lib/hipe/rtl/hipe_rtl_lcm.erl index 9224623c8b..262aedb409 100644 --- a/lib/hipe/rtl/hipe_rtl_lcm.erl +++ b/lib/hipe/rtl/hipe_rtl_lcm.erl @@ -486,7 +486,7 @@ lcm_precalc(CFG, Options) -> ?option_time(NodeInfo2 = calc_down_exp(CFG, ExprMap, NodeInfo1, Labels), "RTL LCM calc_down_exp", Options), ?option_time(NodeInfo3 = calc_killed_expr(CFG, NodeInfo2, UseMap, AllExpr, - Labels), + IdMap, Labels), "RTL LCM calc_killed_exp", Options), ?option_time(NodeInfo4 = calc_avail(CFG, NodeInfo3), "RTL LCM calc_avail", Options), @@ -815,19 +815,19 @@ exp_kill_expr(Instr, [CheckedExpr|Exprs]) -> %%============================================================================= %% Calculates the killed expression sets for all given labels. -calc_killed_expr(_, NodeInfo, _, _, []) -> +calc_killed_expr(_, NodeInfo, _, _, _, []) -> NodeInfo; -calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, [Label|Labels]) -> +calc_killed_expr(CFG, NodeInfo, UseMap, AllExpr, IdMap, [Label|Labels]) -> Code = hipe_bb:code(hipe_rtl_cfg:bb(CFG, Label)), - KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, ?SETS:new()), + KilledExprs = calc_killed_expr_bb(Code, UseMap, AllExpr, IdMap, ?SETS:new()), NewNodeInfo = set_killed_expr(NodeInfo, Label, KilledExprs), - calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, Labels). + calc_killed_expr(CFG, NewNodeInfo, UseMap, AllExpr, IdMap, Labels). %%============================================================================= %% Calculates the killed expressions set for one basic block. -calc_killed_expr_bb([], _UseMap, _AllExpr, KilledExprs) -> +calc_killed_expr_bb([], _UseMap, _AllExpr, _IdMap, KilledExprs) -> KilledExprs; -calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> +calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, IdMap, KilledExprs) -> %% Calls, gctests and stores potentially clobber everything case Instr of #call{} -> AllExpr; @@ -837,7 +837,8 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> %% Kill all float expressions %% FIXME: Make separate function is_fp_expr ?SETS:from_list - (lists:foldl(fun(Expr, Fexprs) -> + (lists:foldl(fun(ExprId, Fexprs) -> + Expr = expr_id_map_get_expr(IdMap, ExprId), [Define|_] = hipe_rtl:defines(Expr), case hipe_rtl:is_fpreg(Define) of true -> @@ -849,10 +850,10 @@ calc_killed_expr_bb([Instr|Instrs], UseMap, AllExpr, KilledExprs) -> _ -> case hipe_rtl:defines(Instr) of [] -> - calc_killed_expr_bb(Instrs, UseMap, AllExpr, KilledExprs); + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, KilledExprs); [Define|_] -> NewKilledExprs = use_map_get_expr_uses(UseMap, Define), - calc_killed_expr_bb(Instrs, UseMap, AllExpr, + calc_killed_expr_bb(Instrs, UseMap, AllExpr, IdMap, ?SETS:union(NewKilledExprs, KilledExprs)) end end. diff --git a/lib/hipe/tools/Makefile b/lib/hipe/tools/Makefile index 0eaa3a7b05..e9745a6767 100644 --- a/lib/hipe/tools/Makefile +++ b/lib/hipe/tools/Makefile @@ -42,7 +42,7 @@ RELSYSDIR = $(RELEASE_PATH)/lib/hipe-$(VSN) # ---------------------------------------------------- # Target Specs # ---------------------------------------------------- -MODULES = hipe_tool hipe_profile hipe_ceach hipe_jit +MODULES = hipe_tool hipe_profile hipe_jit # hipe_timer HRL_FILES= diff --git a/lib/hipe/tools/hipe_ceach.erl b/lib/hipe/tools/hipe_ceach.erl deleted file mode 100644 index b29615e169..0000000000 --- a/lib/hipe/tools/hipe_ceach.erl +++ /dev/null @@ -1,74 +0,0 @@ -%% -*- erlang-indent-level: 2 -*- -%% -%% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2002-2009. All Rights Reserved. -%% -%% The contents of this file are subject to the Erlang Public License, -%% Version 1.1, (the "License"); you may not use this file except in -%% compliance with the License. You should have received a copy of the -%% Erlang Public License along with this software. If not, it can be -%% retrieved online at http://www.erlang.org/. -%% -%% Software distributed under the License is distributed on an "AS IS" -%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See -%% the License for the specific language governing rights and limitations -%% under the License. -%% -%% %CopyrightEnd% -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% Copyright (c) 2001 by Erik Johansson. All Rights Reserved -%% ==================================================================== -%% Module : hipe_ceach -%% Purpose : Compile each function in a module, possibly applying a -%% fun between each compilation. Useful for bug hunting by -%% pinpointing a function that when compiled causes a bug. -%% Notes : -%% History : * 2001-12-11 Erik Johansson ([email protected]): Created. -%% ==================================================================== -%% Exports : -%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --module(hipe_ceach). - --export([c/1, c/2, c/3]). - --include("../main/hipe.hrl"). - -%%--------------------------------------------------------------------- - --spec c(atom()) -> 'ok'. - -c(M) -> - lists:foreach(fun({F,A}) -> comp(M, F, A) end, - M:module_info(functions)). - --spec c(atom(), comp_options()) -> 'ok'. - -c(M, Opts) -> - lists:foreach(fun({F,A}) -> comp(M, F, A, Opts) end, - M:module_info(functions)). - --spec c(atom(), comp_options(), fun(() -> any())) -> 'ok'. - -c(M, Opts, Fn) -> - lists:foreach(fun({F,A}) -> comp(M, F, A, Opts), Fn() end, - M:module_info(functions)). - --spec comp(atom(), atom(), arity()) -> 'ok'. - -comp(M, F, A) -> - io:format("~w:~w/~w... ", [M, F, A]), - MFA = {M, F, A}, - {ok, MFA} = hipe:c(MFA), - io:format("OK\n"). - --spec comp(atom(), atom(), arity(), comp_options()) -> 'ok'. - -comp(M, F, A, Opts) -> - io:format("~w:~w/~w... ", [M, F, A]), - MFA = {M, F, A}, - {ok, MFA} = hipe:c(MFA, Opts), - io:format("OK\n"). |