~ chicken-core (chicken-5) d6c35912072687ed6149c2cc7c248e18059d1a74
commit d6c35912072687ed6149c2cc7c248e18059d1a74
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Fri Mar 18 20:27:09 2016 +0100
Commit: Evan Hanson <evhan@foldling.org>
CommitDate: Fri Mar 18 20:27:09 2016 +0100
Don't shortcut pure calls in the optimiser
When we notice a node represents a call to a pure (side effect-free)
procedure, we attempt to drop the call completely, if the result is
unused. However, if the result _is_ used, we shouldn't just give up.
In fact, if the callee is of type explicit-rest, we *must* finish the
optimisation by tweaking the caller.
This fixes a bug reported by Joerg Wittenberger which got triggered
rather easily when adding profiler instrumentation to procedures,
because those always use rest args.
Signed-off-by: Evan Hanson <evhan@foldling.org>
diff --git a/optimizer.scm b/optimizer.scm
index 9eb4247d..4c97bd9e 100644
--- a/optimizer.scm
+++ b/optimizer.scm
@@ -348,28 +348,27 @@
llist args (first (node-subexpressions lval)) #f db
void)
fids gae) ) )
- ((variable-mark var '##compiler#pure)
- ;; callee is side-effect free
- (or (and-let* ((k (car args))
- ((eq? '##core#variable (node-class k)))
- (kvar (first (node-parameters k)))
- (lval (and (not (test kvar 'unknown))
- (test kvar 'value)))
- ((eq? '##core#lambda (node-class lval)))
- (llist (third (node-parameters lval)))
- ((or (test (car llist) 'unused)
- (and (not (test (car llist) 'references))
- (not (test (car llist) 'assigned)))))
- ((not (any (cut expression-has-side-effects? <> db)
- (cdr args) ))))
- (debugging
- 'o
- "removed call to pure procedure with unused result"
- info)
- (make-node
- '##core#call (list #t)
- (list k (make-node '##core#undefined '() '())) ) )
- (walk-generic n class params subs fids gae #f)) )
+ ((and-let* (((variable-mark var '##compiler#pure))
+ ((eq? '##core#variable (node-class (car args))))
+ (kvar (first (node-parameters (car args))))
+ (lval (and (not (test kvar 'unknown))
+ (test kvar 'value)))
+ ((eq? '##core#lambda (node-class lval)))
+ (llist (third (node-parameters lval)))
+ ((or (test (car llist) 'unused)
+ (and (not (test (car llist) 'references))
+ (not (test (car llist) 'assigned))))))
+ ;; callee is side-effect free
+ (not (any (cut expression-has-side-effects? <> db)
+ (cdr args))))
+ (debugging
+ 'o
+ "removed call to pure procedure with unused result"
+ info)
+ (make-node
+ '##core#call (list #t)
+ (list (car args)
+ (make-node '##core#undefined '() '()))))
((and lval
(eq? '##core#lambda (node-class lval)))
;; callee is a lambda
diff --git a/tests/compiler-tests.scm b/tests/compiler-tests.scm
index 124dc9aa..ad67351a 100644
--- a/tests/compiler-tests.scm
+++ b/tests/compiler-tests.scm
@@ -395,3 +395,20 @@
(assert (= 12.0 (s4v-sum "float" f64vector '#f64(1.5 2.5 3.5 4.5))))
(assert (= 12.0 (s4v-sum "float" nonnull-f32vector '#f32(1.5 2.5 3.5 4.5))))
(assert (= 12.0 (s4v-sum "float" nonnull-f64vector '#f64(1.5 2.5 3.5 4.5))))
+
+
+;; Reported by Jörg Wittenberger: in some cases, -profile would
+;; generate calls to procedures. This was due to calls to pure
+;; procedures not getting replaced with explicitly consed rest
+;; list when the procedures themselves were hidden.
+(module explicitly-consed-rest-args-bug (do-it also-do-it)
+ (import scheme chicken)
+
+ (: get-value (* * #!rest * --> *))
+ (define (get-value x y . rest)
+ (apply x y rest))
+ (define (do-it arg)
+ (get-value arg 2))
+ (define (also-do-it arg)
+ (get-value arg 3))
+)
Trap