1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-09 13:30:26 +02:00

peval: better primcall folding in effect contexts

* module/language/tree-il/peval.scm (peval): If a primcall is
effect-free, don't require that its args are too: just revisit args as a
sequence in effect context.
* module/language/tree-il/effects.scm (effect-free-primcall?): New
exported function.
This commit is contained in:
Andy Wingo 2023-11-15 19:30:09 +01:00
parent 28a428135f
commit c2a9380a42
2 changed files with 32 additions and 10 deletions

View file

@ -36,7 +36,8 @@
constant? constant?
depends-on-effects? depends-on-effects?
causes-effects? causes-effects?
add-primcall-effect-analyzer!)) add-primcall-effect-analyzer!
effect-free-primcall?))
;;; ;;;
;;; Hey, it's some effects analysis! If you invoke ;;; Hey, it's some effects analysis! If you invoke
@ -238,6 +239,31 @@
(define (primcall-effect-analyzer name) (define (primcall-effect-analyzer name)
(hashq-ref *primcall-effect-analyzers* name)) (hashq-ref *primcall-effect-analyzers* name))
(define (effect-free-primcall? name args)
"Return #f unless a primcall of @var{name} with @var{args} can be
replaced with @code{(begin . @var{args})} in an effect context."
(match (cons name args)
((or ('values . _)
('list . _)
('vector . _)
('eq? _ _)
('eqv? _ _)
('cons* _ . _)
('acons _ _ _)
((or 'not
'pair? 'null? 'nil? 'list?
'symbol? 'variable? 'vector? 'struct? 'string?
'number? 'char? 'eof-object? 'exact-integer?
'bytevector? 'keyword? 'bitvector?
'procedure? 'thunk? 'atomic-box?
'vector 'make-variable)
_))
#t)
(_
(match (primcall-effect-analyzer name)
(#f #f)
(effect-free? (effect-free? args))))))
(define (make-effects-analyzer assigned-lexical?) (define (make-effects-analyzer assigned-lexical?)
"Returns a procedure of type EXP -> EFFECTS that analyzes the effects "Returns a procedure of type EXP -> EFFECTS that analyzes the effects
of an expression." of an expression."

View file

@ -683,11 +683,6 @@ top-level bindings from ENV and return the resulting expression."
;; mutable data (like `car' or toplevel references). ;; mutable data (like `car' or toplevel references).
(constant? (compute-effects x))) (constant? (compute-effects x)))
(define (can-elide-statement? stmt)
(let ((effects (compute-effects stmt)))
(effect-free?
(exclude-effects effects (logior &allocation &zero-values)))))
(define (prune-bindings ops in-order? body counter ctx build-result) (define (prune-bindings ops in-order? body counter ctx build-result)
;; This helper handles both `let' and `letrec'/`fix'. In the latter ;; This helper handles both `let' and `letrec'/`fix'. In the latter
;; cases we need to make sure that if referenced binding A needs ;; cases we need to make sure that if referenced binding A needs
@ -1525,10 +1520,11 @@ top-level bindings from ENV and return the resulting expression."
(fold-constants src name args ctx)) (fold-constants src name args ctx))
((name . args) ((name . args)
(let ((exp (make-primcall src name args))) (if (and (eq? ctx 'effect) (effect-free-primcall? name args))
(if (and (eq? ctx 'effect) (can-elide-statement? exp)) (if (null? args)
(make-void src) (make-void src)
exp))))) (for-tail (list->seq src args)))
(make-primcall src name args)))))
(($ <call> src orig-proc orig-args) (($ <call> src orig-proc orig-args)
;; todo: augment the global env with specialized functions ;; todo: augment the global env with specialized functions