diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-04-24 20:40:06 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-04-24 20:40:06 -0700 |
commit | 21a45056fa32e12621da420e207f326060e8ca66 (patch) | |
tree | 4c377efd5825883f0164adbbbcc27a6b3d1b3086 /vm.c | |
parent | d9b04547bc08dfa2db6fa0574a85dc14e47a8d90 (diff) | |
download | txr-21a45056fa32e12621da420e207f326060e8ca66.tar.gz txr-21a45056fa32e12621da420e207f326060e8ca66.tar.bz2 txr-21a45056fa32e12621da420e207f326060e8ca66.zip |
compiler: implement eliding of blocks.
It is time-wasting to have a block in every function. In this
patch we have the compiler eliminate blocks if it is obvious
that they will not be the targets of any exits or continuation
captures through any direct function calls.
If a block contains only calls to library functions,
and doesn't call certain functions, then it is removed.
It is possible for this removal to be strictly wrong
and different from interpreted code. This is true if
the code enclosed in a block invokes a function indirectly or
via a quoted symbol, and that function tries to return from
the block or capture a continuation using that block as
a prompt. Such a call doesn't prevent the block from being
removed.
For instance, this won't work in compiled code
any more:
(defun tricky (fun)
(call fun))
(tricky (lambda () (return-from tricky 42)))
The call function is considered safe; the (call fun)
form doesn't prevent the block inside the tricky
function from being removed.
* share/txr/stdlib/compiler.tl (blockinfo): New struct.
(env): New slot, bb.
(env lookup-block, env extend-block): New methods.
(%block-using-funs%): New global variable.
(compiler comp-block): Implement the elision of the block
based on what free functions are referenced in the body,
and whether the block is referenced lexically.
Also, bind the block in the environment using the bb
member in the env structure.
(comp-return-from): Lookup the block lexically and
mark it as used.
(system-symbol-p): New function.
* txr.1: Document the rules for elision of blocks.
Diffstat (limited to 'vm.c')
0 files changed, 0 insertions, 0 deletions