elide-values.scm 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. ;;; Continuation-passing style (CPS) intermediate language (IL)
  2. ;; Copyright (C) 2013, 2014 Free Software Foundation, Inc.
  3. ;;;; This library is free software; you can redistribute it and/or
  4. ;;;; modify it under the terms of the GNU Lesser General Public
  5. ;;;; License as published by the Free Software Foundation; either
  6. ;;;; version 3 of the License, or (at your option) any later version.
  7. ;;;;
  8. ;;;; This library is distributed in the hope that it will be useful,
  9. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. ;;;; Lesser General Public License for more details.
  12. ;;;;
  13. ;;;; You should have received a copy of the GNU Lesser General Public
  14. ;;;; License along with this library; if not, write to the Free Software
  15. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  16. ;;; Commentary:
  17. ;;;
  18. ;;; Primcalls that don't correspond to VM instructions are treated as if
  19. ;;; they are calls, and indeed the later reify-primitives pass turns
  20. ;;; them into calls. Because no return arity checking is done for these
  21. ;;; primitives, if a later optimization pass simplifies the primcall to
  22. ;;; a VM operation, the tail of the simplification has to be a
  23. ;;; primcall to 'values. Most of these primcalls can be elided, and
  24. ;;; that is the job of this pass.
  25. ;;;
  26. ;;; Code:
  27. (define-module (language cps elide-values)
  28. #:use-module (ice-9 match)
  29. #:use-module (srfi srfi-26)
  30. #:use-module (language cps)
  31. #:use-module (language cps dfg)
  32. #:export (elide-values))
  33. (define (elide-values fun)
  34. (let ((conts (build-local-cont-table
  35. (match fun (($ $fun src meta free body) body)))))
  36. (define (visit-cont cont)
  37. (rewrite-cps-cont cont
  38. (($ $cont sym ($ $kargs names syms body))
  39. (sym ($kargs names syms ,(visit-term body))))
  40. (($ $cont sym ($ $kentry self tail clauses))
  41. (sym ($kentry self ,tail ,(map visit-cont clauses))))
  42. (($ $cont sym ($ $kclause arity body))
  43. (sym ($kclause ,arity ,(visit-cont body))))
  44. (($ $cont)
  45. ,cont)))
  46. (define (visit-term term)
  47. (rewrite-cps-term term
  48. (($ $letk conts body)
  49. ($letk ,(map visit-cont conts)
  50. ,(visit-term body)))
  51. (($ $letrec names syms funs body)
  52. ($letrec names syms (map elide-values funs)
  53. ,(visit-term body)))
  54. (($ $continue k src ($ $primcall 'values vals))
  55. ,(rewrite-cps-term (lookup-cont k conts)
  56. (($ $ktail)
  57. ($continue k src ($values vals)))
  58. (($ $kreceive ($ $arity req () rest () #f) kargs)
  59. ,(cond
  60. ((and (not rest) (= (length vals) (length req)))
  61. (build-cps-term
  62. ($continue kargs src ($values vals))))
  63. ((and rest (>= (length vals) (length req)))
  64. (let-gensyms (krest rest)
  65. (let ((vals* (append (list-head vals (length req))
  66. (list rest))))
  67. (build-cps-term
  68. ($letk ((krest ($kargs ('rest) (rest)
  69. ($continue kargs src
  70. ($values vals*)))))
  71. ,(let lp ((tail (list-tail vals (length req)))
  72. (k krest))
  73. (match tail
  74. (()
  75. (build-cps-term ($continue k src
  76. ($const '()))))
  77. ((v . tail)
  78. (let-gensyms (krest rest)
  79. (build-cps-term
  80. ($letk ((krest ($kargs ('rest) (rest)
  81. ($continue k src
  82. ($primcall 'cons
  83. (v rest))))))
  84. ,(lp tail krest))))))))))))
  85. (else term)))
  86. (($ $kargs args)
  87. ,(if (< (length vals) (length args))
  88. term
  89. (let ((vals (list-head vals (length args))))
  90. (build-cps-term
  91. ($continue k src ($values vals))))))))
  92. (($ $continue k src (and fun ($ $fun)))
  93. ($continue k src ,(elide-values fun)))
  94. (($ $continue)
  95. ,term)))
  96. (rewrite-cps-exp fun
  97. (($ $fun src meta free body)
  98. ($fun src meta free ,(visit-cont body))))))