From 41604a3f87290041f654728e76380d9a343e80db Mon Sep 17 00:00:00 2001 From: felix Date: Fri, 30 Aug 2019 10:09:22 +0200 Subject: [PATCH] Add some optimizer simplification rules Certain combinations of conditionals and ##core#inline operations turns out to reduce the opportunity for collapsing continuation lambdas, specifically, constructs like (if ... (let (( (##core#inline ...))) ( (##core#inline ... ...))) ( ...)) could not be optimized into a simpler form ( ... (##core#cond ...) ...) and thus not be contracted. This patch rewrites the given form (and a variation using ##core#call) into a nested ##core#inline expression, making the contraction possible. --- optimizer.scm | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/optimizer.scm b/optimizer.scm index 8017ef19..5d80ad12 100644 --- a/optimizer.scm +++ b/optimizer.scm @@ -792,7 +792,79 @@ (make-node 'if d (list (make-node '##core#inline (list op) args) - x y) ) ) ) ) ) + x y) ) ) ) ) + + ;; (let (( (##core#inline ...))) + ;; ( (##core#inline ... ...))) + ;; -> ( (##core#inline ... (##core#inline ...) + ;; ...)) + ;; - is used only once. + `((let (var) (##core#inline (op1) . args1) + (##core#call p + (##core#variable (kvar)) + (##core#inline (op2) . args2))) + (var op1 args1 p kvar op2 args2) + ,(lambda (db may-rewrite var op1 args1 p kvar op2 args2) + (and may-rewrite ; give other optimizations a chance first + (not (eq? var kvar)) + (not (db-get db kvar 'contractable)) + (= 1 (length (db-get-list db var 'references))) + (let loop ((args args2) (nargs '()) (ok #f)) + (cond ((null? args) + (and ok + (make-node + '##core#call p + (list (varnode kvar) + (make-node + '##core#inline + (list op2) + (reverse nargs)))))) + ((and (eq? '##core#variable + (node-class (car args))) + (eq? var + (car (node-parameters (car args))))) + (loop (cdr args) + (cons (make-node + '##core#inline + (list op1) + args1) + nargs) + #t)) + (else (loop (cdr args) + (cons (car args) nargs) + ok))))))) + + ;; (let (( (##core#inline ...))) + ;; ( ... ...)) + ;; -> ( ... (##core#inline ...) ...) + ;; ...)) + ;; - is used only once. + `((let (var) (##core#inline (op) . args1) + (##core#call p . args2)) + (var op args1 p args2) + ,(lambda (db may-rewrite var op args1 p args2) + (and may-rewrite ; give other optimizations a chance first + (= 1 (length (db-get-list db var 'references))) + (let loop ((args args2) (nargs '()) (ok #f)) + (cond ((null? args) + (and ok + (make-node + '##core#call p + (reverse nargs)))) + ((and (eq? '##core#variable + (node-class (car args))) + (eq? var + (car (node-parameters (car args))))) + (loop (cdr args) + (cons (make-node + '##core#inline + (list op) + args1) + nargs) + #t)) + (else (loop (cdr args) + (cons (car args) nargs) + ok)))))))) (register-simplifications -- 2.19.1