diff options
author | Björn Gustavsson <[email protected]> | 2014-02-12 14:52:44 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2014-02-12 14:52:44 +0100 |
commit | 152f1a4ba2f4e2f0dfbcde2efe5b5fd5edbdb986 (patch) | |
tree | bbd2547b06badbf7537ca966707f1367fb7d0b3f /lib/compiler/src | |
parent | ce1e2d3e865c42b01c8088ee07470a6f25be55cb (diff) | |
parent | c89ada7517420ce9065840ea857a0009418ce2af (diff) | |
download | otp-152f1a4ba2f4e2f0dfbcde2efe5b5fd5edbdb986.tar.gz otp-152f1a4ba2f4e2f0dfbcde2efe5b5fd5edbdb986.tar.bz2 otp-152f1a4ba2f4e2f0dfbcde2efe5b5fd5edbdb986.zip |
Merge branch 'bjorn/compiler/optimizations/OTP-11584'
* bjorn/compiler/optimizations/OTP-11584:
Teach sys_core_fold:eval_case/2 to cope with handwritten Core Erlang
sys_core_fold: Remove a redundant word in a comment
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index e302e2324d..500d431afe 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -1940,7 +1940,9 @@ opt_bool_case_guard(Arg, [#c_clause{pats=[#c_literal{val=false}]}=Fc,Tc]) -> %% last clause is guaranteed to match so if there is only one clause %% with a pattern containing only variables then rewrite to a let. -eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,body=B}]}, Sub) -> +eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0, + guard=#c_literal{val=true}, + body=B}]}=Case, Sub) -> Es = case cerl:is_c_values(E) of true -> cerl:values_es(E); false -> [E] @@ -1955,7 +1957,7 @@ eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,body=B}]}, Sub) -> %% %% let <X,Y> = <SomeSideEffect(),SomeSideEffect()> in ... %% - %% because SomeSideEffect() would be called evaluated twice. + %% because SomeSideEffect() would be evaluated twice. %% %% Instead we must evaluate the case expression in an outer let %% like this: @@ -1964,11 +1966,19 @@ eval_case(#c_case{arg=E,clauses=[#c_clause{pats=Ps0,body=B}]}, Sub) -> %% let <X,Y> = <NewVar,NewVar> in ... %% Vs = make_vars([], length(Es)), - {true,Bs} = cerl_clauses:match_list(Ps0, Vs), - {Ps,As} = unzip(Bs), - InnerLet = cerl:c_let(Ps, core_lib:make_values(As), B), - Let = cerl:c_let(Vs, E, InnerLet), - expr(Let, sub_new(Sub)); + case cerl_clauses:match_list(Ps0, Vs) of + {false,_} -> + %% This can only happen if the Core Erlang code is + %% handwritten or generated by another code generator + %% than v3_core. Assuming that the Core Erlang program + %% is correct, the clause will always match at run-time. + Case; + {true,Bs} -> + {Ps,As} = unzip(Bs), + InnerLet = cerl:c_let(Ps, core_lib:make_values(As), B), + Let = cerl:c_let(Vs, E, InnerLet), + expr(Let, sub_new(Sub)) + end; eval_case(Case, _) -> Case. %% case_opt(CaseArg, [Clause]) -> {CaseArg,[Clause]}. |