form.scm 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. ; Copyright (c) 1993-2008 by Richard Kelsey. See file COPYING.
  2. ; temporary hack
  3. ;(define enqueue! enqueue)
  4. ;(define dequeue! dequeue)
  5. (define-record-type form
  6. (var ; variable being defined (if any)
  7. (value) ; current value
  8. ;source ; one line of source code
  9. (free) ; variables free in this form
  10. )
  11. (used? ; is the value used in the program
  12. (exported? #f) ; true if the definition in this form is exported
  13. (integrate 'okay) ; one of OKAY, YES, NO, PARTIAL
  14. (aliases '()) ; variables that are aliases for this one
  15. (shadowed '()) ; package variables that should be shadowed here
  16. value-type ; value's type
  17. (dependency-index #f) ; index of this form in the data dependent order
  18. lambdas ; list of all non-cont lambdas in this form
  19. (clients '()) ; forms that use this one's variable
  20. (providers '()) ; forms that define a variable used by this one
  21. (type #f) ; one of LAMBDA, INTEGRATE, INITIALIZE or
  22. ; #F for unfinished forms
  23. merge ; slot used by form-merging code
  24. temp ; handy slot
  25. ))
  26. (define-record-discloser type/form
  27. (lambda (form)
  28. `(form ,(variable-name (form-var form)))))
  29. (define (make-form var value free)
  30. (let ((form (form-maker var value free)))
  31. (if (maybe-variable->form var)
  32. (error "more than one definition of ~S" (variable-name var)))
  33. (set-variable-flags! var `((form . ,form) . ,(variable-flags var)))
  34. form))
  35. (define (pp-one-line x)
  36. (call-with-string-output-port
  37. (lambda (p)
  38. (write-one-line p 70 (lambda (p) (write x p))))))
  39. (define (form-node form)
  40. (let ((value (form-value form)))
  41. (if (node? value)
  42. value
  43. (bug "form's value is not a node ~S ~S" form value))))
  44. (define (set-form-node! form node lambdas)
  45. (set-node-flag! node form)
  46. (set-form-value! form node)
  47. (set-form-lambdas! form lambdas))
  48. (define (node-form node)
  49. (let ((form (node-flag (node-base node))))
  50. (if (form? form)
  51. form
  52. (bug "node ~S (~S) not in any form" node (node-base node)))))
  53. (define (suspend-form-use! form)
  54. (set-form-lambdas! form (make-lambda-list))
  55. (set-node-flag! (form-node form) form))
  56. (define (use-this-form! form)
  57. (initialize-lambdas)
  58. (also-use-this-form! form))
  59. (define (also-use-this-form! form)
  60. (add-lambdas (form-lambdas form))
  61. (set-node-flag! (form-node form) #f))
  62. (define (form-name form)
  63. (variable-name (form-var form)))
  64. (define (make-form-unused! form)
  65. (set-form-type! form 'unused)
  66. (cond ((node? (form-value form))
  67. (erase (form-value form))
  68. (set-form-value! form #f)
  69. (set-form-lambdas! form #f))))
  70. ; notes on writing and reading forms
  71. ; What we really need here are forms.
  72. ; What to do? Can read until there are no missing lambdas = end of form
  73. ; Need the variables as well.
  74. ; (form index type var source? clients providers integrate?)
  75. ; clients and providers are lists of indicies
  76. ; can get lambdas automatically
  77. ;(define (write-cps-file file forms)
  78. ; (let ((port (make-tracking-output-port (open-output-file file))))
  79. ; (reset-pp-cps)
  80. ; (walk (lambda (f)
  81. ; (write-form f port))
  82. ; (sort-list forms
  83. ; (lambda (f1 f2)
  84. ; (< (form-index f1) (form-index f2)))))
  85. ; (close-output-port port)))
  86. ;(define (write-form form port)
  87. ; (format port "(FORM ~D ~S ~S "
  88. ; (form-index form)
  89. ; (form-type form)
  90. ; (form-integrate form))
  91. ; (if (form-var form)
  92. ; (print-variable-name (form-var form) port)
  93. ; (format port "#f"))
  94. ; (format port "~% ~S" (map form-index (form-clients form)))
  95. ; (rereadable-pp-cps (form-value form) port)
  96. ; (format port ")~%~%"))
  97. ;------------------------------------------------------------------------------
  98. ; Put the forms that do not reference any other forms' variables in a queue.
  99. ; Every form gets a list of forms that use its variable and a list of forms
  100. ; whose variables it uses.
  101. (define (sort-forms forms)
  102. (let ((queue (make-queue)))
  103. (for-each (lambda (f)
  104. (set-variable-flag! (form-var f) f))
  105. forms)
  106. (let ((forms (really-remove-unreferenced-forms
  107. forms
  108. set-providers-using-free)))
  109. (for-each (lambda (f)
  110. (if (null? (form-providers f))
  111. (enqueue! queue f)))
  112. (reverse forms))
  113. (for-each (lambda (f)
  114. (set-variable-flag! (form-var f) #f))
  115. forms)
  116. (values forms (make-form-queue queue forms)))))
  117. (define (set-providers-using-free form)
  118. (let loop ((vars (form-free form)) (provs '()))
  119. (cond ((null? vars)
  120. (set-form-providers! form provs))
  121. ((variable-flag (car vars))
  122. => (lambda (prov)
  123. (set-form-clients! prov (cons form (form-clients prov)))
  124. (loop (cdr vars) (cons prov provs))))
  125. (else
  126. (loop (cdr vars) provs)))))
  127. (define (make-form-queue ready forms)
  128. (let ((index 0))
  129. (lambda ()
  130. (let loop ()
  131. (cond ((not (queue-empty? ready))
  132. (let ((form (dequeue! ready)))
  133. (set-form-dependency-index! form index)
  134. (for-each (lambda (f)
  135. (set-form-providers! f (delq! form (form-providers f)))
  136. (if (and (null? (form-providers f))
  137. (not (form-dependency-index f))
  138. (form-used? f))
  139. (enqueue! ready f)))
  140. (form-clients form))
  141. (set! index (+ index 1))
  142. form))
  143. ((find-dependency-loop ready forms)
  144. => (lambda (rest)
  145. (set! forms rest)
  146. (loop)))
  147. (else #f))))))
  148. ; Find a circular dependence between the remaining forms.
  149. (define (find-dependency-loop queue forms)
  150. (let ((forms (do ((forms forms (cdr forms)))
  151. ((or (null? forms)
  152. (not (form-dependency-index (car forms))))
  153. forms))))
  154. (cond ((null? forms)
  155. #f)
  156. (else
  157. ;;(format #t "Dependency loop!~%")
  158. (let ((form (really-find-dependency-loop forms)))
  159. (if (not (every? (lambda (f) (eq? 'no (form-integrate f)))
  160. (form-providers form)))
  161. (set-form-integrate! form 'no))
  162. (set-form-providers! form '())
  163. (enqueue! queue form)
  164. forms)))))
  165. (define (really-find-dependency-loop forms)
  166. (for-each (lambda (f) (set-form-temp! f #f))
  167. forms)
  168. (let label ((form (car forms)))
  169. (cond ((form-temp form)
  170. (break-dependency-loop (filter (lambda (f)
  171. (and (form-temp f) (form-var f)))
  172. forms)))
  173. (else
  174. (set-form-temp! form #t)
  175. (cond ((any-map label (form-providers form))
  176. => (lambda (res)
  177. (set-form-temp! form #f)
  178. res))
  179. (else
  180. (set-form-temp! form #f)
  181. #f))))))
  182. (define (any-map proc list)
  183. (let loop ((list list))
  184. (cond ((null? list)
  185. #f)
  186. ((proc (car list))
  187. => identity)
  188. (else
  189. (loop (cdr list))))))
  190. (define *loop-forms* #f)
  191. (define (break-dependency-loop forms)
  192. (or (first (lambda (f)
  193. (or (every? (lambda (f)
  194. (eq? 'no (form-integrate f)))
  195. (form-providers f))
  196. (memq? f (form-providers f))
  197. (and (scheme-node? (form-value f))
  198. (scheme-literal-node? (form-value f)))))
  199. forms)
  200. (begin (set! *loop-forms* forms)
  201. (let ((f (breakpoint "Break dependency loop: *loop-forms* = ~S" forms)))
  202. (set! *loop-forms* #f)
  203. f))))
  204. (define scheme-literal-node?
  205. (nodes:node-predicate 'literal))
  206. (define scheme-node? nodes:node?)
  207. ;----------------------------------------------------------------
  208. (define (variable-set!? var)
  209. (memq 'set! (variable-flags var)))
  210. (define (note-variable-set!! var)
  211. (if (not (variable-set!? var))
  212. (set-variable-flags! var (cons 'set! (variable-flags var)))))
  213. ;------------------------------------------------------------------------------
  214. ; Turn expression into nodes and simplify it.
  215. ; Still to do:
  216. ; Get representations of data values
  217. ; Need to constant fold vector slots, including detection of modifications
  218. ; and single uses.
  219. (define (expand-and-simplify-form form)
  220. (initialize-lambdas)
  221. (let* ((value (form-value form))
  222. (node (if (variable? value)
  223. (make-reference-node value)
  224. (x->cps (form-value form) (form-name form)))))
  225. (cond ((variable-set!? (form-var form))
  226. (set-form-type! form 'initialize)
  227. (set-form-node! form node '())
  228. "settable")
  229. ((reference-node? node)
  230. (let ((var (reference-variable node)))
  231. (add-known-form-value! form node)
  232. (cond ((maybe-variable->form var)
  233. => (lambda (f)
  234. (set-form-aliases! f
  235. `(,(form-var form)
  236. ,@(form-aliases form)
  237. . ,(form-aliases f))))))
  238. (set-form-type! form 'alias)
  239. (erase node)
  240. (set-form-value! form var)
  241. "alias"))
  242. ((literal-node? node)
  243. (expand-and-simplify-literal node form))
  244. ((lambda-node? node)
  245. (expand-and-simplify-lambda node form))
  246. (else
  247. (bug "funny form value ~S" node)))))
  248. ; This could pay attention to immutability.
  249. (define (atomic? value)
  250. (not (or (vector? value)
  251. (pair? value))))
  252. (define (expand-and-simplify-literal node form)
  253. (let ((value (literal-value node)))
  254. (cond ((unspecific? value)
  255. (format #t "~%Warning: variable `~S' has no value and is not SET!~%"
  256. (form-name form))
  257. (set-form-value! form node)
  258. (set-form-lambdas! form '())
  259. (set-form-integrate! form 'no)
  260. (set-form-type! form 'unused)
  261. "constant")
  262. ((atomic? value)
  263. (add-known-form-value! form node)
  264. (set-form-value! form node)
  265. (set-form-lambdas! form '())
  266. "constant")
  267. (else
  268. (set-form-node! form (stob->node value) '())
  269. (set-form-type! form 'stob)
  270. "consed"))))
  271. ; Make a call node containing the contents of the stob so that any
  272. ; variables will be seen as referenced and any integrable values will
  273. ; be integrated.
  274. ; Only works for vectors at this point.
  275. ; MAKE-VECTOR is a randomly chosen primop, almost anything could be used.
  276. (define (stob->node value)
  277. (let* ((contents '())
  278. (add! (lambda (x) (set! contents (cons x contents)))))
  279. (cond ((vector? value)
  280. (do ((i 0 (+ i 1)))
  281. ((>= i (vector-length value)))
  282. (add! (vector-ref value i))))
  283. (else
  284. (error "unknown kind of stob value ~S" value)))
  285. (let ((call (make-call-node (get-prescheme-primop 'make-vector)
  286. (+ 1 (length contents))
  287. 0))
  288. (node (make-lambda-node 'stob 'init '())))
  289. (attach call 0 (make-literal-node value #f)) ; save for future use
  290. (do ((i 1 (+ i 1))
  291. (cs (reverse contents) (cdr cs)))
  292. ((null? cs))
  293. (let ((x (car cs)))
  294. (attach call i (if (variable? x)
  295. (make-reference-node x)
  296. (make-literal-node x type/unknown)))))
  297. (attach-body node call)
  298. (simplify-args call 1)
  299. node)))
  300. (define (add-known-form-value! form value)
  301. (let ((node (if (variable? value)
  302. (make-reference-node value)
  303. value))
  304. (var (form-var form)))
  305. (set-form-type! form 'integrate)
  306. (cond ((or (literal-node? node)
  307. (reference-node? node)
  308. (and (call-node? node)
  309. (trivial? node)))
  310. (add-variable-known-value! var (node->vector node))
  311. (if (variable? value)
  312. (erase node)))
  313. ((lambda-node? node)
  314. (add-variable-simplifier! var (make-inliner (node->vector node))))
  315. (else
  316. (bug "form's value ~S is not a value" value)))))
  317. (define (make-inliner vector)
  318. (lambda (call)
  319. (let ((proc (call-arg call 1)))
  320. (replace proc (reconstruct-value vector proc call)))))
  321. (define (reconstruct-value value proc call)
  322. (let ((has-type (maybe-follow-uvar (variable-type (reference-variable proc))))
  323. (node (vector->node value)))
  324. (if (type-scheme? has-type)
  325. (instantiate-type&value has-type node proc))
  326. node))
  327. (define (expand-and-simplify-lambda node form)
  328. (simplify-all node (form-name form))
  329. (let ((lambdas (make-lambda-list))
  330. (status (duplicate-form? form node)))
  331. (if status
  332. (add-known-form-value! form node))
  333. (set-form-node! form node lambdas)
  334. (set-form-type! form 'lambda)
  335. (set-form-free! form #f) ; old value no longer valid
  336. status))
  337. (define *duplicate-lambda-size* 10)
  338. (define (set-duplicate-lambda-size! n)
  339. (set! *duplicate-lambda-size* n))
  340. (define (duplicate-form? form node)
  341. (cond ((or (variable-set!? (form-var form))
  342. (eq? 'no (form-integrate form)))
  343. #f)
  344. ((small-node? node *duplicate-lambda-size*)
  345. "small")
  346. ((eq? 'yes (form-integrate form))
  347. "by request")
  348. ; ((called-arguments? node)
  349. ; "called arguments")
  350. (else
  351. #f)))
  352. (define (called-arguments? node)
  353. (any? (lambda (v)
  354. (any? (lambda (n)
  355. (eq? n (called-node (node-parent n))))
  356. (variable-refs v)))
  357. (cdr (lambda-variables node))))
  358. ;------------------------------------------------------------------------------
  359. (define (integrate-stob-form form)
  360. (if (and (eq? 'stob (form-type form))
  361. (elide-aliases! form)
  362. (not (form-exported? form))
  363. (every? cell-use (variable-refs (form-var form))))
  364. (let* ((var (form-var form))
  365. (ref (car (variable-refs var)))
  366. (call (lambda-body (form-value form))))
  367. ; could fold any fixed references - do it later
  368. (cond ((and (null? (cdr (variable-refs var)))
  369. (called-node? (cell-use ref)))
  370. (format #t "computed-goto: ~S~%" (variable-name var))
  371. (make-computed-goto form))))))
  372. (define (cell-use node)
  373. (let ((parent (node-parent node)))
  374. (if (and (call-node? parent)
  375. (eq? 'vector-ref (primop-id (call-primop parent))))
  376. parent
  377. #f)))
  378. (define (elide-aliases! form)
  379. (not (or-map (lambda (f)
  380. (switch-references! (form-var f) (form-var form))
  381. (form-exported? f))
  382. (form-aliases form))))
  383. (define (switch-references! from to)
  384. (for-each (lambda (r)
  385. (set-reference-variable! r to))
  386. (variable-refs from))
  387. (set-variable-refs! to (append (variable-refs from) (variable-refs to))))
  388. ;------------------------------------------------------------------------------
  389. (define (resimplify-form form)
  390. (let ((node (form-value form)))
  391. (cond ((and (node? node)
  392. (not (eq? 'stob (form-type form)))
  393. (not (node-simplified? node)))
  394. (use-this-form! form)
  395. (simplify-node node)
  396. (suspend-form-use! form)))))
  397. ;------------------------------------------------------------------------------
  398. ; This is removes all forms that are not ultimately referenced from some
  399. ; exported form.
  400. (define (add-form-provider! form provider)
  401. (if (not (memq? provider (form-providers form)))
  402. (set-form-providers!
  403. form
  404. (cons provider (form-providers form)))))
  405. (define (variable->form var)
  406. (or (maybe-variable->form var)
  407. (bug "variable ~S has no form" var)))
  408. (define (maybe-variable->form var)
  409. (cond ((flag-assq 'form (variable-flags var))
  410. => cdr)
  411. (else
  412. #f)))
  413. (define (remove-unreferenced-forms forms)
  414. (really-remove-unreferenced-forms forms set-form-providers))
  415. (define (really-remove-unreferenced-forms forms set-form-providers)
  416. (receive (exported others)
  417. (partition-list form-exported? forms)
  418. (for-each (lambda (f)
  419. (set-form-providers! f '())
  420. (set-form-clients! f '())
  421. (set-form-used?! f (form-exported? f)))
  422. forms)
  423. (for-each set-form-providers forms)
  424. (propogate-used?! exported)
  425. (append (remove-unused-forms others) exported)))
  426. (define (set-form-providers form)
  427. (for-each (lambda (n)
  428. (add-form-provider! (node-form n) form))
  429. (variable-refs (form-var form)))
  430. (if (eq? (form-type form) 'alias)
  431. (add-form-provider! form (variable->form (form-value form)))))
  432. (define (propogate-used?! forms)
  433. (let loop ((to-do forms))
  434. (if (not (null? to-do))
  435. (let loop2 ((providers (form-providers (car to-do)))
  436. (to-do (cdr to-do)))
  437. (if (null? providers)
  438. (loop to-do)
  439. (loop2 (cdr providers)
  440. (let ((p (car providers)))
  441. (cond ((form-used? p)
  442. to-do)
  443. (else
  444. (set-form-used?! p #t)
  445. (cons p to-do))))))))))
  446. ; Actually remove forms that are not referenced.
  447. (define (remove-unused-forms forms)
  448. ; (format #t "Removing unused forms~%")
  449. (filter (lambda (f)
  450. (cond ((or (not (form-used? f))
  451. )
  452. ;(let ((value (form-value f)))
  453. ; (and (quote-exp? value)
  454. ; (external-value? (quote-exp-value value))))
  455. ; (format #t " ~S~%" (variable-name (form-var f)))
  456. (erase-variable (form-var f))
  457. (cond ((node? (form-value f))
  458. (erase (form-value f))
  459. (set-form-value! f #f)
  460. (set-form-lambdas! f '())))
  461. #f)
  462. (else #t)))
  463. forms))
  464. ;------------------------------------------------------------
  465. ; Total yucko.
  466. ; (unknown-call (lambda e-vars e-body)
  467. ; protocol
  468. ; (vector-ref x offset)
  469. ; . args)
  470. ; =>
  471. ; (let (lambda ,vars
  472. ; (computed-goto
  473. ; ...
  474. ; (lambda ()
  475. ; (unknown-call (lambda ,copied-evars
  476. ; (jump ,(car vars) ,copied-evars))
  477. ; ,(vector-ref proc-vector i)
  478. ; . ,(cdr vars)))
  479. ; ...
  480. ; '((offsets ...) ...) ; offsets for each continuation
  481. ; ,offset))
  482. ; ,exit
  483. ; . ,args)
  484. (define (make-computed-goto form)
  485. (let* ((ref (car (variable-refs (form-var form))))
  486. (in-form (node-form ref))
  487. (entries (vector->offset-map (call-args (lambda-body (form-node form))))))
  488. (use-this-form! in-form)
  489. (also-use-this-form! form)
  490. (really-make-computed-goto (node-parent ref) entries)
  491. (erase (form-node form))
  492. (set-form-value! form #f)
  493. (set-form-lambdas! form #f)
  494. (simplify-node (form-node in-form))
  495. (suspend-form-use! in-form)))
  496. ; Returns a list ((<node> . <offsets>) ...) where <offsets> are where <node>
  497. ; was found in VECTOR. The first element of VECTOR is a marker which we
  498. ; pretend isn't there.
  499. ;
  500. ; This would be more effective if done by a simplifier after the continuations
  501. ; had been simplified.
  502. (define (vector->offset-map vector)
  503. (let loop ((i 0) (res '()))
  504. (if (= (+ i 1) (vector-length vector))
  505. (reverse (map (lambda (p)
  506. (cons (car p) (reverse (cdr p))))
  507. res))
  508. (let ((n (vector-ref vector (+ i 1))))
  509. (loop (+ i 1)
  510. (cond ((first (lambda (p)
  511. (node-equal? n (car p)))
  512. res)
  513. => (lambda (p)
  514. (set-cdr! p (cons i (cdr p)))
  515. res))
  516. (else
  517. (cons (list n i) res))))))))
  518. (define (really-make-computed-goto vec-ref entries)
  519. (let* ((exits (length entries))
  520. (offset (call-arg vec-ref 1))
  521. (vector-call (node-parent vec-ref))
  522. (args (sub-vector->list (call-args vector-call) 3))
  523. (call (make-call-node (get-prescheme-primop 'computed-goto)
  524. (+ 2 exits)
  525. exits))
  526. (arg-vars (map (lambda (arg) (make-variable 't (node-type arg)))
  527. args))
  528. (protocol (literal-value (call-arg vector-call 2)))
  529. (cont (call-arg vector-call 0)))
  530. (for-each detach args)
  531. (attach call exits (make-literal-node (map cdr entries) #f))
  532. (attach call (+ exits 1) (detach offset))
  533. (receive (top continuations)
  534. (if (reference-node? cont)
  535. (make-computed-goto-tail-conts call args arg-vars entries cont protocol)
  536. (make-computed-goto-conts call args arg-vars entries cont protocol))
  537. (do ((i 0 (+ i 1))
  538. (l continuations (cdr l)))
  539. ((= i exits))
  540. (attach call i (car l)))
  541. (replace-body vector-call top))))
  542. (define (make-computed-goto-tail-conts call args arg-vars entries cont protocol)
  543. (let-nodes ((top (let 1 l1 . args))
  544. (l1 arg-vars call))
  545. (values top (map (lambda (p)
  546. (computed-goto-tail-exit
  547. (detach (car p))
  548. protocol
  549. (reference-variable cont)
  550. arg-vars))
  551. entries))))
  552. (define (computed-goto-tail-exit node protocol cont-var arg-vars)
  553. (let ((args (map make-reference-node arg-vars)))
  554. (let-nodes ((l1 () (unknown-tail-call 0 (* cont-var)
  555. node
  556. '(protocol #f) . args)))
  557. l1)))
  558. (define (make-computed-goto-conts call args arg-vars entries cont protocol)
  559. (let ((cont-vars (lambda-variables cont))
  560. (cont-type (make-arrow-type (map variable-type
  561. (lambda-variables cont))
  562. type/null)))
  563. (detach cont)
  564. (change-lambda-type cont 'jump)
  565. (let-nodes ((top (let 1 l1 cont . args))
  566. (l1 ((j cont-type) . arg-vars) call))
  567. (values top
  568. (map (lambda (p)
  569. (computed-goto-exit (detach (car p))
  570. protocol
  571. arg-vars
  572. j
  573. cont-vars))
  574. entries)))))
  575. (define (computed-goto-exit node protocol arg-vars cont-var cont-vars)
  576. (let* ((cont-vars (map copy-variable cont-vars))
  577. (cont-args (map make-reference-node cont-vars))
  578. (args (map make-reference-node arg-vars)))
  579. (let-nodes ((l1 () (unknown-call 1 l2 node '(protocol #f) . args))
  580. (l2 cont-vars (jump 0 (* cont-var) . cont-args)))
  581. l1)))