diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2024-02-08 20:34:34 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2024-02-08 20:34:34 -0800 |
commit | 82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f (patch) | |
tree | ead36810f728ba9a7c666fec22003751a537f069 /stdlib | |
parent | ed5672b77f5a2980872eca073608cb7bde4587e4 (diff) | |
download | txr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.tar.gz txr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.tar.bz2 txr-82cfcfdd91fb1cd8356fd6aaa537d329ecc3b78f.zip |
compiler: inlined chain: simplify variadic lambdas.
The opip syntax often generates lambdas that have a trailing
parameter and use [sys:apply ...]. This is wasteful in the
second and subsequent argument positions of a chain, because we
know that only a single value is coming from the previous
function. We can pattern match these lambdas and convert
the trailing argument to a single fixed parameter.
* stdlib/compiler.tl (simplify-variadic-lambda): New function.
(inline-chain-rec): Try to simplify every function through
simplify-variadic-lambda. The leftmost function is treated in
inline-chain, so these are all second and subsequent
functions.
Diffstat (limited to 'stdlib')
-rw-r--r-- | stdlib/compiler.tl | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/stdlib/compiler.tl b/stdlib/compiler.tl index 00dbd292..e722cf41 100644 --- a/stdlib/compiler.tl +++ b/stdlib/compiler.tl @@ -2303,12 +2303,25 @@ ,*lm-body)) lm-expr))))) +(defun simplify-variadic-lambda (form) + (if-match @(require (lambda @(and @params @(or @(end (@nil . @rest)) + @rest)) + [sys:apply . @args]) + rest + (eq 1 (count rest (flatten args))) + (eq [args -1] rest)) + form + ^(lambda (,*(butlastn 0 params) ,rest) + [call ,*(butlastn 1 args) ,rest]) + form)) + (defun inline-chain-rec (form arg) (match-ecase form ((chain @fun) - ^(call ,fun ,arg)) + ^(call ,(simplify-variadic-lambda fun) ,arg)) ((chain @fun . @rest) - (inline-chain-rec ^(chain ,*rest) ^(call ,fun ,arg))))) + (inline-chain-rec ^(chain ,*rest) + ^(call ,(simplify-variadic-lambda fun) ,arg))))) (defun can-inline-chain (form) (let (yes) |