aboutsummaryrefslogtreecommitdiffstats
path: root/lib/hipe/main
diff options
context:
space:
mode:
Diffstat (limited to 'lib/hipe/main')
-rw-r--r--lib/hipe/main/hipe.erl48
1 files changed, 33 insertions, 15 deletions
diff --git a/lib/hipe/main/hipe.erl b/lib/hipe/main/hipe.erl
index c026329276..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,
@@ -1484,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.
@@ -1525,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'.
@@ -1543,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.