mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 06:20:23 +02:00
fold constants with accessors
* module/language/tree-il/peval.scm (peval): Factor constant folding out to a helper. Use it in the accessor case in addition to the normal effect-free-primitive case. * test-suite/tests/tree-il.test: Add a test.
This commit is contained in:
parent
9be8a338ac
commit
30fcf30fcf
2 changed files with 51 additions and 30 deletions
|
@ -423,6 +423,38 @@ top-level bindings from ENV and return the resulting expression."
|
||||||
(lambda _
|
(lambda _
|
||||||
(values #f '()))))
|
(values #f '()))))
|
||||||
|
|
||||||
|
(define (make-values src values)
|
||||||
|
(match values
|
||||||
|
((single) single) ; 1 value
|
||||||
|
((_ ...) ; 0, or 2 or more values
|
||||||
|
(make-application src (make-primitive-ref src 'values)
|
||||||
|
values))))
|
||||||
|
|
||||||
|
(define (fold-constants src name args ctx)
|
||||||
|
(define (residualize-call)
|
||||||
|
(make-application src (make-primitive-ref #f name) args))
|
||||||
|
(cond
|
||||||
|
((every const? args)
|
||||||
|
(let-values (((success? values)
|
||||||
|
(apply-primitive name (map const-exp args))))
|
||||||
|
(log 'fold success? values name args)
|
||||||
|
(if success?
|
||||||
|
(case ctx
|
||||||
|
((effect) (make-void src))
|
||||||
|
((test)
|
||||||
|
;; Values truncation: only take the first
|
||||||
|
;; value.
|
||||||
|
(if (pair? values)
|
||||||
|
(make-const src (car values))
|
||||||
|
(make-values src '())))
|
||||||
|
(else
|
||||||
|
(make-values src (map (cut make-const src <>) values))))
|
||||||
|
(residualize-call))))
|
||||||
|
((and (eq? ctx 'effect) (types-check? name args))
|
||||||
|
(make-void #f))
|
||||||
|
(else
|
||||||
|
(residualize-call))))
|
||||||
|
|
||||||
(define (inline-values exp src names gensyms body)
|
(define (inline-values exp src names gensyms body)
|
||||||
(let loop ((exp exp))
|
(let loop ((exp exp))
|
||||||
(match exp
|
(match exp
|
||||||
|
@ -497,13 +529,6 @@ top-level bindings from ENV and return the resulting expression."
|
||||||
(and tail
|
(and tail
|
||||||
(make-sequence src (append head (list tail)))))))))))
|
(make-sequence src (append head (list tail)))))))))))
|
||||||
|
|
||||||
(define (make-values src values)
|
|
||||||
(match values
|
|
||||||
((single) single) ; 1 value
|
|
||||||
((_ ...) ; 0, or 2 or more values
|
|
||||||
(make-application src (make-primitive-ref src 'values)
|
|
||||||
values))))
|
|
||||||
|
|
||||||
(define (constant-expression? x)
|
(define (constant-expression? x)
|
||||||
;; Return true if X is constant---i.e., if it is known to have no
|
;; Return true if X is constant---i.e., if it is known to have no
|
||||||
;; effects, does not allocate storage for a mutable object, and does
|
;; effects, does not allocate storage for a mutable object, and does
|
||||||
|
@ -999,31 +1024,12 @@ top-level bindings from ENV and return the resulting expression."
|
||||||
(else
|
(else
|
||||||
(make-application src proc (list k (make-const #f elts))))))))
|
(make-application src proc (list k (make-const #f elts))))))))
|
||||||
((_ . args)
|
((_ . args)
|
||||||
(make-application src proc args))))
|
(or (fold-constants src name args ctx)
|
||||||
|
(make-application src proc args)))))
|
||||||
(($ <primitive-ref> _ (? effect-free-primitive? name))
|
(($ <primitive-ref> _ (? effect-free-primitive? name))
|
||||||
(let ((args (map for-value orig-args)))
|
(let ((args (map for-value orig-args)))
|
||||||
(if (every const? args) ; only simple constants
|
(or (fold-constants src name args ctx)
|
||||||
(let-values (((success? values)
|
(make-application src proc args))))
|
||||||
(apply-primitive name (map const-exp args))))
|
|
||||||
(log 'fold success? values exp)
|
|
||||||
(if success?
|
|
||||||
(case ctx
|
|
||||||
((effect) (make-void #f))
|
|
||||||
((test)
|
|
||||||
;; Values truncation: only take the first
|
|
||||||
;; value.
|
|
||||||
(if (pair? values)
|
|
||||||
(make-const #f (car values))
|
|
||||||
(make-values src '())))
|
|
||||||
(else
|
|
||||||
(make-values src (map (cut make-const src <>)
|
|
||||||
values))))
|
|
||||||
(make-application src proc args)))
|
|
||||||
(cond
|
|
||||||
((and (eq? ctx 'effect) (types-check? name args))
|
|
||||||
(make-void #f))
|
|
||||||
(else
|
|
||||||
(make-application src proc args))))))
|
|
||||||
(($ <lambda> _ _
|
(($ <lambda> _ _
|
||||||
($ <lambda-case> _ req opt #f #f inits gensyms body #f))
|
($ <lambda-case> _ req opt #f #f inits gensyms body #f))
|
||||||
;; Simple case: no rest, no keyword arguments.
|
;; Simple case: no rest, no keyword arguments.
|
||||||
|
|
|
@ -759,6 +759,21 @@
|
||||||
(loop (cdr l) (+ sum (car l)))))
|
(loop (cdr l) (+ sum (car l)))))
|
||||||
(const 10))
|
(const 10))
|
||||||
|
|
||||||
|
(pass-if-peval resolve-primitives
|
||||||
|
(let ((string->chars
|
||||||
|
(lambda (s)
|
||||||
|
(define (char-at n)
|
||||||
|
(string-ref s n))
|
||||||
|
(define (len)
|
||||||
|
(string-length s))
|
||||||
|
(let loop ((i 0))
|
||||||
|
(if (< i (len))
|
||||||
|
(cons (char-at i)
|
||||||
|
(loop (1+ i)))
|
||||||
|
'())))))
|
||||||
|
(string->chars "yo"))
|
||||||
|
(apply (primitive list) (const #\y) (const #\o)))
|
||||||
|
|
||||||
(pass-if-peval
|
(pass-if-peval
|
||||||
;; Primitives in module-refs are resolved (the expansion of `pmatch'
|
;; Primitives in module-refs are resolved (the expansion of `pmatch'
|
||||||
;; below leads to calls to (@@ (system base pmatch) car) and
|
;; below leads to calls to (@@ (system base pmatch) car) and
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue