reify-primitives.scm 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. ;;; Continuation-passing style (CPS) intermediate language (IL)
  2. ;; Copyright (C) 2013, 2014, 2015, 2017, 2018 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. ;;; A pass to reify lone $prim's that were never folded into a
  19. ;;; $primcall, and $primcall's to primitives that don't have a
  20. ;;; corresponding VM op.
  21. ;;;
  22. ;;; Code:
  23. (define-module (language cps reify-primitives)
  24. #:use-module (ice-9 match)
  25. #:use-module (language cps)
  26. #:use-module (language cps utils)
  27. #:use-module (language cps with-cps)
  28. #:use-module (language cps intmap)
  29. #:use-module (language bytecode)
  30. #:use-module (system base target)
  31. #:use-module (system base types internal)
  32. #:export (reify-primitives))
  33. (define (primitive-module name)
  34. (case name
  35. ((bytevector?
  36. bytevector-length
  37. bytevector-u8-ref bytevector-u8-set!
  38. bytevector-s8-ref bytevector-s8-set!
  39. bytevector-u16-ref bytevector-u16-set!
  40. bytevector-u16-native-ref bytevector-u16-native-set!
  41. bytevector-s16-ref bytevector-s16-set!
  42. bytevector-s16-native-ref bytevector-s16-native-set!
  43. bytevector-u32-ref bytevector-u32-set!
  44. bytevector-u32-native-ref bytevector-u32-native-set!
  45. bytevector-s32-ref bytevector-s32-set!
  46. bytevector-s32-native-ref bytevector-s32-native-set!
  47. bytevector-u64-ref bytevector-u64-set!
  48. bytevector-u64-native-ref bytevector-u64-native-set!
  49. bytevector-s64-ref bytevector-s64-set!
  50. bytevector-s64-native-ref bytevector-s64-native-set!
  51. bytevector-ieee-single-ref bytevector-ieee-single-set!
  52. bytevector-ieee-single-native-ref bytevector-ieee-single-native-set!
  53. bytevector-ieee-double-ref bytevector-ieee-double-set!
  54. bytevector-ieee-double-native-ref bytevector-ieee-double-native-set!)
  55. '(rnrs bytevectors))
  56. ((atomic-box?
  57. make-atomic-box atomic-box-ref atomic-box-set!
  58. atomic-box-swap! atomic-box-compare-and-swap!)
  59. '(ice-9 atomic))
  60. ((current-thread) '(ice-9 threads))
  61. ((class-of) '(oop goops))
  62. ((u8vector-ref
  63. u8vector-set! s8vector-ref s8vector-set!
  64. u16vector-ref u16vector-set! s16vector-ref s16vector-set!
  65. u32vector-ref u32vector-set! s32vector-ref s32vector-set!
  66. u64vector-ref u64vector-set! s64vector-ref s64vector-set!
  67. f32vector-ref f32vector-set! f64vector-ref f64vector-set!)
  68. '(srfi srfi-4))
  69. (else '(guile))))
  70. (define (primitive-ref cps name k src)
  71. (with-cps cps
  72. (letv box)
  73. (letk kbox ($kargs ('box) (box)
  74. ($continue k src
  75. ($primcall 'scm-ref/immediate '(box . 1) (box)))))
  76. ($ ((hashq-ref *ephemeral-reifiers* 'cached-module-box)
  77. kbox src (list (primitive-module name) name #f #t) '()))))
  78. (define (builtin-ref cps idx k src)
  79. (with-cps cps
  80. (build-term
  81. ($continue k src ($primcall 'builtin-ref idx ())))))
  82. (define (reify-clause cps)
  83. (with-cps cps
  84. (let$ body
  85. (with-cps-constants ((wna 'wrong-number-of-args)
  86. (args '(#f "Wrong number of arguments" () #f)))
  87. (build-term ($throw #f 'throw #f (wna args)))))
  88. (letk kbody ($kargs () () ,body))
  89. (letk kclause ($kclause ('() '() #f '() #f) kbody #f))
  90. kclause))
  91. ;; A $kreceive continuation should have only one predecessor.
  92. (define (uniquify-receive cps k)
  93. (match (intmap-ref cps k)
  94. (($ $kreceive ($ $arity req () rest () #f) kargs)
  95. (with-cps cps
  96. (letk k ($kreceive req rest kargs))
  97. k))
  98. (_
  99. (with-cps cps k))))
  100. (define (wrap-unary cps k src wrap unwrap op param a)
  101. (with-cps cps
  102. (letv a* res*)
  103. (letk kres ($kargs ('res*) (res*)
  104. ($continue k src
  105. ($primcall 'u64->s64 #f (res*)))))
  106. (letk ka ($kargs ('a*) (a*)
  107. ($continue kres src
  108. ($primcall op param (a*)))))
  109. (build-term
  110. ($continue ka src
  111. ($primcall 's64->u64 #f (a))))))
  112. (define (wrap-binary cps k src wrap unwrap op param a b)
  113. (with-cps cps
  114. (letv a* b* res*)
  115. (letk kres ($kargs ('res*) (res*)
  116. ($continue k src
  117. ($primcall 'u64->s64 #f (res*)))))
  118. (letk kb ($kargs ('b*) (b*)
  119. ($continue kres src
  120. ($primcall op param (a* b*)))))
  121. (letk ka ($kargs ('a*) (a*)
  122. ($continue kb src
  123. ($primcall 's64->u64 #f (b)))))
  124. (build-term
  125. ($continue ka src
  126. ($primcall 's64->u64 #f (a))))))
  127. (define (wrap-binary/exp cps k src wrap unwrap op param a b-exp)
  128. (with-cps cps
  129. (letv a* b* res*)
  130. (letk kres ($kargs ('res*) (res*)
  131. ($continue k src
  132. ($primcall 'u64->s64 #f (res*)))))
  133. (letk kb ($kargs ('b*) (b*)
  134. ($continue kres src
  135. ($primcall op param (a* b*)))))
  136. (letk ka ($kargs ('a*) (a*)
  137. ($continue kb src ,b-exp)))
  138. (build-term
  139. ($continue ka src
  140. ($primcall 's64->u64 #f (a))))))
  141. ;; Primitives that we need to remove.
  142. (define *ephemeral-reifiers* (make-hash-table))
  143. (define-syntax-rule (define-ephemeral (name cps k src param arg ...)
  144. . body)
  145. (hashq-set! *ephemeral-reifiers* 'name
  146. (lambda (cps k src param args)
  147. (match args ((arg ...) (let () . body))))))
  148. (define-ephemeral (fadd/immediate cps k src param a)
  149. (with-cps cps
  150. (letv b)
  151. (letk kb ($kargs ('b) (b)
  152. ($continue k src
  153. ($primcall 'fadd #f (a b)))))
  154. (build-term
  155. ($continue kb src
  156. ($primcall 'load-f64 param ())))))
  157. (define-syntax-rule (define-binary-signed-ephemeral name uname)
  158. (define-ephemeral (name cps k src param a b)
  159. (wrap-binary cps k src 's64->u64 'u64->s64 'uname #f a b)))
  160. (define-binary-signed-ephemeral sadd uadd)
  161. (define-binary-signed-ephemeral ssub usub)
  162. (define-binary-signed-ephemeral smul umul)
  163. (define-syntax-rule (define-binary-signed-ephemeral/imm name/imm
  164. uname/imm uname)
  165. (define-ephemeral (name/imm cps k src param a)
  166. (if (and (exact-integer? param) (<= 0 param 255))
  167. (wrap-unary cps k src 's64->u64 'u64->s64 'uname/imm param a)
  168. (wrap-binary/exp cps k src 's64->u64 'u64->s64 'uname #f a
  169. (let ((param (logand param (1- (ash 1 64)))))
  170. (build-exp ($primcall 'load-u64 param ())))))))
  171. (define-binary-signed-ephemeral/imm sadd/immediate uadd/immediate uadd)
  172. (define-binary-signed-ephemeral/imm ssub/immediate usub/immediate usub)
  173. (define-binary-signed-ephemeral/imm smul/immediate umul/immediate umul)
  174. (define-ephemeral (slsh cps k src param a b)
  175. (wrap-binary/exp cps k src 's64->u64 'u64->s64 'ulsh #f a
  176. (build-exp ($values (b)))))
  177. (define-ephemeral (slsh/immediate cps k src param a)
  178. (wrap-unary cps k src 's64->u64 'u64->s64 'ulsh/immediate param a))
  179. (define (reify-lookup cps src mod-var name assert-bound? have-var)
  180. (define (%lookup cps kbad k src mod-var name-var var assert-bound?)
  181. (if assert-bound?
  182. (with-cps cps
  183. (letv val)
  184. (letk kcheck
  185. ($kargs ('val) (val)
  186. ($branch k kbad src 'undefined? #f (val))))
  187. (letk kref
  188. ($kargs () ()
  189. ($continue kcheck src
  190. ($primcall 'scm-ref/immediate '(box . 1) (var)))))
  191. ($ (%lookup kbad kref src mod-var name-var var #f)))
  192. (with-cps cps
  193. (letk kres
  194. ($kargs ('var) (var)
  195. ($branch kbad k src 'heap-object? #f (var))))
  196. (build-term
  197. ($continue kres src
  198. ($primcall 'lookup #f (mod-var name-var)))))))
  199. (define %unbound
  200. #(unbound-variable #f "Unbound variable: ~S"))
  201. (with-cps cps
  202. (letv name-var var)
  203. (let$ good (have-var var))
  204. (letk kgood ($kargs () () ,good))
  205. (letk kbad ($kargs () () ($throw src 'throw/value %unbound (name-var))))
  206. (let$ body (%lookup kbad kgood src mod-var name-var var assert-bound?))
  207. (letk klookup ($kargs ('name) (name-var) ,body))
  208. (build-term ($continue klookup src ($const name)))))
  209. (define (reify-resolve-module cps k src module public?)
  210. (with-cps cps
  211. (letv mod-name)
  212. (letk kresolve
  213. ($kargs ('mod-name) (mod-name)
  214. ($continue k src
  215. ($primcall 'resolve-module public? (mod-name)))))
  216. (build-term
  217. ($continue kresolve src ($const module)))))
  218. (define-ephemeral (cached-module-box cps k src param)
  219. (match param
  220. ((module name public? bound?)
  221. (let ((cache-key (cons module name)))
  222. (with-cps cps
  223. (letv mod cached)
  224. (let$ lookup
  225. (reify-lookup
  226. src mod name bound?
  227. (lambda (cps var)
  228. (with-cps cps
  229. (letk k* ($kargs () () ($continue k src ($values (var)))))
  230. (build-term
  231. ($continue k* src
  232. ($primcall 'cache-set! cache-key (var))))))))
  233. (letk kmod ($kargs ('mod) (mod) ,lookup))
  234. (let$ module (reify-resolve-module kmod src module public?))
  235. (letk kinit ($kargs () () ,module))
  236. (letk kok ($kargs () () ($continue k src ($values (cached)))))
  237. (letk ktest
  238. ($kargs ('cached) (cached)
  239. ($branch kinit kok src 'heap-object? #f (cached))))
  240. (build-term
  241. ($continue ktest src
  242. ($primcall 'cache-ref cache-key ()))))))))
  243. (define-ephemeral (cache-current-module! cps k src param mod)
  244. (match param
  245. ((scope)
  246. (with-cps cps
  247. (build-term
  248. ($continue k src
  249. ($primcall 'cache-set! scope (mod))))))))
  250. (define-ephemeral (cached-toplevel-box cps k src param)
  251. (match param
  252. ((scope name bound?)
  253. (let ((cache-key (cons scope name)))
  254. (with-cps cps
  255. (letv mod cached)
  256. (let$ lookup
  257. (reify-lookup
  258. src mod name bound?
  259. (lambda (cps var)
  260. (with-cps cps
  261. (letk k* ($kargs () () ($continue k src ($values (var)))))
  262. (build-term
  263. ($continue k* src
  264. ($primcall 'cache-set! cache-key (var))))))))
  265. (letk kmod ($kargs ('mod) (mod) ,lookup))
  266. (letk kinit ($kargs () ()
  267. ($continue kmod src ($primcall 'cache-ref scope ()))))
  268. (letk kok ($kargs () () ($continue k src ($values (cached)))))
  269. (letk ktest
  270. ($kargs ('cached) (cached)
  271. ($branch kinit kok src 'heap-object? #f (cached))))
  272. (build-term
  273. ($continue ktest src
  274. ($primcall 'cache-ref cache-key ()))))))))
  275. ;; FIXME: Instead of having to check this, instead every primcall that's
  276. ;; not ephemeral should be handled by compile-bytecode.
  277. (define (compute-known-primitives)
  278. (define *macro-instructions*
  279. '(add
  280. add/immediate
  281. sub
  282. sub/immediate
  283. mul
  284. div
  285. quo
  286. rem
  287. mod
  288. logand
  289. logior
  290. logxor
  291. logsub
  292. string-set!
  293. string->number
  294. string->symbol
  295. symbol->keyword
  296. class-of
  297. scm->f64 f64->scm
  298. s64->u64 s64->scm scm->s64
  299. u64->s64 u64->scm scm->u64 scm->u64/truncate
  300. wind unwind
  301. push-fluid pop-fluid fluid-ref fluid-set!
  302. push-dynamic-state pop-dynamic-state
  303. lsh rsh lsh/immediate rsh/immediate
  304. cache-ref cache-set!
  305. resolve-module lookup define! current-module))
  306. (let ((table (make-hash-table)))
  307. (for-each
  308. (match-lambda ((inst . _) (hashq-set! table inst #t)))
  309. (instruction-list))
  310. (for-each
  311. (lambda (prim) (hashq-set! table prim #t))
  312. *macro-instructions*)
  313. table))
  314. (define *known-primitives* (delay (compute-known-primitives)))
  315. (define (known-primitive? name)
  316. "Is @var{name} a primitive that can be lowered to bytecode?"
  317. (hashq-ref (force *known-primitives*) name))
  318. (define (reify-primitives cps)
  319. (define (visit-cont label cont cps)
  320. (define (resolve-prim cps name k src)
  321. (cond
  322. ((builtin-name->index name)
  323. => (lambda (idx) (builtin-ref cps idx k src)))
  324. (else
  325. (primitive-ref cps name k src))))
  326. (match cont
  327. (($ $kfun src meta self tail #f)
  328. (with-cps cps
  329. (let$ clause (reify-clause))
  330. (setk label ($kfun src meta self tail clause))))
  331. (($ $kargs names vars ($ $continue k src ($ $prim name)))
  332. (with-cps cps
  333. (let$ body (resolve-prim name k src))
  334. (setk label ($kargs names vars ,body))))
  335. (($ $kargs names vars
  336. ($ $continue k src ($ $primcall 'call-thunk/no-inline #f (proc))))
  337. (with-cps cps
  338. (setk label ($kargs names vars ($continue k src ($call proc ()))))))
  339. (($ $kargs names vars
  340. ($ $continue k src ($ $primcall 'u64->scm/unlikely #f (u64))))
  341. (with-cps cps
  342. (setk label ($kargs names vars
  343. ($continue k src ($primcall 'u64->scm #f (u64)))))))
  344. (($ $kargs names vars
  345. ($ $continue k src ($ $primcall 's64->scm/unlikely #f (s64))))
  346. (with-cps cps
  347. (setk label ($kargs names vars
  348. ($continue k src ($primcall 's64->scm #f (s64)))))))
  349. (($ $kargs names vars
  350. ($ $continue k src ($ $primcall 'tag-fixnum/unlikely #f (s64))))
  351. (with-cps cps
  352. (setk label ($kargs names vars
  353. ($continue k src ($primcall 'tag-fixnum #f (s64)))))))
  354. (($ $kargs names vars
  355. ($ $continue k src ($ $primcall 'load-const/unlikely val ())))
  356. (with-cps cps
  357. (setk label ($kargs names vars ($continue k src ($const val))))))
  358. (($ $kargs names vars
  359. ($ $continue k src ($ $primcall 'mul/immediate b (a))))
  360. (with-cps cps
  361. (letv b*)
  362. (letk kb ($kargs ('b) (b*)
  363. ($continue k src ($primcall 'mul #f (a b*)))))
  364. (setk label ($kargs names vars
  365. ($continue kb src ($const b))))))
  366. (($ $kargs names vars
  367. ($ $continue k src
  368. ($ $primcall (or 'assume-u64 'assume-s64) (lo . hi) (val))))
  369. (with-cps cps
  370. (setk label ($kargs names vars
  371. ($continue k src ($values (val)))))))
  372. (($ $kargs names vars ($ $continue k src ($ $primcall name param args)))
  373. (cond
  374. ((hashq-ref *ephemeral-reifiers* name)
  375. => (lambda (reify)
  376. (with-cps cps
  377. (let$ body (reify k src param args))
  378. (setk label ($kargs names vars ,body)))))
  379. ((known-primitive? name)
  380. ;; Assume arities are correct.
  381. (let ()
  382. (define (u6? val) (and (exact-integer? val) (<= 0 val 63)))
  383. (define (u8? val) (and (exact-integer? val) (<= 0 val 255)))
  384. (define-syntax-rule (reify-constants
  385. wrap
  386. ((op (pred? c) in ...) (op* out ...))
  387. ...
  388. (_ default))
  389. (match name
  390. ('op
  391. (if (pred? param)
  392. cps
  393. (match args
  394. ((in ...)
  395. (with-cps cps
  396. (letv c)
  397. (letk kconst ($kargs ('c) (c)
  398. ($continue k src
  399. ($primcall 'op* #f (out ...)))))
  400. (setk label
  401. ($kargs names vars
  402. ($continue kconst src wrap))))))))
  403. ...
  404. (_ default)))
  405. (define-syntax-rule (reify-scm-constants clause ...)
  406. (reify-constants ($const param) clause ...))
  407. (define-syntax-rule (reify-u64-constants clause ...)
  408. (reify-constants ($primcall 'load-u64 param ()) clause ...))
  409. (reify-scm-constants
  410. ((add/immediate (u8? y) x) (add x y))
  411. ((sub/immediate (u8? y) x) (sub x y))
  412. (_
  413. (reify-u64-constants
  414. ((uadd/immediate (u8? y) x) (uadd x y))
  415. ((usub/immediate (u8? y) x) (usub x y))
  416. ((umul/immediate (u8? y) x) (umul x y))
  417. ((rsh/immediate (u6? y) x) (rsh x y))
  418. ((lsh/immediate (u6? y) x) (lsh x y))
  419. ;; These should all be u6's by construction.
  420. ;; ((ursh/immediate (u6? y) x) (ursh x y))
  421. ;; ((srsh/immediate (u6? y) x) (srsh x y))
  422. ;; ((ulsh/immediate (u6? y) x) (ulsh x y))
  423. (_
  424. (match (cons name args)
  425. (('allocate-words/immediate)
  426. (match param
  427. ((ann . n)
  428. (if (u8? n)
  429. cps
  430. (with-cps cps
  431. (letv n*)
  432. (letk kop ($kargs ('n) (n*)
  433. ($continue k src
  434. ($primcall 'allocate-words ann (n*)))))
  435. (setk label ($kargs names vars
  436. ($continue kop src
  437. ($primcall 'load-u64 n ())))))))))
  438. ;; Assume (tail-)pointer-ref/immediate is within u8 range.
  439. (((or 'word-ref/immediate 'scm-ref/immediate) obj)
  440. (match param
  441. ((ann . idx)
  442. (if (u8? idx)
  443. cps
  444. (let ((op (match name
  445. ('word-ref/immediate 'word-ref)
  446. ('scm-ref/immediate 'scm-ref))))
  447. (with-cps cps
  448. (letv idx*)
  449. (letk kop ($kargs ('idx) (idx*)
  450. ($continue k src
  451. ($primcall op ann (obj idx*)))))
  452. (setk label ($kargs names vars
  453. ($continue kop src
  454. ($primcall 'load-u64 idx ()))))))))))
  455. (((or 'word-set!/immediate 'scm-set!/immediate) obj val)
  456. (match param
  457. ((ann . idx)
  458. (if (u8? idx)
  459. cps
  460. (let ((op (match name
  461. ('word-set!/immediate 'word-set!)
  462. ('scm-set!/immediate 'scm-set!))))
  463. (with-cps cps
  464. (letv idx*)
  465. (letk kop ($kargs ('idx) (idx*)
  466. ($continue k src
  467. ($primcall op ann (obj idx* val)))))
  468. (setk label ($kargs names vars
  469. ($continue kop src
  470. ($primcall 'load-u64 idx ()))))))))))
  471. (_ cps))))))))
  472. (param (error "unexpected param to reified primcall" name))
  473. (else
  474. (with-cps cps
  475. (letv proc)
  476. (letk krecv ($kreceive '(res) #f k))
  477. (letk kproc ($kargs ('proc) (proc)
  478. ($continue krecv src ($call proc args))))
  479. (let$ body (resolve-prim name kproc src))
  480. (setk label ($kargs names vars ,body))))))
  481. (($ $kargs names vars ($ $branch kf kt src name param args))
  482. (let ()
  483. (define (u11? val) (<= 0 val #x7ff))
  484. (define (u12? val) (<= 0 val #xfff))
  485. (define (s12? val) (<= (- #x800) val #x7ff))
  486. (define-syntax-rule (reify-constants ((op (pred? c) in ...)
  487. wrap-op (op* out ...))
  488. ...
  489. (_ default))
  490. (match name
  491. ('op
  492. (if (pred? param)
  493. cps
  494. (match args
  495. ((in ...)
  496. (with-cps cps
  497. (letv c)
  498. (letk kconst
  499. ($kargs ('c) (c)
  500. ($branch kf kt src 'op* #f (out ...))))
  501. (setk label
  502. ($kargs names vars
  503. ($continue kconst src
  504. ($primcall 'wrap-op param ())))))))))
  505. ...
  506. (_ default)))
  507. (reify-constants
  508. ((u64-imm-= (u11? b) a) load-u64 (u64-= a b))
  509. ((u64-imm-< (u12? b) a) load-u64 (u64-< a b))
  510. ((imm-u64-< (u12? a) b) load-u64 (u64-< a b))
  511. ((s64-imm-= (s12? b) a) load-s64 (s64-= a b))
  512. ((s64-imm-< (s12? b) a) load-s64 (s64-< a b))
  513. ((imm-s64-< (s12? a) b) load-s64 (s64-< a b))
  514. (_ cps))))
  515. (($ $kargs names vars ($ $continue k src ($ $call proc args)))
  516. (with-cps cps
  517. (let$ k (uniquify-receive k))
  518. (setk label ($kargs names vars
  519. ($continue k src ($call proc args))))))
  520. (($ $kargs names vars ($ $continue k src ($ $callk k* proc args)))
  521. (with-cps cps
  522. (let$ k (uniquify-receive k))
  523. (setk label ($kargs names vars
  524. ($continue k src ($callk k* proc args))))))
  525. (_ cps)))
  526. (with-fresh-name-state cps
  527. (persistent-intmap (intmap-fold visit-cont cps cps))))