guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] branch master updated: Fix closure-conversion bug for SC


From: Andy Wingo
Subject: [Guile-commits] branch master updated: Fix closure-conversion bug for SCC with all free vars pruned
Date: Tue, 27 Apr 2021 08:53:24 -0400

This is an automated email from the git hooks/post-receive script.

wingo pushed a commit to branch master
in repository guile.

The following commit(s) were added to refs/heads/master by this push:
     new 12fa7d1  Fix closure-conversion bug for SCC with all free vars pruned
12fa7d1 is described below

commit 12fa7d115d24fa97879c5b6cde44e93a25221895
Author: Andy Wingo <wingo@pobox.com>
AuthorDate: Tue Apr 27 14:51:38 2021 +0200

    Fix closure-conversion bug for SCC with all free vars pruned
    
    * module/language/cps/closure-conversion.scm (convert-one): Fix bug when
    getting value of SCC whose free variables have been elided.  Thanks to
    abcdw for the report!
    * test-suite/tests/compiler.test ("cse auxiliary definitions"): Remove
    spurious newline.
    ("closure conversion"): New test.
---
 module/language/cps/closure-conversion.scm | 16 +++++++++-----
 test-suite/tests/compiler.test             | 35 ++++++++++++++++++++++++++++--
 2 files changed, 44 insertions(+), 7 deletions(-)

diff --git a/module/language/cps/closure-conversion.scm 
b/module/language/cps/closure-conversion.scm
index d1492c1..875552b 100644
--- a/module/language/cps/closure-conversion.scm
+++ b/module/language/cps/closure-conversion.scm
@@ -504,11 +504,17 @@ Otherwise @var{var} is bound, so @var{k} is called with 
@var{var}."
         ;; A not-well-known function with zero free vars.  Copy as a
         ;; constant, relying on the linker to reify just one copy.
         => (lambda (kfun)
-             (with-cps cps
-               (letv var*)
-               (let$ body (k var*))
-               (letk k* ($kargs (#f) (var*) ,body))
-               (build-term ($continue k* #f ($const-fun kfun))))))
+             ;; It may well be that "var" is the "self" of another
+             ;; member of an SCC containing just one not-well-known
+             ;; function.  But here we're asking for the value of the
+             ;; closure, which is the $const-fun of the non-well-known
+             ;; member.
+             (let ((kfun (closure-label kfun shared bound->label)))
+               (with-cps cps
+                 (letv var*)
+                 (let$ body (k var*))
+                 (letk k* ($kargs (#f) (var*) ,body))
+                 (build-term ($continue k* #f ($const-fun kfun)))))))
        ((intset-ref free var)
         (if (and self-known? (eqv? 1 nfree))
             ;; A reference to the one free var of a well-known function.
diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test
index dc75d0a..90eee49 100644
--- a/test-suite/tests/compiler.test
+++ b/test-suite/tests/compiler.test
@@ -1,5 +1,5 @@
 ;;;; compiler.test --- tests for the compiler      -*- scheme -*-
-;;;; Copyright (C) 2008-2014, 2018 Free Software Foundation, Inc.
+;;;; Copyright (C) 2008-2014, 2018, 2021 Free Software Foundation, Inc.
 ;;;; 
 ;;;; This library is free software; you can redistribute it and/or
 ;;;; modify it under the terms of the GNU Lesser General Public
@@ -315,7 +315,6 @@
                (loop (+ i 1) (thunk)))
               (else
                (unless (= result 42) (error "bad result" result))
-               (newline)
                result))))
          (define (test n)
            (let ((matrix (make-vector n)))
@@ -337,3 +336,35 @@
   (pass-if-equal "test terminates without error" 42
     (test-proc)))
 
+(with-test-prefix "closure conversion"
+  (define test-code
+    '(lambda (arg)
+       (define (A a)
+         (let loop ((ls a))
+           (cond ((null? ls)
+                  (B a))
+                 ((pair? ls)
+                  (if (list? (car ls))
+                      (loop (cdr ls))
+                      #t))
+                 (else #t))))
+       (define (B b)
+         (let loop ((ls b))
+           (cond ((null? ls)
+                  (map A b))
+                 ((pair? ls)
+                  (if (list? (car ls))
+                      (loop (cdr ls))
+                      (error "bad" b)))
+                 (else
+                  (error "bad" b)))))
+       (B arg)))
+
+  (define test-proc #f)
+  (pass-if "compiling test works"
+    (begin
+      (set! test-proc (compile test-code))
+      (procedure? test-proc)))
+
+  (pass-if-equal "test terminates without error" '(#t #t)
+    (test-proc '((V X) (Y Z)))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]