From 42a9e26ee933479811565ac28a2f8b0b62b59ddd Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Wed, 21 Oct 2020 08:45:00 -0600 Subject: [PATCH] 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. --- pkgs/racket-test-core/tests/racket/module.rktl | 12 ++++++++++++ racket/src/cs/schemified/schemify.scm | 13 +++++++++---- racket/src/schemify/schemify.rkt | 6 ++++++ 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/pkgs/racket-test-core/tests/racket/module.rktl b/pkgs/racket-test-core/tests/racket/module.rktl index e103bd733f..06d47e897f 100644 --- a/pkgs/racket-test-core/tests/racket/module.rktl +++ b/pkgs/racket-test-core/tests/racket/module.rktl @@ -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) diff --git a/racket/src/cs/schemified/schemify.scm b/racket/src/cs/schemified/schemify.scm index ff9debebe5..05fb508e3e 100644 --- a/racket/src/cs/schemified/schemify.scm +++ b/racket/src/cs/schemified/schemify.scm @@ -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 diff --git a/racket/src/schemify/schemify.rkt b/racket/src/schemify/schemify.rkt index 612b41a706..9c4a6ee43a 100644 --- a/racket/src/schemify/schemify.rkt +++ b/racket/src/schemify/schemify.rkt @@ -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))