diff options
author | Björn Gustavsson <[email protected]> | 2013-12-18 10:08:37 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2013-12-18 10:08:37 +0100 |
commit | 39de9391f76ed8f3503869684726d18d0fe723c3 (patch) | |
tree | 3475105fc750a023be6a879070ed13705c98bd40 | |
parent | 165846b143c8275350972caaf4c1013cfe5db043 (diff) | |
parent | 20c38f0156b711032274cdea5a5049fc7ce8e81f (diff) | |
download | otp-39de9391f76ed8f3503869684726d18d0fe723c3.tar.gz otp-39de9391f76ed8f3503869684726d18d0fe723c3.tar.bz2 otp-39de9391f76ed8f3503869684726d18d0fe723c3.zip |
Merge branch 'nox/asm-reentrant/OTP-11544'
* nox/asm-reentrant/OTP-11544:
Test compilation of BEAM assembly with optimisations on
Keep exit blocks in order when moving them in beam_jump
Add missing recv_set, recv_mark and '%' to BEAM live annotation
Collect all optimised allocate instructions in beam_block
Properly collect allocate_zero instructions in beam_block
Properly let floating-point instructions through in the BEAM compiler
-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 | ||||
-rw-r--r-- | lib/compiler/test/compilation_SUITE.erl | 10 | ||||
-rw-r--r-- | lib/compiler/test/compile_SUITE.erl | 2 |
7 files changed, 44 insertions, 8 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. diff --git a/lib/compiler/test/compilation_SUITE.erl b/lib/compiler/test/compilation_SUITE.erl index d517029b1b..93b2fb4ea5 100644 --- a/lib/compiler/test/compilation_SUITE.erl +++ b/lib/compiler/test/compilation_SUITE.erl @@ -278,6 +278,16 @@ try_it(StartNode, Module, Conf) -> ?line ok = rpc:call(Node, ?MODULE, load_and_call, [Out, Module]), ?line test_server:timetrap_cancel(LastDog), + AsmDog = test_server:timetrap(test_server:minutes(10)), + io:format("Compiling (from assembly): ~s\n", [Src]), + {ok,_} = compile:file(Src, [to_asm,{outdir,Out},report|OtherOpts]), + Asm = filename:join(Out, lists:concat([Module, ".S"])), + CompRc3 = compile:file(Asm, [from_asm,{outdir,Out},report|OtherOpts]), + io:format("Result: ~p\n",[CompRc3]), + {ok,_} = CompRc3, + ok = rpc:call(Node, ?MODULE, load_and_call, [Out, Module]), + test_server:timetrap_cancel(AsmDog), + case StartNode of false -> ok; true -> ?line test_server:stop_node(Node) diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl index 66ce6c00ab..1dc1ddb653 100644 --- a/lib/compiler/test/compile_SUITE.erl +++ b/lib/compiler/test/compile_SUITE.erl @@ -794,7 +794,7 @@ do_asm(Beam, Outdir) -> {ok,Fd} = file:open(AsmFile, [write,{encoding,utf8}]), beam_listing:module(Fd, Asm), ok = file:close(Fd), - case compile:file(AsmFile, [from_asm,no_postopt,binary,report]) of + case compile:file(AsmFile, [from_asm,binary,report]) of {ok,M,_} -> ok = file:delete(AsmFile); Other -> |