aboutsummaryrefslogtreecommitdiffstats
path: root/lib/compiler/src/beam_utils.erl
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-12-11 22:00:24 +0100
committerBjörn Gustavsson <[email protected]>2017-12-15 12:31:29 +0100
commitb89044a800c4950072b14d5e372cb2db55f1966c (patch)
tree07787239d192171ead8b1521e343c5cae0d5811e /lib/compiler/src/beam_utils.erl
parentcd708cf3cd5ea4402ea8cec2d9570506b7bf8e92 (diff)
downloadotp-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/compiler/src/beam_utils.erl')
0 files changed, 0 insertions, 0 deletions