aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2018-01-04 20:07:09 +0100
committerBjörn Gustavsson <[email protected]>2018-01-10 11:39:31 +0100
commit161e67441cca56419fea70edf3ea790aff0f7b32 (patch)
tree30b4f8ec3f95469c393e05a1b467d4248db2345c
parenteb5399aa43a9c5dac82f4d102e8dd8dd5b27a9f8 (diff)
downloadotp-161e67441cca56419fea70edf3ea790aff0f7b32.tar.gz
otp-161e67441cca56419fea70edf3ea790aff0f7b32.tar.bz2
otp-161e67441cca56419fea70edf3ea790aff0f7b32.zip
beam_type: Enhance coalescing of allocation instructions
An 'allocate' or 'allocate_zero' instruction should not be shortly followed by a 'test_heap' instruction. For example, we don't want this type of code: {allocate_zero,3,4}. {line,...}. {test_heap,7,4}. {bif,element,{f,0},...,...}. While the code is safe because 'allocate_zero' has initialized the stack frame, it is wasteful. Also note that the code would become unsafe if the 'allocate_zero' instruction were to be replaced with an 'allocate' instruction. What we want to see is this: {allocate_heap_zero,3,7,4}. {line,...}. {bif,element,{f,0},...,...}.
-rw-r--r--lib/compiler/src/beam_type.erl30
1 files changed, 9 insertions, 21 deletions
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index d1f1076e17..e8cca4a0c0 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -333,29 +333,17 @@ flt_need_heap_2({set,_,_,{put_tuple,_}}, H, Fl) ->
{[],H+1,Fl};
flt_need_heap_2({set,_,_,put}, H, Fl) ->
{[],H+1,Fl};
-%% Then the "neutral" instructions. We just pass them.
-flt_need_heap_2({set,[{fr,_}],_,_}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,[],[],fclearerror}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,[],[],fcheckerror}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,{bif,_,_}}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,move}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,{get_tuple_element,_}}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,get_list}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,{try_catch,_,_}}, H, Fl) ->
- {[],H,Fl};
-flt_need_heap_2({set,_,_,init}, H, Fl) ->
- {[],H,Fl};
-%% All other instructions should cause the insertion of an allocation
+%% The following instructions cause the insertion of an allocation
%% instruction if needed.
+flt_need_heap_2({set,_,_,{alloc,_,_}}, H, Fl) ->
+ {flt_alloc(H, Fl),0,0};
+flt_need_heap_2({set,_,_,{set_tuple_element,_}}, H, Fl) ->
+ {flt_alloc(H, Fl),0,0};
+flt_need_heap_2({'%live',_,_}, H, Fl) ->
+ {flt_alloc(H, Fl),0,0};
+%% All other instructions are "neutral". We just pass them.
flt_need_heap_2(_, H, Fl) ->
- {flt_alloc(H, Fl),0,0}.
+ {[],H,Fl}.
flt_alloc(0, 0) ->
[];