lower-primcalls.scm 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. ;;; Pass to lower-primcalls CPS for hoot
  2. ;;; Copyright (C) 2023 Free Software Foundation, Inc.
  3. ;;;
  4. ;;; This library is free software: you can redistribute it and/or modify
  5. ;;; it under the terms of the GNU Lesser General Public License as
  6. ;;; published by the Free Software Foundation, either version 3 of the
  7. ;;; License, or (at your option) any later version.
  8. ;;;
  9. ;;; This library is distributed in the hope that it will be useful, but
  10. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;; Lesser General Public License for more details.
  13. ;;;
  14. ;;; You should have received a copy of the GNU Lesser General Public
  15. ;;; License along with this program. If not, see
  16. ;;; <http://www.gnu.org/licenses/>.
  17. ;;; Commentary:
  18. ;;;
  19. ;;; When targetting WebAssembly, we don't have untagged struct fields,
  20. ;;; so we can fold some vtable predicates.
  21. ;;;
  22. ;;; Code:
  23. (define-module (language cps hoot lower-primcalls)
  24. #:use-module (ice-9 match)
  25. #:use-module (language cps)
  26. #:use-module (language cps intmap)
  27. #:use-module (language cps utils)
  28. #:use-module (language cps with-cps)
  29. #:export (lower-primcalls))
  30. (define (hoot-fixnum? x) (and (exact-integer? x)
  31. (<= (ash -1 29) x (1- (ash 1 29)))))
  32. (define (not-hoot-fixnum? x) (not (hoot-fixnum? x)))
  33. (define (lower-primcalls cps)
  34. (with-fresh-name-state cps
  35. (intmap-fold
  36. (lambda (label cont out)
  37. (match cont
  38. (($ $kargs names vars
  39. ($ $branch kf kt src 'vtable-has-unboxed-fields? nfields (vtable)))
  40. (intmap-replace out label
  41. (build-cont
  42. ($kargs names vars
  43. ($continue kf src ($values ()))))))
  44. (($ $kargs names vars
  45. ($ $branch kf kt src 'vtable-field-boxed? idx (vtable)))
  46. (intmap-replace out label
  47. (build-cont
  48. ($kargs names vars
  49. ($continue kt src ($values ()))))))
  50. (($ $kargs names vars
  51. ($ $branch kf kt src (or 'number? 'complex?) #f (x)))
  52. (with-cps out
  53. (letk kheap ($kargs () ()
  54. ($branch kf kt src 'heap-number? #f (x))))
  55. (setk label ($kargs names vars
  56. ($branch kheap kt src 'fixnum? #f (x))))))
  57. (($ $kargs names vars
  58. ($ $branch kf kt src 'real? #f (x)))
  59. (with-cps out
  60. (letk kfix? ($kargs () ()
  61. ($branch kf kt src 'fixnum? #f (x))))
  62. (letk kcomplex? ($kargs () ()
  63. ($branch kt kf src 'compnum? #f (x))))
  64. (setk label
  65. ($kargs names vars
  66. ($branch kfix? kcomplex? src 'heap-number? #f (x))))))
  67. (($ $kargs names vars
  68. ($ $branch kf kt src 'rational? #f (x)))
  69. (with-cps out
  70. (letv real imag)
  71. (letk kreal-finite? ($kargs ('real) (real)
  72. ($branch kf kt src 'f64-finite? #f (real))))
  73. (letk kflo ($kargs () ()
  74. ($continue kreal-finite? src
  75. ($primcall 'flonum->f64 #f (x)))))
  76. (letk kcomp-real ($kargs () ()
  77. ($continue kreal-finite? src
  78. ($primcall 'compnum-real #f (x)))))
  79. (letk kimag-finite? ($kargs ('imag) (imag)
  80. ($branch kf kcomp-real src 'f64-finite? #f (imag))))
  81. (letk kcomp ($kargs () ()
  82. ($continue kimag-finite? src
  83. ($primcall 'compnum-imag #f (x)))))
  84. (letk knum? ($kargs () ()
  85. ($branch kf kt src 'heap-number? #f (x))))
  86. (letk kcomp? ($kargs () ()
  87. ($branch knum? kcomp src 'compnum? #f (x))))
  88. (letk kflo? ($kargs () ()
  89. ($branch kcomp? kflo src 'flonum? #f (x))))
  90. (setk label ($kargs names vars
  91. ($branch kflo? kt src 'fixnum? #f (x))))))
  92. (($ $kargs names vars
  93. ($ $branch kf kt src 'integer? #f (x)))
  94. (with-cps out
  95. (letv real imag)
  96. (letk kreal-int? ($kargs ('real) (real)
  97. ($branch kf kt src 'f64-int? #f (real))))
  98. (letk kflo ($kargs () ()
  99. ($continue kreal-int? src
  100. ($primcall 'flonum->f64 #f (x)))))
  101. (letk kcomp-real ($kargs () ()
  102. ($continue kreal-int? src
  103. ($primcall 'compnum-real #f (x)))))
  104. (letk kimag-int? ($kargs ('imag) (imag)
  105. ($branch kf kcomp-real src 'f64-int? #f (imag))))
  106. (letk kcomp ($kargs () ()
  107. ($continue kimag-int? src
  108. ($primcall 'compnum-imag #f (x)))))
  109. (letk kcomp? ($kargs () ()
  110. ($branch kf kcomp src 'compnum? #f (x))))
  111. (letk kflo? ($kargs () ()
  112. ($branch kcomp? kflo src 'flonum? #f (x))))
  113. (letk kbig? ($kargs () ()
  114. ($branch kflo? kt src 'bignum? #f (x))))
  115. (setk label ($kargs names vars
  116. ($branch kbig? kt src 'fixnum? #f (x))))))
  117. (($ $kargs names vars
  118. ($ $branch kf kt src 'exact-integer? #f (x)))
  119. (with-cps out
  120. (letk kbig? ($kargs () ()
  121. ($branch kf kt src 'bignum? #f (x))))
  122. (setk label ($kargs names vars
  123. ($branch kbig? kt src 'fixnum? #f (x))))))
  124. (($ $kargs names vars
  125. ($ $branch kf kt src 'exact? #f (x)))
  126. (with-cps out
  127. (letk kfrac? ($kargs () ()
  128. ($branch kf kt src 'fracnum? #f (x))))
  129. (letk kbig? ($kargs () ()
  130. ($branch kfrac? kt src 'bignum? #f (x))))
  131. (setk label ($kargs names vars
  132. ($branch kbig? kt src 'fixnum? #f (x))))))
  133. (($ $kargs names vars
  134. ($ $branch kf kt src 'inexact? #f (x)))
  135. (with-cps out
  136. (letk kcomp? ($kargs () ()
  137. ($branch kf kt src 'compnum? #f (x))))
  138. (setk label ($kargs names vars
  139. ($branch kcomp? kt src 'flonum? #f (x))))))
  140. (($ $kargs names vars
  141. ($ $continue k src ($ $primcall 'call-thunk/no-inline #f (thunk))))
  142. (intmap-replace out label
  143. (build-cont
  144. ($kargs names vars
  145. ($continue k src ($call thunk ()))))))
  146. (($ $kargs names vars
  147. ($ $continue k src ($ $primcall 'load-const/unlikely val ())))
  148. (with-cps out
  149. (setk label ($kargs names vars ($continue k src ($const val))))))
  150. (($ $kargs names vars
  151. ($ $continue k src ($ $primcall 'tag-fixnum/unlikely #f (val))))
  152. (with-cps out
  153. (setk label ($kargs names vars
  154. ($continue k src
  155. ($primcall 'tag-fixnum #f (val)))))))
  156. (($ $kargs names vars
  157. ($ $continue k src ($ $primcall 'u64->scm/unlikely #f (val))))
  158. (with-cps out
  159. (setk label ($kargs names vars
  160. ($continue k src ($primcall 'u64->scm #f (val)))))))
  161. (($ $kargs names vars
  162. ($ $continue k src ($ $primcall 's64->scm/unlikely #f (val))))
  163. (with-cps out
  164. (setk label ($kargs names vars
  165. ($continue k src ($primcall 's64->scm #f (val)))))))
  166. (($ $kargs names vars
  167. ($ $continue k src
  168. ($ $primcall (or 'assume-u64 'assume-s64) (lo . hi) (val))))
  169. (with-cps out
  170. (setk label ($kargs names vars
  171. ($continue k src ($values (val)))))))
  172. (($ $kargs names vars
  173. ($ $continue k src
  174. ($ $primcall 'add/immediate (? not-hoot-fixnum? y) (x))))
  175. (with-cps out
  176. (letv y*)
  177. (letk k* ($kargs ('y) (y*)
  178. ($continue k src ($primcall 'add #f (x y*)))))
  179. (setk label ($kargs names vars
  180. ($continue k* src ($const y))))))
  181. (($ $kargs names vars
  182. ($ $continue k src
  183. ($ $primcall 'sub/immediate (? not-hoot-fixnum? y) (x))))
  184. (with-cps out
  185. (letv y*)
  186. (letk k* ($kargs ('y) (y*)
  187. ($continue k src ($primcall 'sub #f (x y*)))))
  188. (setk label ($kargs names vars
  189. ($continue k* src ($const y))))))
  190. (($ $kargs names vars
  191. ($ $continue k src
  192. ($ $primcall 'mul/immediate (? not-hoot-fixnum? y) (x))))
  193. (with-cps out
  194. (letv y*)
  195. (letk k* ($kargs ('y) (y*)
  196. ($continue k src ($primcall 'mul #f (x y*)))))
  197. (setk label ($kargs names vars
  198. ($continue k* src ($const y))))))
  199. (($ $kargs names vars
  200. ($ $continue k src
  201. ($ $primcall 'logand/immediate (? not-hoot-fixnum? y) (x))))
  202. (with-cps out
  203. (letv y*)
  204. (letk k* ($kargs ('y) (y*)
  205. ($continue k src ($primcall 'logand #f (x y*)))))
  206. (setk label ($kargs names vars
  207. ($continue k* src ($const y))))))
  208. (($ $kargs names vars ($ $throw src op param args))
  209. (match op
  210. ((or 'raise-type-error
  211. 'raise-range-error
  212. 'raise-arity-error
  213. 'raise-exception) out)
  214. (_ (error "unexpected throw; fix to use raise-exception" op))))
  215. (_ out)))
  216. cps
  217. cps)))