schemify: improve known-value detection
Recognize `(let () <expr>)` and `(begin <expr>)` when inspecting expressions.
This commit is contained in:
parent
ca285c384d
commit
482fcd6d59
|
@ -22,59 +22,68 @@
|
|||
#:primitives [primitives #hasheq()] ; for `optimize-inline?` mode
|
||||
#:optimize-inline? [optimize-inline? #f]
|
||||
#:post-schemify? [post-schemify? #f])
|
||||
(cond
|
||||
[(lambda? rhs)
|
||||
(define-values (lam inlinable?) (extract-lambda rhs))
|
||||
(define arity-mask (lambda-arity-mask lam))
|
||||
(if (and inlinable?
|
||||
(not post-schemify?)
|
||||
(or (can-inline? lam)
|
||||
(wrap-property defn 'compiler-hint:cross-module-inline)))
|
||||
(let ([lam (if optimize-inline?
|
||||
(optimize* lam prim-knowns primitives knowns imports mutated unsafe-mode?)
|
||||
lam)])
|
||||
(known-procedure/can-inline arity-mask lam))
|
||||
(known-procedure arity-mask))]
|
||||
[(and (literal? rhs)
|
||||
(not (hash-ref mutated (unwrap id) #f)))
|
||||
(known-literal (unwrap-literal rhs))]
|
||||
[(and (symbol? (unwrap rhs))
|
||||
(not (hash-ref mutated (unwrap id) #f)))
|
||||
(define u-rhs (unwrap rhs))
|
||||
(cond
|
||||
[(hash-ref prim-knowns u-rhs #f)
|
||||
=> (lambda (known) (known-copy u-rhs))]
|
||||
[(not (simple-mutated-state? (hash-ref mutated u-rhs #f)))
|
||||
;; referenced variable is mutated, but not necessarily the target
|
||||
(and defn a-known-constant)]
|
||||
[(hash-ref-either knowns imports u-rhs)
|
||||
=> (lambda (known)
|
||||
(cond
|
||||
[(known-procedure/can-inline/need-imports? known)
|
||||
;; can't just return `known`, since that loses the connection to the import;
|
||||
;; the `inline-clone` function specially handles an identifier as the
|
||||
;; expression to inline
|
||||
(known-procedure/can-inline (known-procedure-arity-mask known)
|
||||
rhs)]
|
||||
[(or (known-procedure/can-inline? known)
|
||||
(known-literal? known))
|
||||
known]
|
||||
[(or (not defn)
|
||||
;; can't just return `known`; like `known-procedure/can-inline/need-imports`,
|
||||
;; we'd lose track of the need to potentially propagate imports
|
||||
(known-copy? known))
|
||||
(known-copy rhs)]
|
||||
[else known]))]
|
||||
[defn a-known-constant]
|
||||
[else (known-copy rhs)])]
|
||||
[(parameter-result? rhs prim-knowns knowns mutated)
|
||||
(known-procedure 3)]
|
||||
[(constructed-procedure-arity-mask rhs)
|
||||
=> (lambda (m) (known-procedure m))]
|
||||
[(and defn
|
||||
(simple? rhs prim-knowns knowns imports mutated simples))
|
||||
a-known-constant]
|
||||
[else #f]))
|
||||
(let loop ([rhs rhs])
|
||||
(cond
|
||||
[(lambda? rhs)
|
||||
(define-values (lam inlinable?) (extract-lambda rhs))
|
||||
(define arity-mask (lambda-arity-mask lam))
|
||||
(if (and inlinable?
|
||||
(not post-schemify?)
|
||||
(or (can-inline? lam)
|
||||
(wrap-property defn 'compiler-hint:cross-module-inline)))
|
||||
(let ([lam (if optimize-inline?
|
||||
(optimize* lam prim-knowns primitives knowns imports mutated unsafe-mode?)
|
||||
lam)])
|
||||
(known-procedure/can-inline arity-mask lam))
|
||||
(known-procedure arity-mask))]
|
||||
[(and (literal? rhs)
|
||||
(not (hash-ref mutated (unwrap id) #f)))
|
||||
(known-literal (unwrap-literal rhs))]
|
||||
[(and (symbol? (unwrap rhs))
|
||||
(not (hash-ref mutated (unwrap id) #f)))
|
||||
(define u-rhs (unwrap rhs))
|
||||
(cond
|
||||
[(hash-ref prim-knowns u-rhs #f)
|
||||
=> (lambda (known) (known-copy u-rhs))]
|
||||
[(not (simple-mutated-state? (hash-ref mutated u-rhs #f)))
|
||||
;; referenced variable is mutated, but not necessarily the target
|
||||
(and defn a-known-constant)]
|
||||
[(hash-ref-either knowns imports u-rhs)
|
||||
=> (lambda (known)
|
||||
(cond
|
||||
[(known-procedure/can-inline/need-imports? known)
|
||||
;; can't just return `known`, since that loses the connection to the import;
|
||||
;; the `inline-clone` function specially handles an identifier as the
|
||||
;; expression to inline
|
||||
(known-procedure/can-inline (known-procedure-arity-mask known)
|
||||
rhs)]
|
||||
[(or (known-procedure/can-inline? known)
|
||||
(known-literal? known))
|
||||
known]
|
||||
[(or (not defn)
|
||||
;; can't just return `known`; like `known-procedure/can-inline/need-imports`,
|
||||
;; we'd lose track of the need to potentially propagate imports
|
||||
(known-copy? known))
|
||||
(known-copy rhs)]
|
||||
[else known]))]
|
||||
[defn a-known-constant]
|
||||
[else (known-copy rhs)])]
|
||||
[(parameter-result? rhs prim-knowns knowns mutated)
|
||||
(known-procedure 3)]
|
||||
[(constructed-procedure-arity-mask rhs)
|
||||
=> (lambda (m) (known-procedure m))]
|
||||
[else
|
||||
(match rhs
|
||||
[`(let-values () ,e)
|
||||
(loop e)]
|
||||
[`(begin ,e)
|
||||
(loop e)]
|
||||
[`,_
|
||||
(cond
|
||||
[(and defn
|
||||
(simple? rhs prim-knowns knowns imports mutated simples))
|
||||
a-known-constant]
|
||||
[else #f])])])))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user