From f833a900897faae48230bc8c1e7572fb470a4a6f Mon Sep 17 00:00:00 2001 From: Erik Norgren Date: Mon, 9 Jun 2014 14:12:08 +0200 Subject: hipe: Add test suite for verifying optimisations * Added a suite opt_verify_SUITE.erl to HiPE that tests for the results of optimisations, with a single testcase that checks that the icode_call_elim optimisation pass does remove calls to maps:is_key/2 where sound and not otherwise. * Made hipe_testsuite_driver only create explicitly listed suites. --- lib/hipe/test/Makefile | 5 +- lib/hipe/test/hipe_testsuite_driver.erl | 24 +++------ lib/hipe/test/opt_verify_SUITE.erl | 62 ++++++++++++++++++++++ .../test/opt_verify_SUITE_data/call_elim_test.erl | 12 +++++ .../call_elim_test_branches_no_opt_poss.erl | 32 +++++++++++ .../call_elim_test_branches_opt_poss.erl | 32 +++++++++++ 6 files changed, 149 insertions(+), 18 deletions(-) create mode 100644 lib/hipe/test/opt_verify_SUITE.erl create mode 100644 lib/hipe/test/opt_verify_SUITE_data/call_elim_test.erl create mode 100644 lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_no_opt_poss.erl create mode 100644 lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_opt_poss.erl (limited to 'lib/hipe') diff --git a/lib/hipe/test/Makefile b/lib/hipe/test/Makefile index 09f4fd2129..544888719f 100644 --- a/lib/hipe/test/Makefile +++ b/lib/hipe/test/Makefile @@ -6,7 +6,8 @@ include $(ERL_TOP)/make/$(TARGET)/otp.mk # ---------------------------------------------------- MODULES= \ - hipe_SUITE + hipe_SUITE \ + opt_verify_SUITE # .erl files for these modules are automatically generated GEN_MODULES= \ @@ -79,4 +80,4 @@ release_tests_spec: make_emakefile @tar cf - *_SUITE_data | (cd "$(RELSYSDIR)"; tar xf -) cd "$(RELSYSDIR)";\ erlc hipe_testsuite_driver.erl;\ - erl -noshell -run hipe_testsuite_driver create_all_suites -s erlang halt + erl -noshell -run hipe_testsuite_driver create_all_suites $(GEN_MODULES) -s erlang halt diff --git a/lib/hipe/test/hipe_testsuite_driver.erl b/lib/hipe/test/hipe_testsuite_driver.erl index 9f5d7421b4..15b267b72e 100644 --- a/lib/hipe/test/hipe_testsuite_driver.erl +++ b/lib/hipe/test/hipe_testsuite_driver.erl @@ -1,6 +1,6 @@ -module(hipe_testsuite_driver). --export([create_all_suites/0, run/3]). +-export([create_all_suites/1, run/3]). -include_lib("kernel/include/file.hrl"). @@ -16,25 +16,17 @@ outputfile :: file:io_device(), testcases :: [testcase()]}). --spec create_all_suites() -> 'ok'. +-spec create_all_suites([string()]) -> 'ok'. -create_all_suites() -> - {ok, Cwd} = file:get_cwd(), - Suites = get_suites(Cwd), +create_all_suites(SuitesWithSuiteSuffix) -> + Suites = get_suites(SuitesWithSuiteSuffix), lists:foreach(fun create_suite/1, Suites). --spec get_suites(file:filename()) -> [string()]. +-spec get_suites([string()]) -> [string()]. -get_suites(Dir) -> - case file:list_dir(Dir) of - {error, _} -> []; - {ok, Filenames} -> - FullFilenames = [filename:join(Dir, F) || F <- Filenames], - Dirs = [suffix(filename:basename(F), ?suite_data) || - F <- FullFilenames, - file_type(F) =:= {ok, 'directory'}], - [S || {yes, S} <- Dirs] - end. +get_suites(SuitesWithSuiteSuffix) -> + Prefixes = [suffix(F, ?suite_suffix) || F <- SuitesWithSuiteSuffix], + [S || {yes, S} <- Prefixes]. suffix(String, Suffix) -> case string:rstr(String, Suffix) of diff --git a/lib/hipe/test/opt_verify_SUITE.erl b/lib/hipe/test/opt_verify_SUITE.erl new file mode 100644 index 0000000000..61952e81d7 --- /dev/null +++ b/lib/hipe/test/opt_verify_SUITE.erl @@ -0,0 +1,62 @@ +-module(opt_verify_SUITE). + +-compile([export_all]). + +all() -> + [call_elim]. + +groups() -> + []. + +init_per_suite(Config) -> + case erlang:system_info(hipe_architecture) of + undefined -> {skip, "HiPE not available or enabled"}; + _ -> Config + end. + +end_per_suite(_Config) -> + ok. + +init_per_group(_GroupName, Config) -> + Config. + +end_per_group(_GroupName, Config) -> + Config. + +call_elim_test_file(Config, FileName, Option) -> + PrivDir = test_server:lookup_config(priv_dir, Config), + TempOut = test_server:temp_name(filename:join(PrivDir, "call_elim_out")), + {ok, TestCase} = compile:file(FileName), + {ok, TestCase} = hipe:c(TestCase, [Option, {pp_range_icode, {file, TempOut}}]), + {ok, Icode} = file:read_file(TempOut), + ok = file:delete(TempOut), + Icode. + +substring_count(Icode, Substring) -> + substring_count(Icode, Substring, 0). +substring_count(Icode, Substring, N) -> + case string:str(Icode, Substring) of + 0 -> N; + I -> substring_count(lists:nthtail(I, Icode), Substring, N+1) + end. + +call_elim() -> + [{doc, "Test that the call elimination optimization pass is ok"}]. +call_elim(Config) -> + DataDir = test_server:lookup_config(data_dir, Config), + F1 = filename:join(DataDir, "call_elim_test.erl"), + Icode1 = call_elim_test_file(Config, F1, icode_call_elim), + 0 = substring_count(binary:bin_to_list(Icode1), "is_key"), + Icode2 = call_elim_test_file(Config, F1, no_icode_call_elim), + true = (0 /= substring_count(binary:bin_to_list(Icode2), "is_key")), + F2 = filename:join(DataDir, "call_elim_test_branches_no_opt_poss.erl"), + Icode3 = call_elim_test_file(Config, F2, icode_call_elim), + 3 = substring_count(binary:bin_to_list(Icode3), "is_key"), + Icode4 = call_elim_test_file(Config, F2, no_icode_call_elim), + 3 = substring_count(binary:bin_to_list(Icode4), "is_key"), + F3 = filename:join(DataDir, "call_elim_test_branches_opt_poss.erl"), + Icode5 = call_elim_test_file(Config, F3, icode_call_elim), + 0 = substring_count(binary:bin_to_list(Icode5), "is_key"), + Icode6 = call_elim_test_file(Config, F3, no_icode_call_elim), + 3 = substring_count(binary:bin_to_list(Icode6), "is_key"), + ok. diff --git a/lib/hipe/test/opt_verify_SUITE_data/call_elim_test.erl b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test.erl new file mode 100644 index 0000000000..8b725f8ffe --- /dev/null +++ b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test.erl @@ -0,0 +1,12 @@ +-module(call_elim_test). + +-export([test/0]). + +test() -> + true = has_1_field(#{1=>true}), + true = has_1_field(#{1=>"hej", b=>2}), + true = has_1_field(#{b=>3, 1=>4}), + ok. + +has_1_field(#{1:=_}) -> true; +has_1_field(#{}) -> false. diff --git a/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_no_opt_poss.erl b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_no_opt_poss.erl new file mode 100644 index 0000000000..7ffae86797 --- /dev/null +++ b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_no_opt_poss.erl @@ -0,0 +1,32 @@ +-module(call_elim_test_branches_no_opt_poss). + +-export([test/1]). + +test(A) -> + if A > 0 -> + false = has_a_field(#{b=>true}), + true = has_a_field(#{b=>1, a=>"2"}), + false = has_a_field(#{b=>5, c=>4}), + false = has_tuple_field(#{{ab, 2}=><<"qq">>, 1 =>0}), + false = has_tuple_field(#{up =>down, {ab, 2}=>[]}), + false = has_tuple_field(#{{ab, 2}=>42}); + A =< 0 -> + true = has_a_field(#{a=>q, 'A' =>nej}), + true = has_a_field(#{a=>"hej", false=>true}), + true = has_a_field(#{a=>3}), + true = has_tuple_field(#{{ab, 1}=>q, 'A' =>nej}), + true = has_tuple_field(#{{ab, 1}=>"hej", false=>true}), + true = has_tuple_field(#{{ab, 1}=>3}) + end, + true = has_nil_field(#{[] =>3, b=>"seven"}), + true = has_nil_field(#{"seventeen"=>17}), + ok. + +has_tuple_field(#{{ab, 1}:=_}) -> true; +has_tuple_field(#{}) -> false. + +has_a_field(#{a:=_}) -> true; +has_a_field(#{}) -> false. + +has_nil_field(#{[]:=_}) -> true; +has_nil_field(#{}) -> false. diff --git a/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_opt_poss.erl b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_opt_poss.erl new file mode 100644 index 0000000000..c8ddfa1e75 --- /dev/null +++ b/lib/hipe/test/opt_verify_SUITE_data/call_elim_test_branches_opt_poss.erl @@ -0,0 +1,32 @@ +-module(call_elim_test_branches_opt_poss). + +-export([test/1]). + +test(A) -> + if A > 0 -> + true = has_a_field(#{a=>true}), + true = has_a_field(#{b=>1, a=>"2"}), + true = has_a_field(#{a=>5, c=>4}), + true = has_tuple_field(#{{ab, 1}=><<"qq">>, 1 =>0}), + true = has_tuple_field(#{up =>down, {ab, 1}=>[]}), + true = has_tuple_field(#{{ab, 1}=>42}); + A =< 0 -> + true = has_a_field(#{a=>q, 'A' =>nej}), + true = has_a_field(#{a=>"hej", false=>true}), + true = has_a_field(#{a=>3}), + true = has_tuple_field(#{{ab, 1}=>q, 'A' =>nej}), + true = has_tuple_field(#{{ab, 1}=>"hej", false=>true}), + true = has_tuple_field(#{{ab, 1}=>3}) + end, + true = has_nil_field(#{[] =>3, b =>"seven"}), + true = has_nil_field(#{"seventeen"=>17, []=>nil}), + ok. + +has_tuple_field(#{{ab, 1}:=_}) -> true; +has_tuple_field(#{}) -> false. + +has_a_field(#{a:=_}) -> true; +has_a_field(#{}) -> false. + +has_nil_field(#{[]:=_}) -> true; +has_nil_field(#{}) -> false. -- cgit v1.2.3