diff options
Diffstat (limited to 'lib/hipe/main')
-rw-r--r-- | lib/hipe/main/hipe.app.src | 1 | ||||
-rw-r--r-- | lib/hipe/main/hipe.erl | 55 | ||||
-rw-r--r-- | lib/hipe/main/hipe_main.erl | 14 |
3 files changed, 52 insertions, 18 deletions
diff --git a/lib/hipe/main/hipe.app.src b/lib/hipe/main/hipe.app.src index aa86b6dc5b..f8487151d7 100644 --- a/lib/hipe/main/hipe.app.src +++ b/lib/hipe/main/hipe.app.src @@ -88,6 +88,7 @@ hipe_icode2rtl, hipe_icode_bincomp, hipe_icode_callgraph, + hipe_icode_call_elim, hipe_icode_cfg, hipe_icode_coordinator, hipe_icode_ebb, diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl index 0e32da1d36..981265b3e9 100644 --- a/lib/hipe/main/hipe.erl +++ b/lib/hipe/main/hipe.erl @@ -200,8 +200,9 @@ compile/4, compile_core/4, file/1, - file/2, - llvm_support_available/0, + file/2, + get_llvm_version/0, + llvm_support_available/0, load/1, help/0, help_hiper/0, @@ -1165,6 +1166,9 @@ option_text(caller_save_spill_restore) -> "Activates caller save register spills and restores"; option_text(debug) -> "Outputs internal debugging information during compilation"; +option_text(icode_call_elim) -> + "Performs call elimination of BIFs that are side-effect free\n" ++ + "only on some argument types"; option_text(icode_range) -> "Performs integer range analysis on the Icode level"; option_text(icode_ssa_check) -> @@ -1318,6 +1322,7 @@ opt_keys() -> get_called_modules, split_arith, split_arith_unsafe, + icode_call_elim, icode_inline_bifs, icode_ssa_check, icode_ssa_copy_prop, @@ -1399,7 +1404,7 @@ o1_opts(TargetArch) -> o2_opts(TargetArch) -> Common = [icode_ssa_const_prop, icode_ssa_copy_prop, % icode_ssa_struct_reuse, - icode_type, icode_inline_bifs, rtl_lcm, + icode_type, icode_inline_bifs, icode_call_elim, rtl_lcm, rtl_ssa, rtl_ssa_const_prop, spillmin_color, use_indexing, remove_comments, concurrent_comp, binary_opt | o1_opts(TargetArch)], @@ -1429,6 +1434,7 @@ opt_negations() -> {no_icode_inline_bifs, icode_inline_bifs}, {no_icode_range, icode_range}, {no_icode_split_arith, icode_split_arith}, + {no_icode_call_elim, icode_call_elim}, {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}, @@ -1479,18 +1485,25 @@ opt_expansions(TargetArch) -> [{o1, o1_opts(TargetArch)}, {o2, o2_opts(TargetArch)}, {o3, o3_opts(TargetArch)}, - {to_llvm, llvm_opts(o3)}, - {{to_llvm, o0}, llvm_opts(o0)}, - {{to_llvm, o1}, llvm_opts(o1)}, - {{to_llvm, o2}, llvm_opts(o2)}, - {{to_llvm, o3}, llvm_opts(o3)}, + {to_llvm, llvm_opts(o3, TargetArch)}, + {{to_llvm, o0}, llvm_opts(o0, TargetArch)}, + {{to_llvm, o1}, llvm_opts(o1, TargetArch)}, + {{to_llvm, o2}, llvm_opts(o2, TargetArch)}, + {{to_llvm, o3}, llvm_opts(o3, TargetArch)}, {x87, [x87, inline_fp]}, {inline_fp, case TargetArch of %% XXX: Temporary until x86 has sse2 x86 -> [x87, inline_fp]; _ -> [inline_fp] end}]. -llvm_opts(O) -> - [to_llvm, {llvm_opt, O}, {llvm_llc, O}]. +llvm_opts(O, TargetArch) -> + Base = [to_llvm, {llvm_opt, O}, {llvm_llc, O}], + case TargetArch of + %% A llvm bug present in 3.4 through (at least) 3.8 miscompiles x86 + %% functions that have floats are spilled to stack by clobbering the process + %% pointer (ebp) trying to realign the stack pointer. + x86 -> [no_inline_fp | Base]; + _ -> Base + end. %% This expands "basic" options, which may be tested early and cannot be %% in conflict with options found in the source code. @@ -1520,7 +1533,8 @@ expand_options(Opts, TargetArch) -> proplists:normalize(Opts, [{negations, opt_negations()}, {aliases, opt_aliases()}, {expand, opt_basic_expansions()}, - {expand, opt_expansions(TargetArch)}]). + {expand, opt_expansions(TargetArch)}, + {negations, opt_negations()}]). -spec check_options(comp_options()) -> 'ok'. @@ -1538,18 +1552,27 @@ check_options(Opts) -> -spec llvm_support_available() -> boolean(). llvm_support_available() -> - get_llvm_version() >= 3.4. + get_llvm_version() >= {3,4}. + +-type llvm_version() :: {Major :: integer(), Minor :: integer()}. +-spec get_llvm_version() -> llvm_version() | {0, 0}. get_llvm_version() -> OptStr = os:cmd("opt -version"), SubStr = "LLVM version ", N = length(SubStr), case string:str(OptStr, SubStr) of 0 -> % No opt available - 0.0; + {0, 0}; S -> - case string:to_float(string:sub_string(OptStr, S + N)) of - {error, _} -> 0.0; %XXX: Assumes no revision numbers in versioning - {Float, _} -> Float + case string:tokens(string:sub_string(OptStr, S + N), ".") of + [MajorS, MinorS | _] -> + case {string:to_integer(MajorS), string:to_integer(MinorS)} of + {{Major, ""}, {Minor, _}} + when is_integer(Major), is_integer(Minor) -> + {Major, Minor}; + _ -> {0, 0} + end; + _ -> {0, 0} %XXX: Assumes no revision numbers in versioning end end. diff --git a/lib/hipe/main/hipe_main.erl b/lib/hipe/main/hipe_main.erl index be5050e155..b9d783d20a 100644 --- a/lib/hipe/main/hipe_main.erl +++ b/lib/hipe/main/hipe_main.erl @@ -284,8 +284,9 @@ icode_ssa_type(IcodeSSA, MFA, Options, Servers) -> false -> AnnIcode1 end, AnnIcode3 = icode_range_analysis(AnnIcode2, MFA, Options, Servers), - pp(AnnIcode3, MFA, icode, pp_range_icode, Options, Servers), - hipe_icode_type:unannotate_cfg(AnnIcode3) + AnnIcode4 = icode_eliminate_safe_calls(AnnIcode3, Options), + pp(AnnIcode4, MFA, icode, pp_range_icode, Options, Servers), + hipe_icode_type:unannotate_cfg(AnnIcode4) end. icode_ssa_convert(IcodeCfg, Options) -> @@ -334,6 +335,15 @@ icode_range_analysis(IcodeSSA, MFA, Options, Servers) -> IcodeSSA end. +icode_eliminate_safe_calls(IcodeSSA, Options) -> + case proplists:get_bool(icode_call_elim, Options) of + true -> + ?option_time(hipe_icode_call_elim:cfg(IcodeSSA), + "Icode SSA safe call elimination", Options); + false -> + IcodeSSA + end. + icode_ssa_dead_code_elimination(IcodeSSA, Options) -> IcodeSSA1 = ?option_time(hipe_icode_ssa:remove_dead_code(IcodeSSA), "Icode SSA dead code elimination pass 2", |