From 0a5c510b72a4f589606bd1da1d86027ee7a4ce5a Mon Sep 17 00:00:00 2001 From: Gustavo Massaccesi Date: Fri, 27 Jan 2017 18:09:42 -0300 Subject: [PATCH] advance the vclock for a `values` with 0 or more than 1 argument To avoid moving expressions that may have a side effect, the optimizer must recognize that in this position this will cause an error and advance the virtual clock. Currently the only primitive that is flagged as SCHEME_PRIM_IS_OMITABLE and may have multiple return values is `values`. Thanks to Robby for finding the original version of the test. --- pkgs/racket-test-core/tests/racket/optimize.rktl | 9 +++++++++ racket/src/racket/src/optimize.c | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pkgs/racket-test-core/tests/racket/optimize.rktl b/pkgs/racket-test-core/tests/racket/optimize.rktl index 76900e6945..89ffe204f6 100644 --- a/pkgs/racket-test-core/tests/racket/optimize.rktl +++ b/pkgs/racket-test-core/tests/racket/optimize.rktl @@ -1724,6 +1724,15 @@ (let loop ([n 0] [m 9]) (loop (+ m 10) (+ n 9)))))) +;; Don't reorder pass a `values` with the wrong nunmber of arguments. +;; `values` is the only primitive that is omitable and may return multiple values. +(test-comp '(lambda (b) + (let ([x (unbox b)]) + (+ (values 2 2) x))) + '(lambda (b) + (+ (values 2 2) (unbox b))) + #f) + (test-comp '(lambda (z) (let-values ([(x y) (if z diff --git a/racket/src/racket/src/optimize.c b/racket/src/racket/src/optimize.c index 6d0298aa2a..f226d8a126 100644 --- a/racket/src/racket/src/optimize.c +++ b/racket/src/racket/src/optimize.c @@ -2987,7 +2987,8 @@ static int is_nonmutating_nondependant_primitive(Scheme_Object *rator, int n) { if (SCHEME_PRIMP(rator) && ((SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_OMITABLE | SCHEME_PRIM_IS_OMITABLE_ALLOCATION)) - && !(SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_UNSAFE_OMITABLE))) + && !(SCHEME_PRIM_PROC_OPT_FLAGS(rator) & (SCHEME_PRIM_IS_UNSAFE_OMITABLE)) + && !((SAME_OBJ(scheme_values_proc, rator) && (n != 1)))) && (n >= ((Scheme_Primitive_Proc *)rator)->mina) && (n <= ((Scheme_Primitive_Proc *)rator)->mu.maxa)) return 1;