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)

View File

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

View File

@ -688,6 +688,12 @@
`(let ([,tmp ,new-rhs])
(check-not-unsafe-undefined/assign ,id ',(too-early-mutated-state-name state int-id))
(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
`(set! ,id ,new-rhs)])])]
[`(variable-reference-constant? (#%variable-reference ,id))