1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-28 16:00:22 +02:00

peval uses effects analysis

* module/language/tree-il/peval.scm: Use effects analysis from (language
  tree-il effects) instead of our own constant-expression?.  Eagerly
  mark assigned lexicals as non-copyable.
This commit is contained in:
Andy Wingo 2012-04-12 16:46:18 -07:00
parent da9b2b71f7
commit a36e7870c3

View file

@ -19,6 +19,7 @@
(define-module (language tree-il peval)
#:use-module (language tree-il)
#:use-module (language tree-il primitives)
#:use-module (language tree-il effects)
#:use-module (ice-9 vlist)
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
@ -301,12 +302,13 @@
(constant-value operand-constant-value set-operand-constant-value!))
(define* (make-operand var sym #:optional source visit)
;; Bind SYM to VAR, with value SOURCE. Bound operands are considered
;; copyable until we prove otherwise. If we have a source expression,
;; truncate it to one value. Copy propagation does not work on
;; multiply-valued expressions.
;; Bind SYM to VAR, with value SOURCE. Unassigned bound operands are
;; considered copyable until we prove otherwise. If we have a source
;; expression, truncate it to one value. Copy propagation does not
;; work on multiply-valued expressions.
(let ((source (and=> source truncate-values)))
(%make-operand var sym visit source 0 #f (and source #t) #f #f)))
(%make-operand var sym visit source 0 #f
(and source (not (var-set? var))) #f #f)))
(define (make-bound-operands vars syms sources visit)
(map (lambda (x y z) (make-operand x y z visit)) vars syms sources))
@ -566,51 +568,15 @@ top-level bindings from ENV and return the resulting expression."
(and tail
(make-sequence src (append head (list tail)))))))))))
(define compute-effects
(make-effects-analyzer assigned-lexical?))
(define (constant-expression? x)
;; Return true if X is constant, for the purposes of copying or
;; elision---i.e., if it is known to have no effects, does not
;; allocate storage for a mutable object, and does not access
;; mutable data (like `car' or toplevel references).
(let loop ((x x))
(match x
(($ <void>) #t)
(($ <const>) #t)
(($ <lambda>) #t)
(($ <lambda-case> _ req opt rest kw inits syms body alternate)
(and (not (any assigned-lexical? syms))
(every loop inits) (loop body)
(or (not alternate) (loop alternate))))
(($ <lexical-ref> _ _ gensym)
(not (assigned-lexical? gensym)))
(($ <primitive-ref>) #t)
(($ <conditional> _ condition subsequent alternate)
(and (loop condition) (loop subsequent) (loop alternate)))
(($ <application> _ ($ <primitive-ref> _ 'values) exps)
(and (not (null? exps))
(every loop exps)))
(($ <application> _ ($ <primitive-ref> _ name) args)
(and (effect-free-primitive? name)
(not (constructor-primitive? name))
(not (accessor-primitive? name))
(types-check? name args)
(every loop args)))
(($ <application> _ ($ <lambda> _ _ body) args)
(and (loop body) (every loop args)))
(($ <sequence> _ exps)
(every loop exps))
(($ <let> _ _ syms vals body)
(and (not (any assigned-lexical? syms))
(every loop vals) (loop body)))
(($ <letrec> _ _ _ syms vals body)
(and (not (any assigned-lexical? syms))
(every loop vals) (loop body)))
(($ <fix> _ _ _ vals body)
(and (every loop vals) (loop body)))
(($ <let-values> _ exp body)
(and (loop exp) (loop body)))
(($ <prompt> _ tag body handler)
(and (loop tag) (loop body) (loop handler)))
(_ #f))))
(constant? (compute-effects x)))
(define (prune-bindings ops in-order? body counter ctx build-result)
;; This helper handles both `let' and `letrec'/`fix'. In the latter
@ -985,14 +951,20 @@ top-level bindings from ENV and return the resulting expression."
((test) (make-const #f #t))
(else exp)))
(($ <conditional> src condition subsequent alternate)
(let ((condition (for-test condition)))
(if (const? condition)
(if (const-exp condition)
(for-tail subsequent)
(for-tail alternate))
(make-conditional src condition
(for-tail subsequent)
(for-tail alternate)))))
(match (for-test condition)
(($ <const> _ val)
(if val
(for-tail subsequent)
(for-tail alternate)))
;; Swap the arms of (if (not FOO) A B), to simplify.
(($ <application> _ ($ <primitive-ref> _ 'not) (c))
(make-conditional src c
(for-tail alternate)
(for-tail subsequent)))
(c
(make-conditional src c
(for-tail subsequent)
(for-tail alternate)))))
(($ <application> src
($ <primitive-ref> _ '@call-with-values)
(producer