diff options
Diffstat (limited to 'lib/compiler')
-rw-r--r-- | lib/compiler/src/beam_kernel_to_ssa.erl | 61 | ||||
-rw-r--r-- | lib/compiler/src/core_lib.erl | 2 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 26 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel.erl | 72 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel.hrl | 3 | ||||
-rw-r--r-- | lib/compiler/src/v3_kernel_pp.erl | 18 |
6 files changed, 8 insertions, 174 deletions
diff --git a/lib/compiler/src/beam_kernel_to_ssa.erl b/lib/compiler/src/beam_kernel_to_ssa.erl index 1741bd806a..6b2da2fda3 100644 --- a/lib/compiler/src/beam_kernel_to_ssa.erl +++ b/lib/compiler/src/beam_kernel_to_ssa.erl @@ -123,14 +123,6 @@ cg(#k_try_enter{arg=Ta,vars=Vs,body=Tb,evars=Evs,handler=Th}, St) -> try_enter_cg(Ta, Vs, Tb, Evs, Th, St); cg(#k_catch{body=Cb,ret=[R]}, St) -> do_catch_cg(Cb, R, St); -cg(#k_receive{anno=Le,timeout=Te,var=Rvar,body=Rm,action=Tes,ret=Rs}, St) -> - recv_loop_cg(Te, Rvar, Rm, Tes, Rs, Le, St); -cg(#k_receive_next{}, #cg{recv=Recv}=St) -> - Is = [#b_set{op=recv_next},make_uncond_branch(Recv)], - {Is,St}; -cg(#k_receive_accept{}, St) -> - Remove = #b_set{op=remove_message}, - {[Remove],St}; cg(#k_put{anno=Le,arg=Con,ret=Var}, St) -> put_cg(Var, Con, Le, St); cg(#k_return{args=[Ret0]}, St) -> @@ -797,59 +789,6 @@ bif_is_record_cg(Dst, Tuple, TagVal, ArityVal, St0) -> Is = Is0 ++ [GetArity] ++ Is1 ++ [GetTag] ++ Is2 ++ Is3, {Is,St}. -%% recv_loop_cg(TimeOut, ReceiveVar, ReceiveMatch, TimeOutExprs, -%% [Ret], Le, St) -> {[Ainstr],St}. - -recv_loop_cg(Te, _Rvar, #k_receive_next{}, Tes, Rs, _Le, St0) -> - {Tl,St1} = new_label(St0), - {Bl,St2} = new_label(St1), - St3 = St2#cg{break=Bl,recv=Tl}, - {Wis,St4} = cg_recv_wait(Te, Tes, St3), - {BreakVars,St} = new_ssa_vars(Rs, St4), - {[make_uncond_branch(Tl),{label,Tl}] ++ Wis ++ - [{label,Bl},#cg_phi{vars=BreakVars}], - St#cg{break=St0#cg.break,recv=St0#cg.recv}}; -recv_loop_cg(Te, Rvar, Rm, Tes, Rs, Le, St0) -> - %% Get labels. - {Rl,St1} = new_label(St0), - {Tl,St2} = new_label(St1), - {Bl,St3} = new_label(St2), - St4 = St3#cg{break=Bl,recv=Rl}, - {Ris,St5} = cg_recv_mesg(Rvar, Rm, Tl, Le, St4), - {Wis,St6} = cg_recv_wait(Te, Tes, St5), - {BreakVars,St} = new_ssa_vars(Rs, St6), - {Ris ++ [{label,Tl}] ++ Wis ++ - [{label,Bl},#cg_phi{vars=BreakVars}], - St#cg{break=St0#cg.break,recv=St0#cg.recv}}. - -%% cg_recv_mesg( ) -> {[Ainstr],St}. - -cg_recv_mesg(#k_var{name=R}, Rm, Tl, Le, St0) -> - {Dst,St1} = new_ssa_var(R, St0), - {Mis,St2} = match_cg(Rm, none, St1), - RecvLbl = St1#cg.recv, - {TestIs,St} = make_succeeded(Dst, {guard, Tl}, St2), - Is = [#b_br{anno=line_anno(Le),bool=#b_literal{val=true}, - succ=RecvLbl,fail=RecvLbl}, - {label,RecvLbl}, - #b_set{op=peek_message,dst=Dst}|TestIs], - {Is++Mis,St}. - -%% cg_recv_wait(Te, Tes, St) -> {[Ainstr],St}. - -cg_recv_wait(#k_literal{val=0}, Es, St0) -> - {Tis,St} = cg(Es, St0), - {[#b_set{op=timeout}|Tis],St}; -cg_recv_wait(Te, Es, St0) -> - {Tis,St1} = cg(Es, St0), - Args = [ssa_arg(Te, St1)], - {WaitDst,St2} = new_ssa_var('@ssa_wait', St1), - {WaitIs,St} = make_succeeded(WaitDst, {guard, St1#cg.recv}, St2), - %% Infinite timeout will be optimized later. - Is = [#b_set{op=wait_timeout,dst=WaitDst,args=Args}] ++ WaitIs ++ - [#b_set{op=timeout}] ++ Tis, - {Is,St}. - %% try_cg(TryBlock, [BodyVar], TryBody, [ExcpVar], TryHandler, [Ret], St) -> %% {[Ainstr],St}. diff --git a/lib/compiler/src/core_lib.erl b/lib/compiler/src/core_lib.erl index c1806272bd..8073ed603c 100644 --- a/lib/compiler/src/core_lib.erl +++ b/lib/compiler/src/core_lib.erl @@ -79,8 +79,6 @@ vu_expr(V, #c_seq{arg=Arg,body=B}) -> vu_expr(V, Arg) orelse vu_expr(V, B); vu_expr(V, #c_case{arg=Arg,clauses=Cs}) -> vu_expr(V, Arg) orelse vu_clauses(V, Cs); -vu_expr(V, #c_receive{clauses=Cs,timeout=T,action=A}) -> - vu_clauses(V, Cs) orelse vu_expr(V, T) orelse vu_expr(V, A); vu_expr(V, #c_apply{op=Op,args=As}) -> vu_expr_list(V, [Op|As]); vu_expr(V, #c_call{module=M,name=N,args=As}) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 05a42348b7..47fb2cc1bf 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -392,11 +392,6 @@ expr(#c_case{}=Case0, Ctxt, Sub) -> Other -> expr(Other, Ctxt, Sub) end; -expr(#c_receive{anno=Anno,clauses=Cs0,timeout=T0,action=A0}=Recv, Ctxt, Sub) -> - Cs1 = clauses(#c_var{name='_'}, Cs0, Ctxt, Sub, false, Anno), - T1 = expr(T0, value, Sub), - A1 = body(A0, Ctxt, Sub), - Recv#c_receive{clauses=Cs1,timeout=T1,action=A1}; expr(#c_apply{anno=Anno,op=Op0,args=As0}=Apply0, _, Sub) -> Op1 = expr(Op0, value, Sub), As1 = expr_list(As0, value, Sub), @@ -541,10 +536,6 @@ ifes_1(FVar, #c_map_pair{key=Key,val=Val}, _Safe) -> ifes_1(FVar, Key, false) andalso ifes_1(FVar, Val, false); ifes_1(FVar, #c_primop{args=Args}, _Safe) -> ifes_list(FVar, Args, false); -ifes_1(FVar, #c_receive{timeout=Timeout,action=Action,clauses=Clauses}, Safe) -> - ifes_1(FVar, Timeout, false) andalso - ifes_1(FVar, Action, Safe) andalso - ifes_list(FVar, Clauses, Safe); ifes_1(FVar, #c_seq{arg=Arg,body=Body}, Safe) -> %% Arg of a #c_seq{} has no effect so it's okay to use FVar there even if %% Safe=false. @@ -1095,10 +1086,6 @@ clause_1(#c_clause{guard=G0,body=B0}=Cl, Ps1, Cexpr, Ctxt, Sub1) -> %% No need for substitution tricks when the guard %% does not contain any variables. Sub1; - {#c_var{name='_'},_,_} -> - %% In a 'receive', Cexpr is the variable '_', which represents the - %% message being matched. We must NOT do any extra substiutions. - Sub1; {#c_var{},[#c_var{}=Var],_} -> %% The idea here is to optimize expressions such as %% @@ -2603,19 +2590,6 @@ delay_build_expr_1(#c_case{clauses=Cs0}=Case, TypeSig) -> delay_build_expr_1(#c_let{body=B0}=Let, TypeSig) -> B = delay_build_expr(B0, TypeSig), Let#c_let{body=B}; -delay_build_expr_1(#c_receive{clauses=Cs0, - timeout=Timeout, - action=A0}=Rec, TypeSig) -> - Cs = delay_build_cs(Cs0, TypeSig), - A = case {Timeout,A0} of - {#c_literal{val=infinity},#c_literal{}} -> - {_Type,Arity} = TypeSig, - Es = lists:duplicate(Arity, A0), - core_lib:make_values(Es); - _ -> - delay_build_expr(A0, TypeSig) - end, - Rec#c_receive{clauses=Cs,action=A}; delay_build_expr_1(#c_seq{body=B0}=Seq, TypeSig) -> B = delay_build_expr(B0, TypeSig), Seq#c_seq{body=B}; diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index 650065f7ee..095455975f 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -82,7 +82,7 @@ keyfind/3,keyreplace/4, last/1,partition/2,reverse/1, sort/1,sort/2,splitwith/2]). --import(ordsets, [add_element/2,del_element/2,intersection/2, +-import(ordsets, [add_element/2,intersection/2, subtract/2,union/2,union/1]). -include("core_parse.hrl"). @@ -105,8 +105,6 @@ copy_anno(Kdst, Ksrc) -> -record(iletrec, {anno=[],defs}). -record(ialias, {anno=[],vars,pat}). -record(iclause, {anno=[],isub,osub,pats,guard,body}). --record(ireceive_accept, {anno=[],arg}). --record(ireceive_next, {anno=[],arg}). -type warning() :: term(). % XXX: REFINE @@ -184,8 +182,6 @@ body(#c_values{anno=A,es=Ces}, Sub, St0) -> %% Do this here even if only in bodies. {Kes,Pe,St1} = atomic_list(Ces, Sub, St0), {#ivalues{anno=A,args=Kes},Pe,St1}; -body(#ireceive_next{anno=A}, _, St) -> - {#k_receive_next{anno=A},[],St}; body(Ce, Sub, St0) -> expr(Ce, Sub, St0). @@ -326,22 +322,6 @@ expr(#c_case{arg=Ca,clauses=Ccs}, Sub, St0) -> {Km,St3} = kmatch(Kvs, Ccs, Sub, St2), Match = flatten_seq(build_match(Km)), {last(Match),Pa ++ Pv ++ droplast(Match),St3}; -expr(#c_receive{anno=A,clauses=Ccs0,timeout=Ce,action=Ca}, Sub, St0) -> - {Ke,Pe,St1} = atomic(Ce, Sub, St0), %Force this to be atomic! - {Rvar,St2} = new_var(St1), - %% Need to massage accept clauses and add reject clause before matching. - Ccs1 = map(fun (#c_clause{anno=Banno,body=B0}=C) -> - B1 = #c_seq{arg=#ireceive_accept{anno=A},body=B0}, - C#c_clause{anno=Banno,body=B1} - end, Ccs0), - {Mpat,St3} = new_var_name(St2), - Rc = #c_clause{anno=[compiler_generated|A], - pats=[#c_var{name=Mpat}],guard=#c_literal{anno=A,val=true}, - body=#ireceive_next{anno=A}}, - {Km,St4} = kmatch([Rvar], Ccs1 ++ [Rc], Sub, add_var_def(Rvar, St3)), - {Ka,Pa,St5} = body(Ca, Sub, St4), - {#k_receive{anno=A,var=Rvar,body=Km,timeout=Ke,action=pre_seq(Pa, Ka)}, - Pe,St5}; expr(#c_apply{anno=A,op=Cop,args=Cargs}, Sub, St) -> c_apply(A, Cop, Cargs, Sub, St); expr(#c_call{anno=A,module=M0,name=F0,args=Cargs}, Sub, St0) -> @@ -382,9 +362,7 @@ expr(#c_try{anno=A,arg=Ca,vars=Cvs,body=Cb,evars=Evs,handler=Ch}, Sub0, St0) -> evars=Kevs,handler=pre_seq(Ph, Kh)},[],St5}; expr(#c_catch{anno=A,body=Cb}, Sub, St0) -> {Kb,Pb,St1} = body(Cb, Sub, St0), - {#k_catch{anno=A,body=pre_seq(Pb, Kb)},[],St1}; -%% Handle internal expressions. -expr(#ireceive_accept{anno=A}, _Sub, St) -> {#k_receive_accept{anno=A},[],St}. + {#k_catch{anno=A,body=pre_seq(Pb, Kb)},[],St1}. %% Implement letrec in the traditional way as a local %% function for each definition in the letrec. @@ -950,9 +928,6 @@ new_vars(0, St, Vs) -> {Vs,St}. make_vars(Vs) -> [ #k_var{name=V} || V <- Vs ]. -add_var_def(V, St) -> - St#kern{ds=cerl_sets:add_element(V#k_var.name, St#kern.ds)}. - %% is_remote_bif(Mod, Name, Arity) -> true | false. %% Test if function is really a BIF. @@ -1843,24 +1818,13 @@ ubody(E, return, St0) -> ubody(pre_seq(Pa, #ivalues{args=[Ea]}), return, St1) end; ubody(E, {break,[_]} = Break, St0) -> - %%ok = io:fwrite("ubody ~w:~p~n", [?LINE,{E,Br}]), - %% Exiting expressions need no trailing break. - case is_exit_expr(E) of - true -> uexpr(E, return, St0); - false -> - {Ea,Pa,St1} = force_atomic(E, St0), - ubody(pre_seq(Pa, #ivalues{args=[Ea]}), Break, St1) - end; + {Ea,Pa,St1} = force_atomic(E, St0), + ubody(pre_seq(Pa, #ivalues{args=[Ea]}), Break, St1); ubody(E, {break,Rs}=Break, St0) -> - case is_exit_expr(E) of - true -> - uexpr(E, return, St0); - false -> - {Vs,St1} = new_vars(length(Rs), St0), - Iset = #iset{vars=Vs,arg=E}, - PreSeq = pre_seq([Iset], #ivalues{args=Vs}), - ubody(PreSeq, Break, St1) - end. + {Vs,St1} = new_vars(length(Rs), St0), + Iset = #iset{vars=Vs,arg=E}, + PreSeq = pre_seq([Iset], #ivalues{args=Vs}), + ubody(PreSeq, Break, St1). iletrec_funs(#iletrec{defs=Fs}, St0) -> %% Use union of all free variables. @@ -1893,12 +1857,6 @@ iletrec_funs_gen(Fs, FreeVs, St) -> end, St, Fs). -%% is_exit_expr(Kexpr) -> boolean(). -%% Test whether Kexpr always exits and never returns. - -is_exit_expr(#k_receive_next{}) -> true; -is_exit_expr(_) -> false. - %% is_enter_expr(Kexpr) -> boolean(). %% Test whether Kexpr is "enterable", i.e. can handle return from %% within itself without extra #k_return{}. @@ -1906,8 +1864,6 @@ is_exit_expr(_) -> false. is_enter_expr(#k_try{}) -> true; is_enter_expr(#k_call{}) -> true; is_enter_expr(#k_match{}) -> true; -is_enter_expr(#k_receive{}) -> true; -is_enter_expr(#k_receive_next{}) -> true; is_enter_expr(#k_letrec_goto{}) -> true; is_enter_expr(_) -> false. @@ -1953,18 +1909,6 @@ uexpr(#k_match{anno=A,body=B0}, Br, St0) -> Rs = break_rets(Br), {B1,Bu,St1} = umatch(B0, Br, St0), {#k_match{anno=A,body=B1,ret=Rs},Bu,St1}; -uexpr(#k_receive{anno=A,var=V,body=B0,timeout=T,action=A0}, Br, St0) -> - Rs = break_rets(Br), - Tu = lit_vars(T), %Timeout is atomic - {B1,Bu,St1} = umatch(B0, Br, St0), - {A1,Au,St2} = ubody(A0, Br, St1), - Used = del_element(V#k_var.name, union(Bu, union(Tu, Au))), - {#k_receive{anno=A,var=V,body=B1,timeout=T,action=A1,ret=Rs}, - Used,St2}; -uexpr(#k_receive_accept{anno=A}, _, St) -> - {#k_receive_accept{anno=A},[],St}; -uexpr(#k_receive_next{anno=A}, _, St) -> - {#k_receive_next{anno=A},[],St}; uexpr(#k_try{anno=A,arg=A0,vars=Vs,body=B0,evars=Evs,handler=H0}, {break,Rs0}=Br, St0) -> case {Vs,B0,H0,Rs0} of diff --git a/lib/compiler/src/v3_kernel.hrl b/lib/compiler/src/v3_kernel.hrl index e8336a8f26..582e4f9b12 100644 --- a/lib/compiler/src/v3_kernel.hrl +++ b/lib/compiler/src/v3_kernel.hrl @@ -52,9 +52,6 @@ -record(k_test, {anno=[],op,args}). -record(k_call, {anno=[],op,args,ret=[]}). -record(k_enter, {anno=[],op,args}). --record(k_receive, {anno=[],var,body,timeout,action,ret=[]}). --record(k_receive_accept, {anno=[]}). --record(k_receive_next, {anno=[]}). -record(k_try, {anno=[],arg,vars,body,evars,handler,ret=[]}). -record(k_try_enter, {anno=[],arg,vars,body,evars,handler}). -record(k_catch, {anno=[],body,ret=[]}). diff --git a/lib/compiler/src/v3_kernel_pp.erl b/lib/compiler/src/v3_kernel_pp.erl index aeddd13472..f7479e6b15 100644 --- a/lib/compiler/src/v3_kernel_pp.erl +++ b/lib/compiler/src/v3_kernel_pp.erl @@ -289,24 +289,6 @@ format_1(#k_catch{body=B,ret=Rs}, Ctxt) -> "end", format_ret(Rs, Ctxt1) ]; -format_1(#k_receive{var=V,body=B,timeout=T,action=A,ret=Rs}, Ctxt) -> - Ctxt1 = ctxt_bump_indent(Ctxt, Ctxt#ctxt.item_indent), - ["receive ", - format(V, Ctxt), - nl_indent(Ctxt1), - format(B, Ctxt1), - nl_indent(Ctxt), - "after ", - format(T, ctxt_bump_indent(Ctxt, 6)), - " ->", - nl_indent(Ctxt1), - format(A, Ctxt1), - nl_indent(Ctxt), - "end", - format_ret(Rs, Ctxt1) - ]; -format_1(#k_receive_accept{}, _Ctxt) -> "receive_accept"; -format_1(#k_receive_next{}, _Ctxt) -> "receive_next"; format_1(#k_break{args=As}, Ctxt) -> ["<", format_hseq(As, ",", ctxt_bump_indent(Ctxt, 1), fun format/2), |