diff options
author | Björn Gustavsson <[email protected]> | 2017-12-11 22:00:24 +0100 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2017-12-15 12:31:29 +0100 |
commit | b89044a800c4950072b14d5e372cb2db55f1966c (patch) | |
tree | 07787239d192171ead8b1521e343c5cae0d5811e /lib/kernel/doc | |
parent | cd708cf3cd5ea4402ea8cec2d9570506b7bf8e92 (diff) | |
download | otp-b89044a800c4950072b14d5e372cb2db55f1966c.tar.gz otp-b89044a800c4950072b14d5e372cb2db55f1966c.tar.bz2 otp-b89044a800c4950072b14d5e372cb2db55f1966c.zip |
v3_codegen: Delay creation of stack frames
v3_codegen currently wraps a stack frame around each clause in
a function (unless the clause is simple without any 'case' or
other complex constructions).
Consider this function:
f({a,X}) ->
A = abs(X),
case A of
0 ->
{result,"0"};
_ ->
{result,integer_to_list(A)}
end;
f(_) ->
error.
The first clause needs a stack frame because there is a function
call to integer_to_list/1 not in the tail position. v3_codegen
currently wraps the entire first clause in stack frame.
We can delay the creation of the stack frame, and create a
stack frame in each arm of the 'case' (if needed):
f({a,X}) ->
A = abs(X),
case A of
0 ->
%% Don't create a stack frame here.
{result,"0"};
_ ->
%% Create a stack frame here.
{result,integer_to_list(A)}
end;
f(_) ->
error.
There are pros and cons of this approach.
The cons are that the code size may increase if there are many
'case' clauses and each needs its own stack frame. The allocation
instructions may also interfere with other optimizations, but
the new optimizations introduced in previous commits will mitigate
most of those issues.
The pros are the following:
* For some clauses in a 'case', there is no need to create any
stack frame at all.
* Often when moving an allocation instruction into a 'case' clause,
the slightly cheaper 'allocate' instruction can be used instead
of 'allocate_zero'. There is also the possibility that the
allocate instruction can be be combined with a 'test_heap'
instruction.
* Each stack frame for each arm of the 'case' will have exactly as
many slots as needed.
Diffstat (limited to 'lib/kernel/doc')
0 files changed, 0 insertions, 0 deletions