aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'lib/compiler')
-rw-r--r--lib/compiler/src/beam_bsm.erl68
-rw-r--r--lib/compiler/src/beam_jump.erl2
-rw-r--r--lib/compiler/src/beam_utils.erl18
-rw-r--r--lib/compiler/src/v3_codegen.erl1
-rw-r--r--lib/compiler/test/Makefile4
-rw-r--r--lib/compiler/test/andor_SUITE.erl7
-rw-r--r--lib/compiler/test/beam_except_SUITE.erl (renamed from lib/compiler/test/beam_expect_SUITE.erl)2
-rw-r--r--lib/compiler/test/beam_validator_SUITE.erl19
-rw-r--r--lib/compiler/test/bs_bit_binaries_SUITE.erl12
-rw-r--r--lib/compiler/test/bs_construct_SUITE.erl10
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl71
-rw-r--r--lib/compiler/test/compilation_SUITE.erl39
-rw-r--r--lib/compiler/test/core_SUITE.erl8
-rw-r--r--lib/compiler/test/core_fold_SUITE.erl8
-rw-r--r--lib/compiler/test/error_SUITE.erl19
-rw-r--r--lib/compiler/test/guard_SUITE.erl19
-rw-r--r--lib/compiler/test/inline_SUITE.erl31
-rw-r--r--lib/compiler/test/match_SUITE.erl8
-rw-r--r--lib/compiler/test/misc_SUITE.erl7
-rw-r--r--lib/compiler/test/receive_SUITE.erl6
-rw-r--r--lib/compiler/test/record_SUITE.erl10
-rw-r--r--lib/compiler/test/test_lib.erl15
-rw-r--r--lib/compiler/test/trycatch_SUITE.erl12
-rw-r--r--lib/compiler/test/warnings_SUITE.erl14
24 files changed, 259 insertions, 151 deletions
diff --git a/lib/compiler/src/beam_bsm.erl b/lib/compiler/src/beam_bsm.erl
index 37053e1cc4..02794a8e18 100644
--- a/lib/compiler/src/beam_bsm.erl
+++ b/lib/compiler/src/beam_bsm.erl
@@ -241,21 +241,45 @@ btb_reaches_match_2([{bif,_,{f,F},Ss,Dst}=I|Is], Regs0, D0) ->
Regs = btb_kill([Dst], Regs0),
D = btb_follow_branch(F, Regs, D0),
btb_reaches_match_1(Is, Regs, D);
-btb_reaches_match_2([{test,bs_start_match2,_,_,[Ctx,_],Ctx}|Is], Regs, D) ->
- case btb_context_regs(Regs) of
- [Ctx] ->
- D;
- CtxRegs ->
- case member(Ctx, CtxRegs) of
- false -> btb_reaches_match_2(Is, Regs, D);
- true -> btb_error(unsuitable_bs_start_match)
+btb_reaches_match_2([{test,bs_start_match2,{f,F},Live,[Ctx,_],Ctx}=I|Is],
+ Regs0, D0) ->
+ CtxRegs = btb_context_regs(Regs0),
+ case member(Ctx, CtxRegs) of
+ false ->
+ %% This bs_start_match2 instruction does not use "our"
+ %% match state. Therefore we can continue the search
+ %% for another bs_start_match2 instruction.
+ D = btb_follow_branch(F, Regs0, D0),
+ Regs = btb_kill_not_live(Live, Regs0),
+ btb_reaches_match_2(Is, Regs, D);
+ true ->
+ %% OK. This instruction will use "our" match state,
+ %% but we must make sure that all other copies of the
+ %% match state are killed in the code that follows
+ %% the instruction. (We know that the fail branch cannot
+ %% be taken in this case.)
+ OtherCtxRegs = CtxRegs -- [Ctx],
+ case btb_are_all_unused(OtherCtxRegs, Is, D0) of
+ false -> btb_error({OtherCtxRegs,not_all_unused_after,I});
+ true -> D0
end
end;
-btb_reaches_match_2([{test,bs_start_match2,_,_,[Bin,_],Ctx}|Is], Regs, D) ->
- CtxRegs = btb_context_regs(Regs),
+btb_reaches_match_2([{test,bs_start_match2,{f,F},Live,[Bin,_],Ctx}|Is],
+ Regs0, D0) ->
+ CtxRegs = btb_context_regs(Regs0),
case member(Bin, CtxRegs) orelse member(Ctx, CtxRegs) of
- false -> btb_reaches_match_2(Is, Regs, D);
- true -> btb_error(unsuitable_bs_start_match)
+ false ->
+ %% This bs_start_match2 does not reference any copy of the
+ %% match state. Therefore it can safely be passed on the
+ %% way to another (perhaps more suitable) bs_start_match2
+ %% instruction.
+ D = btb_follow_branch(F, Regs0, D0),
+ Regs = btb_kill_not_live(Live, Regs0),
+ btb_reaches_match_2(Is, Regs, D);
+ true ->
+ %% This variant of the bs_start_match2 instruction does
+ %% not accept a match state as source.
+ btb_error(unsuitable_bs_start_match)
end;
btb_reaches_match_2([{test,_,{f,F},Ss}=I|Is], Regs, D0) ->
btb_ensure_not_used(Ss, I, Regs),
@@ -287,11 +311,11 @@ btb_reaches_match_2([{bs_restore2,Src,_}=I|Is], Regs0, D) ->
btb_reaches_match_1(Is, Regs0, D);
true ->
%% Check that all other copies of the context registers
- %% are killed by the following instructions.
+ %% are unused by the following instructions.
Regs = btb_kill([Src], Regs0),
CtxRegs = btb_context_regs(Regs),
- case btb_are_all_killed(CtxRegs, Is, D) of
- false -> btb_error({CtxRegs,not_all_killed_after,I});
+ case btb_are_all_unused(CtxRegs, Is, D) of
+ false -> btb_error({CtxRegs,not_all_unused_after,I});
true -> D#btb{must_not_save=true}
end
end;
@@ -301,11 +325,11 @@ btb_reaches_match_2([{bs_context_to_binary,Src}=I|Is], Regs0, D) ->
btb_reaches_match_1(Is, Regs0, D);
true ->
%% Check that all other copies of the context registers
- %% are killed by the following instructions.
+ %% are unused by the following instructions.
Regs = btb_kill([Src], Regs0),
CtxRegs = btb_context_regs(Regs),
- case btb_are_all_killed(CtxRegs, Is, D) of
- false -> btb_error({CtxRegs,not_all_killed_after,I});
+ case btb_are_all_unused(CtxRegs, Is, D) of
+ false -> btb_error({CtxRegs,not_all_unused_after,I});
true -> D#btb{must_not_save=true}
end
end;
@@ -343,7 +367,7 @@ btb_call(Arity, Lbl, Regs0, Is, D0) ->
%% tucked away in a y register.
RegList = btb_context_regs(Regs),
YRegs = [R || {y,_}=R <- RegList],
- case btb_are_all_killed(YRegs, Is, D) of
+ case btb_are_all_unused(YRegs, Is, D) of
true -> D;
false -> btb_error({multiple_uses,RegList})
end;
@@ -426,11 +450,11 @@ btb_reaches_match_block([], Regs) ->
Regs.
%% btb_are_all_killed([Register], [Instruction], D) -> true|false
-%% Test whether all of the register are killed in the instruction stream.
+%% Test whether all of the register are unused in the instruction stream.
-btb_are_all_killed(RegList, Is, #btb{index=Li}) ->
+btb_are_all_unused(RegList, Is, #btb{index=Li}) ->
all(fun(R) ->
- beam_utils:is_killed(R, Is, Li)
+ beam_utils:is_not_used(R, Is, Li)
end, RegList).
%% btp_regs_from_list([Register]) -> RegisterSet.
diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl
index b05d01b2a1..636c299e47 100644
--- a/lib/compiler/src/beam_jump.erl
+++ b/lib/compiler/src/beam_jump.erl
@@ -220,6 +220,8 @@ extract_seq([{line,_}=Line|Is], Acc) ->
extract_seq(Is, [Line|Acc]);
extract_seq([{block,_}=Bl|Is], Acc) ->
extract_seq_1(Is, [Bl|Acc]);
+extract_seq([{bs_context_to_binary,_}=I|Is], Acc) ->
+ extract_seq_1(Is, [I|Acc]);
extract_seq([{label,_}|_]=Is, Acc) ->
extract_seq_1(Is, Acc);
extract_seq(_, _) -> no.
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index 8b661e6901..8af0447f63 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.erl
@@ -263,19 +263,11 @@ check_liveness(R, [{test,_,{f,Fail},As}|Is], St0) ->
{_,_}=Other -> Other
end
end;
-check_liveness(R, [{test,_,{f,Fail},Live,Ss,_}|Is], St0) ->
- case R of
- {x,X} ->
- case X < Live orelse member(R, Ss) of
- true -> {used,St0};
- false -> check_liveness_at(R, Fail, St0)
- end;
- {y,_} ->
- case check_liveness_at(R, Fail, St0) of
- {killed,St} -> check_liveness(R, Is, St);
- {_,_}=Other -> Other
- end
- end;
+check_liveness(R, [{test,Op,Fail,Live,Ss,Dst}|Is], St) ->
+ %% Check this instruction as a block to get a less conservative
+ %% result if the caller is is_not_used/3.
+ Block = [{set,[Dst],Ss,{alloc,Live,{bif,Op,Fail}}}],
+ check_liveness(R, [{block,Block}|Is], St);
check_liveness(R, [{select,_,R,_,_}|_], St) ->
{used,St};
check_liveness(R, [{select,_,_,Fail,Branches}|_], St) ->
diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl
index 3b73269545..6a13495523 100644
--- a/lib/compiler/src/v3_codegen.erl
+++ b/lib/compiler/src/v3_codegen.erl
@@ -379,6 +379,7 @@ bsm_rename_ctx(#l{ke={test,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={gc_bif,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={set,_,_}}=L, _, _, _) -> L;
+bsm_rename_ctx(#l{ke={call,_,_,_}}=L, _, _, _) -> L;
bsm_rename_ctx(#l{ke={block,_}}=L, Old, _, false) ->
%% This block is not inside a protected. The match context variable cannot
%% possibly be live inside the block.
diff --git a/lib/compiler/test/Makefile b/lib/compiler/test/Makefile
index e047166ade..3b065ec3b9 100644
--- a/lib/compiler/test/Makefile
+++ b/lib/compiler/test/Makefile
@@ -10,7 +10,7 @@ MODULES= \
apply_SUITE \
beam_validator_SUITE \
beam_disasm_SUITE \
- beam_expect_SUITE \
+ beam_except_SUITE \
bs_bincomp_SUITE \
bs_bit_binaries_SUITE \
bs_construct_SUITE \
@@ -39,7 +39,7 @@ MODULES= \
NO_OPT= \
andor \
apply \
- beam_expect \
+ beam_except \
bs_construct \
bs_match \
bs_utf \
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index f7388f1614..fe69aeeb43 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_SUITE.erl
@@ -29,11 +29,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [t_case, t_and_or, t_andalso, t_orelse, inside, overlap,
- combined, in_case, before_and_inside_if].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [t_case,t_and_or,t_andalso,t_orelse,inside,overlap,
+ combined,in_case,before_and_inside_if]}].
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/beam_expect_SUITE.erl b/lib/compiler/test/beam_except_SUITE.erl
index 6f216eac4f..6b55224a42 100644
--- a/lib/compiler/test/beam_expect_SUITE.erl
+++ b/lib/compiler/test/beam_except_SUITE.erl
@@ -16,7 +16,7 @@
%%
%% %CopyrightEnd%
%%
--module(beam_expect_SUITE).
+-module(beam_except_SUITE).
-export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1,
init_per_group/2,end_per_group/2,
diff --git a/lib/compiler/test/beam_validator_SUITE.erl b/lib/compiler/test/beam_validator_SUITE.erl
index 902867bc19..c84c83795a 100644
--- a/lib/compiler/test/beam_validator_SUITE.erl
+++ b/lib/compiler/test/beam_validator_SUITE.erl
@@ -47,17 +47,18 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [beam_files, compiler_bug, stupid_but_valid, xrange,
- yrange, stack, call_last, merge_undefined, uninit,
- unsafe_catch, dead_code, mult_labels,
- overwrite_catchtag, overwrite_trytag, accessing_tags,
- bad_catch_try, cons_guard, freg_range, freg_uninit,
- freg_state, bin_match, bin_aligned, bad_dsetel,
- state_after_fault_in_catch, no_exception_in_catch,
- undef_label, illegal_instruction, failing_gc_guard_bif].
+ [beam_files,{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [compiler_bug,stupid_but_valid,xrange,
+ yrange,stack,call_last,merge_undefined,uninit,
+ unsafe_catch,dead_code,mult_labels,
+ overwrite_catchtag,overwrite_trytag,accessing_tags,
+ bad_catch_try,cons_guard,freg_range,freg_uninit,
+ freg_state,bin_match,bin_aligned,bad_dsetel,
+ state_after_fault_in_catch,no_exception_in_catch,
+ undef_label,illegal_instruction,failing_gc_guard_bif]}].
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/bs_bit_binaries_SUITE.erl b/lib/compiler/test/bs_bit_binaries_SUITE.erl
index 30276f1259..897b4769f1 100644
--- a/lib/compiler/test/bs_bit_binaries_SUITE.erl
+++ b/lib/compiler/test/bs_bit_binaries_SUITE.erl
@@ -34,13 +34,15 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [misc, horrid_match, test_bitstr, test_bit_size,
- asymmetric_tests, big_asymmetric_tests,
- binary_to_and_from_list, big_binary_to_and_from_list,
- send_and_receive, send_and_receive_alot].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [misc,horrid_match,test_bitstr,test_bit_size,
+ asymmetric_tests,big_asymmetric_tests,
+ binary_to_and_from_list,big_binary_to_and_from_list,
+ send_and_receive,send_and_receive_alot]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/bs_construct_SUITE.erl b/lib/compiler/test/bs_construct_SUITE.erl
index a393aaeffd..4ea5235bb6 100644
--- a/lib/compiler/test/bs_construct_SUITE.erl
+++ b/lib/compiler/test/bs_construct_SUITE.erl
@@ -36,12 +36,14 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [two, test1, fail, float_bin, in_guard, in_catch,
- nasty_literals, side_effect, opt, otp_7556, float_arith,
- otp_8054].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [two,test1,fail,float_bin,in_guard,in_catch,
+ nasty_literals,side_effect,opt,otp_7556,float_arith,
+ otp_8054]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 0e9d0bbc17..d63d2235d7 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2005-2011. All Rights Reserved.
+%% Copyright Ericsson AB 2005-2012. 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
@@ -33,7 +33,7 @@
matching_meets_construction/1,simon/1,matching_and_andalso/1,
otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1,
match_string/1,zero_width/1,bad_size/1,haystack/1,
- cover_beam_bool/1,matched_out_size/1]).
+ cover_beam_bool/1,matched_out_size/1,follow_fail_branch/1]).
-export([coverage_id/1,coverage_external_ignore/2]).
@@ -44,19 +44,21 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [fun_shadow, int_float, otp_5269, null_fields, wiger,
- bin_tail, save_restore, shadowed_size_var,
- partitioned_bs_match, function_clause, unit,
- shared_sub_bins, bin_and_float, dec_subidentifiers,
- skip_optional_tag, wfbm, degenerated_match, bs_sum,
- coverage, multiple_uses, zero_label, followed_by_catch,
- matching_meets_construction, simon,
- matching_and_andalso, otp_7188, otp_7233, otp_7240,
- otp_7498, match_string, zero_width, bad_size, haystack,
- cover_beam_bool, matched_out_size].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [fun_shadow,int_float,otp_5269,null_fields,wiger,
+ bin_tail,save_restore,shadowed_size_var,
+ partitioned_bs_match,function_clause,unit,
+ shared_sub_bins,bin_and_float,dec_subidentifiers,
+ skip_optional_tag,wfbm,degenerated_match,bs_sum,
+ coverage,multiple_uses,zero_label,followed_by_catch,
+ matching_meets_construction,simon,
+ matching_and_andalso,otp_7188,otp_7233,otp_7240,
+ otp_7498,match_string,zero_width,bad_size,haystack,
+ cover_beam_bool,matched_out_size,follow_fail_branch]}].
+
init_per_suite(Config) ->
Config.
@@ -800,12 +802,29 @@ matching_and_andalso(Config) when is_list(Config) ->
?line {'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, -8)),
?line {'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, blurf)),
?line {'EXIT',{function_clause,_}} = (catch matching_and_andalso_1(<<1,2,3>>, 19)),
+
+ {"abc",<<"xyz">>} = matching_and_andalso_2("abc", <<"-xyz">>),
+ {"abc",<<"">>} = matching_and_andalso_2("abc", <<($a-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_2("abc", <<($z+1)>>),
+ {"abc",<<"">>} = matching_and_andalso_2("abc", <<($A-1)>>),
+ {"abc",<<"">>} = matching_and_andalso_2("abc", <<($Z+1)>>),
+ error = matching_and_andalso_2([], <<>>),
+ error = matching_and_andalso_2([], <<$A>>),
+ error = matching_and_andalso_2([], <<$Z>>),
+ error = matching_and_andalso_2([], <<$a>>),
+ error = matching_and_andalso_2([], <<$z>>),
ok.
matching_and_andalso_1(<<Bitmap/binary>>, K)
when is_integer(K) andalso size(Bitmap) >= K andalso 0 < K ->
ok.
+matching_and_andalso_2(Datetime, <<H,T/binary>>)
+ when not ((H >= $a) andalso (H =< $z)) andalso
+ not ((H >= $A) andalso (H =< $Z)) ->
+ {Datetime,T};
+matching_and_andalso_2(_, _) -> error.
+
%% Thanks to Tomas Stejskal.
otp_7188(Config) when is_list(Config) ->
MP3 = <<84,65,71,68,117,154,105,232,107,121,0,0,0,0,0,0,0,0,0,0,
@@ -1089,6 +1108,32 @@ mos_bin(<<L,Bin:L/binary,"abcdefghij">>) ->
L = byte_size(Bin),
Bin.
+follow_fail_branch(_) ->
+ 42 = ffb_1(<<0,1>>, <<0>>),
+ 8 = ffb_1(<<0,1>>, [a]),
+ 42 = ffb_2(<<0,1>>, <<0>>, 17),
+ 8 = ffb_2(<<0,1>>, [a], 0),
+ ok.
+
+ffb_1(<<_,T/bitstring>>, List) ->
+ case List of
+ <<_>> ->
+ 42;
+ [_|_] ->
+ %% The fail branch of the bs_start_match2 instruction
+ %% pointing to here would be ignored, making the compiler
+ %% incorrectly assume that the delayed sub-binary
+ %% optimization was safe.
+ bit_size(T)
+ end.
+
+ffb_2(<<_,T/bitstring>>, List, A) ->
+ case List of
+ <<_>> when A =:= 17 -> 42;
+ [_|_] -> bit_size(T)
+ end.
+
+
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl
index 34f105b5fc..bec97b0199 100644
--- a/lib/compiler/test/compilation_SUITE.erl
+++ b/lib/compiler/test/compilation_SUITE.erl
@@ -28,26 +28,29 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [self_compile_old_inliner, self_compile, compiler_1,
- compiler_3, compiler_5, beam_compiler_1,
- beam_compiler_2, beam_compiler_3, beam_compiler_4,
- beam_compiler_5, beam_compiler_6, beam_compiler_7,
- beam_compiler_8, beam_compiler_9, beam_compiler_10,
- beam_compiler_11, beam_compiler_12,
- nested_tuples_in_case_expr, otp_2330, guards,
- {group, vsn}, otp_2380, otp_2141, otp_2173, otp_4790,
- const_list_256, bin_syntax_1, bin_syntax_2,
- bin_syntax_3, bin_syntax_4, bin_syntax_5, bin_syntax_6,
- live_var, convopts, bad_functional_value,
- catch_in_catch, redundant_case, long_string, otp_5076,
- complex_guard, otp_5092, otp_5151, otp_5235, otp_5244,
- trycatch_4, opt_crash, otp_5404, otp_5436, otp_5481,
- otp_5553, otp_5632, otp_5714, otp_5872, otp_6121,
- otp_6121a, otp_6121b, otp_7202, otp_7345, on_load,
- string_table,otp_8949_a,otp_8949_a,split_cases].
+ [self_compile_old_inliner,self_compile,
+ {group,p}].
groups() ->
- [{vsn, [], [vsn_1, vsn_2, vsn_3]}].
+ [{vsn,[parallel],[vsn_1,vsn_2,vsn_3]},
+ {p,test_lib:parallel(),
+ [compiler_1,
+ compiler_3,compiler_5,beam_compiler_1,
+ beam_compiler_2,beam_compiler_3,beam_compiler_4,
+ beam_compiler_5,beam_compiler_6,beam_compiler_7,
+ beam_compiler_8,beam_compiler_9,beam_compiler_10,
+ beam_compiler_11,beam_compiler_12,
+ nested_tuples_in_case_expr,otp_2330,guards,
+ {group,vsn},otp_2380,otp_2141,otp_2173,otp_4790,
+ const_list_256,bin_syntax_1,bin_syntax_2,
+ bin_syntax_3,bin_syntax_4,bin_syntax_5,bin_syntax_6,
+ live_var,convopts,bad_functional_value,
+ catch_in_catch,redundant_case,long_string,otp_5076,
+ complex_guard,otp_5092,otp_5151,otp_5235,otp_5244,
+ trycatch_4,opt_crash,otp_5404,otp_5436,otp_5481,
+ otp_5553,otp_5632,otp_5714,otp_5872,otp_6121,
+ otp_6121a,otp_6121b,otp_7202,otp_7345,on_load,
+ string_table,otp_8949_a,otp_8949_a,split_cases]}].
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/core_SUITE.erl b/lib/compiler/test/core_SUITE.erl
index 06185bfc34..a40dc32d59 100644
--- a/lib/compiler/test/core_SUITE.erl
+++ b/lib/compiler/test/core_SUITE.erl
@@ -43,11 +43,13 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
- eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [dehydrated_itracer,nested_tries,seq_in_guard,make_effect_seq,
+ eval_is_boolean,unsafe_case,nomatch_shadow,reversed_annos]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/core_fold_SUITE.erl b/lib/compiler/test/core_fold_SUITE.erl
index 54bd52947e..2adc71c237 100644
--- a/lib/compiler/test/core_fold_SUITE.erl
+++ b/lib/compiler/test/core_fold_SUITE.erl
@@ -31,11 +31,13 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [t_element, setelement, t_length, append, t_apply, bifs,
- eq, nested_call_in_case, guard_try_catch, coverage].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [t_element,setelement,t_length,append,t_apply,bifs,
+ eq,nested_call_in_case,guard_try_catch,coverage]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index e798023cd8..859c4571ea 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -32,10 +32,11 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [head_mismatch_line, warnings_as_errors, bif_clashes, transforms].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [head_mismatch_line,warnings_as_errors,bif_clashes,transforms]}].
init_per_suite(Config) ->
Config.
@@ -282,12 +283,14 @@ filter(X) ->
%% Compiles a test module and returns the list of errors and warnings.
test_filename(Conf) ->
- Filename = "errors_test.erl",
+ Filename = ["errors_test_",test_lib:uniq(),".erl"],
DataDir = ?config(priv_dir, Conf),
filename:join(DataDir, Filename).
run_test(Test0, File, Warnings, WriteBeam) ->
- ?line Test = ["-module(errors_test). ", Test0],
+ ModName = filename:rootname(filename:basename(File), ".erl"),
+ Mod = list_to_atom(ModName),
+ Test = ["-module(",ModName,"). ",Test0],
?line Opts = case WriteBeam of
dont_write_beam ->
[binary,return_errors|Warnings];
@@ -301,17 +304,17 @@ run_test(Test0, File, Warnings, WriteBeam) ->
%% Test result of compilation.
?line Res = case compile:file(File, Opts) of
- {ok,errors_test,_,[{_File,Ws}]} ->
+ {ok,Mod,_,[{_File,Ws}]} ->
%io:format("compile:file(~s,~p) ->~n~p~n",
% [File,Opts,Ws]),
{warning,Ws};
- {ok,errors_test,_,[]} ->
+ {ok,Mod,_,[]} ->
%io:format("compile:file(~s,~p) ->~n~p~n",
% [File,Opts,Ws]),
[];
- {ok,errors_test,[{_File,Ws}]} ->
+ {ok,Mod,[{_File,Ws}]} ->
{warning,Ws};
- {ok,errors_test,[]} ->
+ {ok,Mod,[]} ->
[];
{error,[{XFile,Es}],Ws} = _ZZ when is_list(XFile) ->
%io:format("compile:file(~s,~p) ->~n~p~n",
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index 40711783ed..66c0b9a295 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -39,17 +39,18 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [misc, const_cond, basic_not, complex_not, nested_nots,
- semicolon, complex_semicolon, comma, or_guard,
- more_or_guards, complex_or_guards, and_guard, xor_guard,
- more_xor_guards, build_in_guard, old_guard_tests, gbif,
- t_is_boolean, is_function_2, tricky, rel_ops,
- literal_type_tests, basic_andalso_orelse, traverse_dcd,
- check_qlc_hrl, andalso_semi, t_tuple_size, binary_part,
- bad_constants].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [misc,const_cond,basic_not,complex_not,nested_nots,
+ semicolon,complex_semicolon,comma,or_guard,
+ more_or_guards,complex_or_guards,and_guard,xor_guard,
+ more_xor_guards,build_in_guard,old_guard_tests,gbif,
+ t_is_boolean,is_function_2,tricky,rel_ops,
+ literal_type_tests,basic_andalso_orelse,traverse_dcd,
+ check_qlc_hrl,andalso_semi,t_tuple_size,binary_part,
+ bad_constants]}].
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/inline_SUITE.erl b/lib/compiler/test/inline_SUITE.erl
index 2e17d3fde6..e2eb6a0dec 100644
--- a/lib/compiler/test/inline_SUITE.erl
+++ b/lib/compiler/test/inline_SUITE.erl
@@ -32,17 +32,22 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [attribute, bsdecode, bsdes, barnes2, decode1, smith,
- itracer, pseudoknot, comma_splitter, lists, really_inlined, otp_7223,
- coverage].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [attribute,bsdecode,bsdes,barnes2,decode1,smith,
+ itracer,pseudoknot,comma_splitter,lists,really_inlined,otp_7223,
+ coverage]}].
init_per_suite(Config) ->
- Config.
+ Pa = "-pa " ++ filename:dirname(code:which(?MODULE)),
+ {ok,Node} = start_node(compiler, Pa),
+ [{testing_node,Node}|Config].
-end_per_suite(_Config) ->
+end_per_suite(Config) ->
+ Node = ?config(testing_node, Config),
+ ?t:stop_node(Node),
ok.
init_per_group(_GroupName, Config) ->
@@ -81,6 +86,7 @@ attribute(Config) when is_list(Config) ->
?comp(comma_splitter).
try_inline(Mod, Config) ->
+ Node = ?config(testing_node, Config),
?line Src = filename:join(?config(data_dir, Config), atom_to_list(Mod)),
?line Out = ?config(priv_dir,Config),
@@ -89,8 +95,6 @@ try_inline(Mod, Config) ->
?line {ok,Mod} = compile:file(Src, [{outdir,Out},report,bin_opt_info,clint]),
?line Dog = test_server:timetrap(test_server:minutes(10)),
- ?line Pa = "-pa " ++ filename:dirname(code:which(?MODULE)),
- ?line {ok,Node} = start_node(compiler, Pa),
?line NormalResult = rpc:call(Node, ?MODULE, load_and_call, [Out,Mod]),
?line test_server:timetrap_cancel(Dog),
@@ -125,7 +129,6 @@ try_inline(Mod, Config) ->
%% Delete Beam file.
?line ok = file:delete(filename:join(Out, atom_to_list(Mod)++code:objfile_extension())),
- ?line ?t:stop_node(Node),
ok.
compare(Same, Same) -> ok;
@@ -293,9 +296,9 @@ otp_7223_2({a}) ->
1.
coverage(Config) when is_list(Config) ->
- ?line Src = filename:join(?config(data_dir, Config), bsdecode),
- ?line Out = ?config(priv_dir,Config),
- ?line {ok,Mod} = compile:file(Src, [{outdir,Out},report,{inline,0},clint]),
- ?line {ok,Mod} = compile:file(Src, [{outdir,Out},report,{inline,20},verbose,clint]),
- ?line ok = file:delete(filename:join(Out, "bsdecode"++code:objfile_extension())),
+ Mod = bsdecode,
+ Src = filename:join(?config(data_dir, Config), Mod),
+ {ok,Mod,_} = compile:file(Src, [binary,report,{inline,0},clint]),
+ {ok,Mod,_} = compile:file(Src, [binary,report,{inline,20},
+ verbose,clint]),
ok.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index 9406d7de8f..de44926d81 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -30,11 +30,13 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [pmatch, mixed, aliases, match_in_call, untuplify,
- shortcut_boolean, letify_guard, selectify, underscore, coverage].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [pmatch,mixed,aliases,match_in_call,untuplify,
+ shortcut_boolean,letify_guard,selectify,underscore,coverage]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index 6df8b2ac30..44c7161530 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -57,11 +57,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
-spec all() -> misc_SUITE_test_cases().
all() ->
test_lib:recompile(?MODULE),
- [tobias, empty_string, md5, silly_coverage,
- confused_literals, integer_encoding, override_bif].
+ [{group,p}].
groups() ->
- [].
+ [{p,[],%%test_lib:parallel(),
+ [tobias,empty_string,md5,silly_coverage,
+ confused_literals,integer_encoding,override_bif]}].
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index 2a67615e5e..82c823b789 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_SUITE.erl
@@ -40,10 +40,12 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [recv, coverage, otp_7980, ref_opt, export].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [recv,coverage,otp_7980,ref_opt,export]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl
index 363422ec7e..96f3712be9 100644
--- a/lib/compiler/test/record_SUITE.erl
+++ b/lib/compiler/test/record_SUITE.erl
@@ -42,12 +42,14 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [errors, record_test_2, record_test_3,
- record_access_in_guards, guard_opt, eval_once, foobar,
- missing_test_heap, nested_access, coverage].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [errors,record_test_2,record_test_3,
+ record_access_in_guards,guard_opt,eval_once,foobar,
+ missing_test_heap,nested_access,coverage]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index 2295592a38..996c369705 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -20,7 +20,8 @@
-include("test_server.hrl").
-compile({no_auto_import,[binary_part/2]}).
--export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1,p_run/2,binary_part/2]).
+-export([recompile/1,parallel/0,uniq/0,opt_opts/1,get_data_dir/1,
+ smoke_disasm/1,p_run/2,binary_part/2]).
recompile(Mod) when is_atom(Mod) ->
case whereis(cover_server) of
@@ -43,6 +44,18 @@ smoke_disasm(File) when is_list(File) ->
Res = beam_disasm:file(File),
{beam_file,_Mod} = {element(1, Res),element(2, Res)}.
+parallel() ->
+ case ?t:is_cover() orelse erlang:system_info(schedulers) =:= 1 of
+ true -> [];
+ false -> [parallel]
+ end.
+
+uniq() ->
+ U0 = erlang:ref_to_list(make_ref()),
+ U1 = re:replace(U0, "^#Ref", ""),
+ U = re:replace(U1, "[^[A-Za-z0-9_]+", "_", [global]),
+ re:replace(U, "_*$", "", [{return,list}]).
+
%% Retrieve the "interesting" compiler options (options for optimization
%% and compatibility) for the given module.
diff --git a/lib/compiler/test/trycatch_SUITE.erl b/lib/compiler/test/trycatch_SUITE.erl
index 29119c0f5d..4530d08c77 100644
--- a/lib/compiler/test/trycatch_SUITE.erl
+++ b/lib/compiler/test/trycatch_SUITE.erl
@@ -32,13 +32,15 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [basic, lean_throw, try_of, try_after, catch_oops,
- after_oops, eclectic, rethrow, nested_of, nested_catch,
- nested_after, nested_horrid, last_call_optimization,
- bool, plain_catch_coverage, andalso_orelse, get_in_try].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [basic,lean_throw,try_of,try_after,catch_oops,
+ after_oops,eclectic,rethrow,nested_of,nested_catch,
+ nested_after,nested_horrid,last_call_optimization,
+ bool,plain_catch_coverage,andalso_orelse,get_in_try]}].
+
init_per_suite(Config) ->
Config.
diff --git a/lib/compiler/test/warnings_SUITE.erl b/lib/compiler/test/warnings_SUITE.erl
index f6a572abfa..9ce0df5ec4 100644
--- a/lib/compiler/test/warnings_SUITE.erl
+++ b/lib/compiler/test/warnings_SUITE.erl
@@ -55,12 +55,13 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
test_lib:recompile(?MODULE),
- [pattern, pattern2, pattern3, pattern4, guard,
- bad_arith, bool_cases, bad_apply, files, effect,
- bin_opt_info, bin_construction].
+ [{group,p}].
groups() ->
- [].
+ [{p,test_lib:parallel(),
+ [pattern,pattern2,pattern3,pattern4,guard,
+ bad_arith,bool_cases,bad_apply,files,effect,
+ bin_opt_info,bin_construction]}].
init_per_suite(Config) ->
Config.
@@ -556,9 +557,10 @@ run(Config, Tests) ->
%% Compiles a test module and returns the list of errors and warnings.
run_test(Conf, Test0, Warnings) ->
- Filename = 'warnings_test.erl',
+ Mod = "warnings_"++test_lib:uniq(),
+ Filename = Mod ++ ".erl",
?line DataDir = ?privdir,
- ?line Test = ["-module(warnings_test). ", Test0],
+ Test = ["-module(", Mod, "). ", Test0],
?line File = filename:join(DataDir, Filename),
?line Opts = [binary,export_all,return|Warnings],
?line ok = file:write_file(File, Test),