hipe.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 1,594 行 · 第 1/4 页

ERL
1,594
字号
option_text(pp_rtl_ssapre) ->  "Display the intermediate HiPE-RTL A-SSAPRE sets";option_text(pp_native) ->  "Display the generated (back-end specific) native code";option_text(regalloc) ->  "Select register allocation algorithm. Used as {regalloc, METHOD}.\n" ++  "  Currently available methods:\n" ++  "    naive - spills everything (for debugging and testing)\n" ++  "    linear_scan - fast; not so good if few registers available\n" ++  "    graph_color - slow, but gives OK performance\n" ++  "    coalescing - slower, tries hard to use registers\n" ++  "    optimistic - another variant of a coalescing allocator";option_text(remove_comments) ->  "Strip comments from intermediate code";option_text(rtl_ssa) ->  "Perform SSA conversion on the RTL level -- default starting at O2";option_text(rtl_ssa_const_prop) ->  "Performs sparse conditional constant propagation on RTL SSA";option_text(rtl_lcm) ->  "Perform Lazy Code Motion on RTL";option_text(rtl_ssapre) ->  "Perform A-SSAPRE on RTL";option_text(sparc_peephole) ->  "Perform Sparc peephole optimization";option_text(sparc_prop) ->  "Perform Sparc-level optimization";option_text(time) ->  "Reports the compilation times for the different stages\n" ++  "of the compiler.\n" ++  "    {time, Module}       reports timings for the module Module.\n" ++  "    {time, [M1, M2, M3]} reports timings for the specified modules.\n" ++  "    {time, all}          reports timings all modules.\n" ++  "    time                 reports timings for the main module.\n";option_text(timeout) ->  "Specify compilation time limit in ms. Used as {timeout, LIMIT}.\n" ++  "    The limit must be a non-negative integer or the atom 'infinity'.\n" ++  "    The current default limit is 15 minutes (900000 ms).";option_text(type_warnings) ->  "Turns on warnings from the icode type propagator";option_text(use_indexing) ->  "Use indexing for multiple-choice branch selection.";option_text(use_callgraph) ->  "Compile the functions in a module according to a reversed topological " ++  "sorted order to gain more information when using a persistent lookup " ++  "table for storing intra-modular type information.";option_text(verbose) ->  "Output information about what is being done";option_text(Opt) when is_atom(Opt) ->  "".%% @spec (option()) -> ok%% @doc Prints documentation about a specific option to the standard%% output.help_option(Opt) ->  set_architecture([]), %% needed for target-specific option expansion  case expand_options([Opt]) of    [Opt] ->      Name = if is_atom(Opt) -> Opt;		is_tuple(Opt), size(Opt) =:= 2 -> element(1, Opt)	     end,      case option_text(Name) of	"" ->  	  case lists:member(Name, opt_keys()) of	    true ->	      io:format("~w - Sorry, this option is not documented yet.\n",			[Name]);	    _ -> 	      io:format("Unknown option ~p.\n", [Name])	  end;	Txt ->	  io:fwrite("~w - ~s\n", [Name, Txt])      end;    Opts ->      io:fwrite("This is an alias for: ~p.\n", [Opts])  end,  ok.%% @spec () -> ok%% @doc Prints documentation about debugging options to the standard%% output.help_debug_options() ->  io:format("HiPE compiler debug options:\n" ++	    "  Might require that some modules have been compiled " ++ 	    "with the debug flag.\n" ++	    "    rtl_show_translation - Prints each step in the\n" ++	    "                           translation from Icode to RTL\n",	    []),  ok.%% @spec (Name) -> bool() %% Name = mod() | string()%% @doc Returns true if the module or file contains native HiPE code.has_hipe_code(Atom) when is_atom(Atom) ->  has_hipe_code(atom_to_list(Atom));has_hipe_code(File) ->  case catch     lists:member($H, 		 [ hd(ChunkName) ||		   {ChunkName,_} <- element(3,beam_lib:all_chunks(File))]		) of    {'EXIT',_} ->      exit({bad_beam_file,File});    R -> R  end.%%hipe_timers() ->  [time_ra].%% ____________________________________________________________________%% %% Option expansion%% These are currently in use, but not documented:%%%%     count_instrs:%%     fill_delayslot:%%     {hot, Functions}:%%     icode_type:%%     icode_range:%%     {ls_order, Order}:%%     {regalloc, Algorithm}:%%     remove_comments%%     sparc_estimate_block_time%%     sparc_peephole:%%     sparc_post_schedule%%     sparc_profile:%%     sparc_rename:%%     sparc_schedule%%     timeregalloc:%%     timers%%     use_indexing%% Valid option keys. (Don't list aliases or negations - the check is%% done after the options have been expanded to normal form.)opt_keys() ->    ['O',     bitlevel_binaries,     concurrent_comp,     check_for_inlining,     core,     core_transform,     counters,     count_instrs,     count_spills,     count_temps,     dialyzer,     debug,     fill_delayslot,     frame_x86,     get_called_modules,     hot,     split_arith,     split_arith_unsafe,     icode_inline_bifs,     icode_ssa_check,     icode_ssa_copy_prop,     icode_ssa_const_prop,     icode_ssa_struct_reuse,     icode_type,     icode_range,     icode_multret,     inline_fp,     ls_order,     load,     measure_regalloc,     peephole,     pmatch,     pp_asm,     pp_beam,     pp_icode,     pp_icode_ssa,     pp_icode_split_arith,     pp_opt_icode,     pp_range_icode,     pp_typed_icode,     pp_icode_liveness,     pp_native,     pp_rtl,     pp_rtl_liveness,     pp_rtl_ssa,     pp_rtl_lcm,     pp_rtl_ssapre,     pp_rtl_linear,     regalloc,     remove_comments,     rtl_ssa,     rtl_ssa_const_prop,     rtl_lcm,     rtl_ssapre,     rtl_show_translation,     sparc_estimate_block_time,     sparc_peephole,     sparc_post_schedule,     sparc_profile,     sparc_prop,     sparc_schedule,     sparc_rename,     spillmin_color,     target,     time,     timeout,     timeregalloc,     timers,     to_rtl,     type_warnings,     use_indexing,     use_inline_atom_search,     use_callgraph,     use_clusters,     use_jumptable,     verbose,     %% verbose_spills,     x87].%% Definitions: o1_opts() ->  Common = [inline_fp, pmatch, peephole],  case get(hipe_target_arch) of    ultrasparc ->      [sparc_peephole, fill_delayslot | Common];    powerpc ->      Common;    arm ->      Common -- [inline_fp]; % Pointless optimising for absent hardware    x86 ->      [x87 | Common];        % XXX: Temporary until x86 has sse2    amd64 ->      Common;    Arch ->      ?EXIT({executing_on_an_unsupported_architecture,Arch})  end.o2_opts() ->  Common = [icode_ssa_const_prop, icode_ssa_copy_prop, % icode_ssa_struct_reuse,	    icode_type, icode_inline_bifs,	    rtl_ssa, rtl_ssa_const_prop,	    spillmin_color, use_indexing, remove_comments, 	    concurrent_comp | o1_opts()],  case get(hipe_target_arch) of    ultrasparc ->      [sparc_prop | Common];	% no rtl_lcm here; untagged values over GC...    powerpc ->      [rtl_lcm | Common];    arm ->      [rtl_lcm | Common];    x86 ->      [rtl_lcm | Common];      % [rtl_ssapre | Common];    amd64 ->      [rtl_lcm, icode_range | Common]; % range analysis is effective on 64 bits    Arch ->      ?EXIT({executing_on_an_unsupported_architecture,Arch})  end.o3_opts() ->  Common = [icode_range, {regalloc,coalescing} | o2_opts()],  case get(hipe_target_arch) of    ultrasparc ->      Common;    powerpc ->      Common;    arm ->      Common;    x86 ->      Common;    amd64 ->      Common;    Arch ->      ?EXIT({executing_on_an_unsupported_architecture,Arch})  end.%% Note that in general, the normal form for options should be positive.%% This is a good programming convention, so that tests in the code say%% "if 'x' ..." instead of "if not 'no_x' ...".opt_negations() ->  [{no_bitlevel_binaries, bitlevel_binaries},   {no_core, core},   {no_debug, debug},   {no_fill_delayslot, fill_delayslot},   {no_get_called_modules, get_called_modules},   {no_split_arith, split_arith},   {no_concurrent_comp, concurrent_comp},   {no_icode_inline_bifs, icode_inline_bifs},   {no_icode_range, icode_range},   {no_icode_split_arith, icode_split_arith},   {no_icode_ssa_check, icode_ssa_check},   {no_icode_ssa_copy_prop, icode_ssa_copy_prop},   {no_icode_ssa_const_prop, icode_ssa_const_prop},   {no_icode_ssa_struct_reuse, icode_ssa_struct_reuse},   {no_icode_type, icode_type},   {no_icode_range, icode_range},   {no_inline_fp, inline_fp},   {no_load, load},   {no_peephole, peephole},   {no_pmatch, pmatch},   {no_pp_beam, pp_beam},   {no_pp_icode, pp_icode},   {no_pp_icode_ssa, pp_icode_ssa},   {no_pp_opt_icode, pp_opt_icode},   {no_pp_typed_icode, pp_typed_icode},   {no_pp_rtl, pp_rtl},   {no_pp_native, pp_native},   {no_pp_rtl_lcm, pp_rtl_lcm},   {no_pp_rtl_ssapre, pp_rtl_ssapre},   {no_remove_comments, remove_comments},   {no_rtl_ssa, rtl_ssa},   {no_rtl_ssa_const_prop, rtl_ssa_const_prop},   {no_rtl_lcm, rtl_lcm},   {no_rtl_ssapre, rtl_ssapre},   {no_rtl_show_translation, rtl_show_translation},   {no_sparc_estimate_block_time, sparc_estimate_block_time},   {no_sparc_peephole, sparc_peephole},   {no_sparc_post_schedule, sparc_post_schedule},   {no_sparc_profile, sparc_profile},   {no_sparc_prop, sparc_prop},   {no_sparc_schedule, sparc_schedule},   {no_time, time},   {no_type_warnings, type_warnings},   {no_use_callgraph, use_callgraph},   {no_use_clusters, use_clusters},   {no_use_inline_atom_search, use_inline_atom_search},   {no_use_indexing, use_indexing}].%% Don't use negative forms in right-hand sides of aliases and expansions!%% We only expand negations once, before the other expansions are done.opt_aliases() ->  [{'O0', o0},   {'O1', o1},   {'O2', o2},   {'O3', o3},   {pp_sparc, pp_native},   {pp_x86, pp_native},   {pp_amd64, pp_native},   {pp_ppc, pp_native}].opt_basic_expansions() ->  [{pp_all, [pp_beam, pp_icode, pp_rtl, pp_native]}].opt_pre_expansions() ->  [{o0, [{'O', 0}]},   {o1, [{'O', 1}]},   {o2, [{'O', 2}]},   {o3, [{'O', 3}]}].opt_expansions() ->  [{{'O', 1}, [{'O', 1} | o1_opts()]},   {{'O', 2}, [{'O', 2} | o2_opts()]},   {{'O', 3}, [{'O', 3} | o3_opts()]},   {x87, [x87, inline_fp]},   {inline_fp, case get(hipe_target_arch) of %% XXX: Temporary until x86		 x86 -> [x87, inline_fp];    %%       has sse2		 _ -> [inline_fp] end}].%% This expands "basic" options, which may be tested early and cannot be%% in conflict with options found in the source code.expand_basic_options(Opts) ->  proplists:normalize(Opts, [{negations, opt_negations()},			     {aliases, opt_aliases()},			     {expand, opt_basic_expansions()}]).expand_kt2(Opts) ->   proplists:normalize(Opts, [{expand, [{kt2_type,					[{use_callgraph, fixpoint}, core, 					 {core_transform, cerl_typean}]}]}]).%% Note that set_architecture/1 must be called first, and that the given%% list should contain the total set of options, since things like 'o2'%% are expanded here. Basic expansions are processed here also, since%% this function is called from the help-functions.expand_options(Opts) ->  proplists:normalize(Opts, [{negations, opt_negations()},			     {aliases, opt_aliases()},			     {expand, opt_basic_expansions()},			     {expand, opt_pre_expansions()},			     {expand, opt_expansions()}]).check_options(Opts) ->  Keys = ordsets:from_list(opt_keys()),  Used = ordsets:from_list(proplists:get_keys(Opts)),  case ordsets:subtract(Used, Keys) of    [] ->      ok;    L ->      ?WARNING_MSG("Unknown options: ~p.\n", [L]),      ok  end.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?