--- beam_bsm.erl.orig 2008-08-21 12:22:09.945529616 -0400 +++ beam_bsm.erl 2008-08-21 12:22:09.917526638 -0400 @@ -63,6 +63,7 @@ {f, %Gbtrees for all functions. index, %{Label,Code} index (for liveness). ok_br, %Labels that are OK. + must_not_save, %Must not save position when optimizing (reaches bs_context_to_binary) need_save %Must save position when optmizing. }). @@ -158,9 +159,12 @@ btb_reaches_match(Is, RegList, D0) -> try Regs = btb_regs_from_list(RegList), - D = D0#btb{ok_br=gb_sets:empty(),need_save=false}, - #btb{need_save=NeedSave} = btb_reaches_match_1(Is, Regs, D), - {ok,NeedSave} + D = D0#btb{ok_br=gb_sets:empty(),must_not_save=false,need_save=false}, + #btb{must_not_save=MustNotSave,need_save=NeedSave} = btb_reaches_match_1(Is, Regs, D), + case MustNotSave and NeedSave of + true -> btb_error(must_and_must_not_save); + _ -> {ok,NeedSave} + end catch throw:{error,_}=Error -> Error end. @@ -313,7 +317,7 @@ CtxRegs = btb_context_regs(Regs), case btb_are_all_killed(CtxRegs, Is, D) of false -> btb_error({CtxRegs,not_all_killed_after,I}); - true -> D + true -> D#btb{must_not_save=true} end end; btb_reaches_match_2([{badmatch,Src}=I|_], Regs, D) -> @@ -400,10 +404,10 @@ false -> %% New branch. Try it. Is = fetch_code_at(Lbl, Li), - #btb{ok_br=Br} = btb_reaches_match_1(Is, Regs, D), + #btb{ok_br=Br,must_not_save=MustNotSave,need_save=NeedSave} = btb_reaches_match_1(Is, Regs, D), %% Since we got back, this branch is OK. - D#btb{ok_br=gb_sets:insert(Lbl, Br)} + D#btb{ok_br=gb_sets:insert(Lbl, Br),must_not_save=MustNotSave,need_save=NeedSave} end. btb_reaches_match_block([{set,Ds,Ss,{alloc,Live,_}}=I|Is], Regs0) -> @@ -526,7 +530,7 @@ btb_context_regs_1(Regs, N, Tag, Acc) -> btb_context_regs_1(Regs bsr 1, N+1, Tag, Acc). -%% btb_index([Function]) -> GbTree({EntryLabel,{Register,NumberOfSlots}}) +%% btb_index([Function]) -> GbTree({EntryLabel,{Register,NumberOfSlots,MustNotSave,NeedsSave}}) %% Build an index of functions that accept a match context instead of %% a binary.