elide-values.scm 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. ;;; Continuation-passing style (CPS) intermediate language (IL)
  2. ;; Copyright (C) 2013, 2014, 2015 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 (language cps)
  30. #:use-module (language cps utils)
  31. #:use-module (language cps with-cps)
  32. #:use-module (language cps intmap)
  33. #:export (elide-values))
  34. (define (inline-values cps k src args)
  35. (match (intmap-ref cps k)
  36. (($ $ktail)
  37. (with-cps cps
  38. (build-term
  39. ($continue k src ($values args)))))
  40. (($ $kreceive ($ $arity req () rest () #f) kargs)
  41. (cond
  42. ((and (not rest) (= (length args) (length req)))
  43. (with-cps cps
  44. (build-term
  45. ($continue kargs src ($values args)))))
  46. ((and rest (>= (length args) (length req)))
  47. (let ()
  48. (define (build-rest cps k tail)
  49. (match tail
  50. (()
  51. (with-cps cps
  52. (build-term ($continue k src ($const '())))))
  53. ((v . tail)
  54. (with-cps cps
  55. (letv rest)
  56. (letk krest ($kargs ('rest) (rest)
  57. ($continue k src ($primcall 'cons (v rest)))))
  58. ($ (build-rest krest tail))))))
  59. (with-cps cps
  60. (letv rest)
  61. (letk krest ($kargs ('rest) (rest)
  62. ($continue kargs src
  63. ($values ,(append (list-head args (length req))
  64. (list rest))))))
  65. ($ (build-rest krest (list-tail args (length req)))))))
  66. (else (with-cps cps #f))))))
  67. (define (elide-values conts)
  68. (with-fresh-name-state conts
  69. (persistent-intmap
  70. (intmap-fold
  71. (lambda (label cont out)
  72. (match cont
  73. (($ $kargs names vars ($ $continue k src ($ $primcall 'values args)))
  74. (call-with-values (lambda () (inline-values out k src args))
  75. (lambda (out term)
  76. (if term
  77. (let ((cont (build-cont ($kargs names vars ,term))))
  78. (intmap-replace! out label cont))
  79. out))))
  80. (_ out)))
  81. conts
  82. conts))))