schemify: fix handling of set! in dead code

Mutability analysis may determine that a `set!` is dead code, and then
the mutated variable might be optimized away, so don't leave the dead
`set!` behind.
This commit is contained in:
Matthew Flatt 2020-10-21 08:45:00 -06:00
parent 1dcabfada7
commit 42a9e26ee9
3 changed files with 27 additions and 4 deletions

View File

@ -3385,4 +3385,16 @@ case of module-leve bindings; it doesn't cover local bindings.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(module regression-test-for-set!-in-dead-compile-time-code '#%kernel
(#%require (for-syntax '#%kernel))
(begin-for-syntax
(let-values ([(fresh)
(let-values ([(weird-next) 0])
(lambda ()
(set! weird-next (add1 weird-next))))])
10)))
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(report-errs) (report-errs)

View File

@ -31550,10 +31550,15 @@
'set! 'set!
id_0 id_0
tmp_0))) tmp_0)))
(list (if (not
'set! state_0)
id_0 (list
new-rhs_0)))))))) 'void
new-rhs_0)
(list
'set!
id_0
new-rhs_0)))))))))
(args (args
(raise-binding-result-arity-error (raise-binding-result-arity-error
2 2

View File

@ -688,6 +688,12 @@
`(let ([,tmp ,new-rhs]) `(let ([,tmp ,new-rhs])
(check-not-unsafe-undefined/assign ,id ',(too-early-mutated-state-name state int-id)) (check-not-unsafe-undefined/assign ,id ',(too-early-mutated-state-name state int-id))
(set! ,id ,tmp))] (set! ,id ,tmp))]
[(not state)
;; It's worrying that `id` is not marked as mutable, but this is
;; possible when mutability inference determines that the `set!` is
;; dead code. Since the variable is not mutated, it might even be
;; optimized away by schemify; so, just in case, discard the `set!`.
`(void ,new-rhs)]
[else [else
`(set! ,id ,new-rhs)])])] `(set! ,id ,new-rhs)])])]
[`(variable-reference-constant? (#%variable-reference ,id)) [`(variable-reference-constant? (#%variable-reference ,id))