diff options
Diffstat (limited to 'lib/compiler/src')
| -rw-r--r-- | lib/compiler/src/beam_block.erl | 15 | ||||
| -rw-r--r-- | lib/compiler/src/beam_flatten.erl | 1 | ||||
| -rw-r--r-- | lib/compiler/src/beam_jump.erl | 12 | ||||
| -rw-r--r-- | lib/compiler/src/beam_type.erl | 6 | ||||
| -rw-r--r-- | lib/compiler/src/beam_utils.erl | 6 | 
5 files changed, 33 insertions, 7 deletions
| diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl index cf5244e1ce..402fbe2e2e 100644 --- a/lib/compiler/src/beam_block.erl +++ b/lib/compiler/src/beam_block.erl @@ -123,15 +123,24 @@ is_last_bool([], _) -> false.  collect_block(Is) ->      collect_block(Is, []). +collect_block([{allocate,N,R}|Is0], Acc) -> +    {Inits,Is} = lists:splitwith(fun ({init,{y,_}}) -> true; +                                     (_) -> false +                                 end, Is0), +    collect_block(Is, [{set,[],[],{alloc,R,{nozero,N,0,Inits}}}|Acc]);  collect_block([{allocate_zero,Ns,R},{test_heap,Nh,R}|Is], Acc) -> -    collect_block(Is, [{set,[],[],{alloc,R,{no_opt,Ns,Nh,[]}}}|Acc]); +    collect_block(Is, [{set,[],[],{alloc,R,{zero,Ns,Nh,[]}}}|Acc]);  collect_block([I|Is]=Is0, Acc) ->      case collect(I) of  	error -> {reverse(Acc),Is0};  	Instr -> collect_block(Is, [Instr|Acc])      end. +collect({allocate,N,R})      -> {set,[],[],{alloc,R,{nozero,N,0,[]}}};  collect({allocate_zero,N,R}) -> {set,[],[],{alloc,R,{zero,N,0,[]}}}; +collect({allocate_heap,Ns,Nh,R}) -> {set,[],[],{alloc,R,{nozero,Ns,Nh,[]}}}; +collect({allocate_heap_zero,Ns,Nh,R}) -> {set,[],[],{alloc,R,{zero,Ns,Nh,[]}}}; +collect({init,D})            -> {set,[D],[],init};  collect({test_heap,N,R})     -> {set,[],[],{alloc,R,{nozero,nostack,N,[]}}};  collect({bif,N,F,As,D})      -> {set,[D],As,{bif,N,F}};  collect({gc_bif,N,F,R,As,D}) -> {set,[D],As,{alloc,R,{gc_bif,N,F}}}; @@ -144,6 +153,10 @@ collect({set_tuple_element,S,D,I}) -> {set,[],[S,D],{set_tuple_element,I}};  collect({get_list,S,D1,D2})  -> {set,[D1,D2],[S],get_list};  collect(remove_message)      -> {set,[],[],remove_message};  collect({'catch',R,L})       -> {set,[R],[],{'catch',L}}; +collect(fclearerror)         -> {set,[],[],fclearerror}; +collect({fcheckerror,{f,0}}) -> {set,[],[],fcheckerror}; +collect({fmove,S,D})         -> {set,[D],[S],fmove}; +collect({fconv,S,D})         -> {set,[D],[S],fconv};  collect(_)                   -> error.  %% embed_lines([Instruction]) -> [Instruction] diff --git a/lib/compiler/src/beam_flatten.erl b/lib/compiler/src/beam_flatten.erl index 25428c0c10..5603a677e8 100644 --- a/lib/compiler/src/beam_flatten.erl +++ b/lib/compiler/src/beam_flatten.erl @@ -51,6 +51,7 @@ norm_block([], Acc) -> Acc.  norm({set,[D],As,{bif,N,F}})      -> {bif,N,F,As,D};  norm({set,[D],As,{alloc,R,{gc_bif,N,F}}}) -> {gc_bif,N,F,R,As,D}; +norm({set,[D],[],init})           -> {init,D};  norm({set,[D],[S],move})          -> {move,S,D};  norm({set,[D],[S],fmove})         -> {fmove,S,D};  norm({set,[D],[S],fconv})         -> {fconv,S,D}; diff --git a/lib/compiler/src/beam_jump.erl b/lib/compiler/src/beam_jump.erl index b29a3565e4..d57fb80ac2 100644 --- a/lib/compiler/src/beam_jump.erl +++ b/lib/compiler/src/beam_jump.erl @@ -202,19 +202,19 @@ is_label(_) -> false.  move(Is) ->      move_1(Is, [], []). -move_1([I|Is], End0, Acc0) -> +move_1([I|Is], Ends, Acc0) ->      case is_exit_instruction(I) of  	false -> -	    move_1(Is, End0, [I|Acc0]); +	    move_1(Is, Ends, [I|Acc0]);  	true -> -	    case extract_seq(Acc0, [I|End0]) of +	    case extract_seq(Acc0, [I]) of  		no -> -		    move_1(Is, End0, [I|Acc0]); +		    move_1(Is, Ends, [I|Acc0]);  		{yes,End,Acc} -> -		    move_1(Is, End, Acc) +		    move_1(Is, [End|Ends], Acc)  	    end      end; -move_1([], End, Acc) -> reverse(Acc, End). +move_1([], Ends, Acc) -> reverse(Acc, lists:append(reverse(Ends))).  extract_seq([{line,_}=Line|Is], Acc) ->      extract_seq(Is, [Line|Acc]); diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl index 3ec57a67da..58c0f765ae 100644 --- a/lib/compiler/src/beam_type.erl +++ b/lib/compiler/src/beam_type.erl @@ -142,6 +142,12 @@ simplify_float(Is0, Ts0) ->  	throw:not_possible -> not_possible      end. +simplify_float_1([{set,[],[],fclearerror}|Is], Ts, Rs, Acc) -> +    simplify_float_1(Is, Ts, Rs, clearerror(Acc)); +simplify_float_1([{set,[],[],fcheckerror}|Is], Ts, Rs, Acc) -> +    simplify_float_1(Is, Ts, Rs, checkerror(Acc)); +simplify_float_1([{set,[{fr,_}],_,_}=I|Is], Ts, Rs, Acc) -> +    simplify_float_1(Is, Ts, Rs, [I|Acc]);  simplify_float_1([{set,[D0],[A0],{alloc,_,{gc_bif,'-',{f,0}}}}=I|Is]=Is0,  		 Ts0, Rs0, Acc0) ->      case tdb_find(A0, Ts0) of diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl index e9911fefd9..36f3200d11 100644 --- a/lib/compiler/src/beam_utils.erl +++ b/lib/compiler/src/beam_utils.erl @@ -759,6 +759,12 @@ live_opt([{allocate,_,Live}=I|Is], _, D, Acc) ->      live_opt(Is, live_call(Live), D, [I|Acc]);  live_opt([{allocate_heap,_,_,Live}=I|Is], _, D, Acc) ->      live_opt(Is, live_call(Live), D, [I|Acc]); +live_opt([{'%',_}=I|Is], Regs, D, Acc) -> +    live_opt(Is, Regs, D, [I|Acc]); +live_opt([{recv_set,_}=I|Is], Regs, D, Acc) -> +    live_opt(Is, Regs, D, [I|Acc]); +live_opt([{recv_mark,_}=I|Is], Regs, D, Acc) -> +    live_opt(Is, Regs, D, [I|Acc]);  live_opt([], _, _, Acc) -> Acc. | 
