flatten.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. ; Definitions are (<variable> . <value>) pairs, where <value> can be any
  4. ; Scheme value. This code walks the values looking for sharing and for
  5. ; closures. Shared values are collected in a list and additional definitions
  6. ; are introduced for the bindings in the environments of closures and for
  7. ; close-compiled versions of any primitives in non-call position. References
  8. ; to closure-bound variables are replaced with references to the newly-created
  9. ; package variables.
  10. (define (flatten-definitions definitions)
  11. (set! *shared* '())
  12. (set! *definitions* '())
  13. (set! *immutable-value-table* (make-value-table))
  14. (set! *closed-compiled-primitives* (make-symbol-table))
  15. (let loop ((defs definitions) (flat '()))
  16. (cond ((not (null? defs))
  17. (let ((var (caar defs))
  18. (value (cdar defs)))
  19. (if (and (variable-set!? var)
  20. (closure? value))
  21. (let ((new (generate-top-variable (variable-name var))))
  22. (loop `((,var . ,new)
  23. (,new . ,value)
  24. . ,defs)
  25. flat))
  26. (loop (cdr defs)
  27. (cons (cons var (flatten-value value))
  28. flat)))))
  29. ((null? *definitions*)
  30. (let ((forms (really-make-forms flat *shared*)))
  31. (set! *shared* #f) ; safety
  32. (set! *closed-compiled-primitives* #f)
  33. (set! *immutable-value-table* #f)
  34. forms))
  35. (else
  36. (let ((defs *definitions*))
  37. (set! *definitions* '())
  38. (loop defs flat))))))
  39. ; <Definitions> is a list of (<variable> . <value>) pairs.
  40. ; <Shared> is a list of all shared objects, each of which must end up being
  41. ; bound to a variable.
  42. (define (really-make-forms definitions shared)
  43. (for-each (lambda (defn)
  44. (let ((var (car defn))
  45. (shared (value-shared (cdr defn))))
  46. (if (and (not (variable-set!? var))
  47. shared
  48. (not (shared-variable shared)))
  49. (set-shared-variable! shared var))))
  50. definitions)
  51. (map definition->form
  52. (append definitions
  53. (shared-values->definitions shared))))
  54. (define variable-set!? (structure-ref forms variable-set!?))
  55. (define (shared-values->definitions shared)
  56. (do ((shared shared (cdr shared))
  57. (defns '() (if (shared-variable (value-shared (car shared)))
  58. defns
  59. (let ((var (generate-top-variable #f)))
  60. (set-shared-variable! (value-shared (car shared)) var)
  61. (cons (cons var (car shared)) defns)))))
  62. ((null? shared)
  63. defns)))
  64. (define (definition->form definition)
  65. (let* ((var (car definition))
  66. (value (cdr definition))
  67. (shared (value-shared value))
  68. (value (if (or (not shared)
  69. (eq? var (shared-variable shared)))
  70. value
  71. (shared-variable shared)))
  72. (clean (clean-value! value)))
  73. ((structure-ref forms make-form)
  74. var
  75. (if (or (node? clean)
  76. (variable? clean))
  77. clean
  78. (make-literal-node clean))
  79. (if (closure? value)
  80. (cdr (shared-saved (closure-temp value))) ; free vars
  81. (stored-value-free-vars clean)))))
  82. (define (make-literal-node value)
  83. (make-node op/literal value))
  84. (define (make-name-node value)
  85. (make-node op/name value))
  86. (define *shared* '())
  87. (define (add-shared! value)
  88. (set! *shared* (cons value *shared*)))
  89. (define *definitions* '())
  90. (define (add-package-definition! value id)
  91. (let ((var (generate-top-variable id)))
  92. (set! *definitions*
  93. (cons (cons var value)
  94. *definitions*))
  95. var))
  96. (define (generate-top-variable maybe-id)
  97. (let ((var (make-global-variable (concatenate-symbol
  98. (if maybe-id
  99. (schemify maybe-id)
  100. 'top.)
  101. (next-top-id))
  102. type/undetermined)))
  103. (set-variable-flags! var
  104. (cons 'generated-top-variable
  105. (variable-flags var)))
  106. var))
  107. (define *next-top-id* 0)
  108. (define (next-top-id)
  109. (let ((id *next-top-id*))
  110. (set! *next-top-id* (+ 1 *next-top-id*))
  111. id))
  112. (define (generated-top-variable? var)
  113. (memq? 'generated-top-variable (variable-flags var)))
  114. (define (stored-value-free-vars value)
  115. (let ((vars '()))
  116. (let label ((value value))
  117. (cond ((variable? value)
  118. (cond ((not (variable-flag value))
  119. (set-variable-flag! value #t)
  120. (set! vars (cons value vars)))
  121. (else
  122. ;(breakpoint "marked variable") ; why did I care?
  123. (values))))
  124. ((vector? value)
  125. (do ((i 0 (+ i 1)))
  126. ((= i (vector-length value)))
  127. (label (vector-ref value i))))
  128. ((pair? value)
  129. (label (car value))
  130. (label (cdr value)))))
  131. (for-each (lambda (var)
  132. (set-variable-flag! var #f))
  133. vars)
  134. vars))
  135. ;----------------------------------------------------------------
  136. ; Finding shared data structures.
  137. (define-record-type shared
  138. ()
  139. (saved
  140. (shared? #f)
  141. (variable #f)))
  142. (define make-shared shared-maker)
  143. (define (value-shared value)
  144. (cond ((pair? value)
  145. (car value))
  146. ((vector? value)
  147. (if (= 0 (vector-length value))
  148. #f
  149. (vector-ref value 0)))
  150. ((closure? value)
  151. (closure-temp value))
  152. (else
  153. #f)))
  154. (define (clean-value! value)
  155. (cond ((pair? value)
  156. (cons (clean-sub-value! (shared-saved (car value)))
  157. (clean-sub-value! (cdr value))))
  158. ((vector? value)
  159. (if (= 0 (vector-length value))
  160. value
  161. (let ((new (make-vector (vector-length value))))
  162. (vector-set! new 0 (clean-sub-value!
  163. (shared-saved (vector-ref value 0))))
  164. (do ((i 1 (+ i 1)))
  165. ((= i (vector-length value)))
  166. (vector-set! new i (clean-sub-value! (vector-ref value i))))
  167. new)))
  168. ((closure? value)
  169. (car (shared-saved (closure-temp value)))) ; flattened version of node
  170. ((node? value)
  171. (if (name-node? value)
  172. (name-node->variable value)
  173. (bug "bad definition value: ~S" value)))
  174. (else
  175. value)))
  176. (define name-node? (node-predicate 'name))
  177. (define (clean-sub-value! value)
  178. (cond ((pair? value)
  179. (let ((shared (car value)))
  180. (cond ((shared-shared? shared)
  181. (shared-variable shared))
  182. (else
  183. (set-car! value (clean-sub-value! (shared-saved shared)))
  184. (set-cdr! value (clean-sub-value! (cdr value)))
  185. value))))
  186. ((vector? value)
  187. (cond ((= 0 (vector-length value))
  188. value)
  189. ((shared-shared? (vector-ref value 0))
  190. (shared-variable (vector-ref value 0)))
  191. (else
  192. (vector-set! value 0 (clean-sub-value!
  193. (shared-saved (vector-ref value 0))))
  194. (do ((i 1 (+ i 1)))
  195. ((= i (vector-length value)))
  196. (vector-set! value i (clean-sub-value! (vector-ref value i))))
  197. value)))
  198. ((closure? value)
  199. (shared-variable (closure-temp value)))
  200. (else
  201. value)))
  202. (define (flatten-value value)
  203. (cond ((immutable? value)
  204. (flatten-immutable-value value))
  205. ((primitive? value)
  206. (primitive->name-node value))
  207. (else
  208. (flatten-value! value)
  209. value)))
  210. (define (flatten-value! value)
  211. (cond ((pair? value)
  212. (check-shared! (car value) flatten-pair! value))
  213. ((vector? value)
  214. (if (not (= 0 (vector-length value)))
  215. (check-shared! (vector-ref value 0) flatten-vector! value)))
  216. ((closure? value)
  217. (check-shared! (closure-temp value) flatten-closure! value))))
  218. (define (check-shared! shared flatten! value)
  219. (cond ((not (shared? shared))
  220. (flatten! value))
  221. ((not (shared-shared? shared))
  222. (set-shared-shared?! shared #t)
  223. (add-shared! value))))
  224. (define *immutable-value-table* #f)
  225. (define (flatten-immutable-value value)
  226. (cond ((pair? value)
  227. (or (shared-immutable-value value car)
  228. (let ((p (cons (car value) (cdr value))))
  229. (table-set! *immutable-value-table* value p)
  230. (flatten-pair! p)
  231. p)))
  232. ((vector? value)
  233. (if (= 0 (vector-length value))
  234. value
  235. (or (shared-immutable-value value (lambda (x) (vector-ref x 0)))
  236. (let ((v (copy-vector value)))
  237. (table-set! *immutable-value-table* value v)
  238. (flatten-vector! v)
  239. v))))
  240. ; no immutable closures
  241. (else
  242. value))) ; no sub-values
  243. (define (shared-immutable-value value accessor)
  244. (cond ((table-ref *immutable-value-table* value)
  245. => (lambda (copy)
  246. (cond ((not (shared-shared? (accessor copy)))
  247. (set-shared-shared?! (accessor copy) #t)
  248. (add-shared! copy)
  249. copy))))
  250. (else
  251. #f)))
  252. (define (flatten-pair! pair)
  253. (let ((temp (car pair))
  254. (shared (make-shared)))
  255. (set-car! pair shared)
  256. (set-shared-saved! shared (flatten-value temp))
  257. (set-cdr! pair (flatten-value (cdr pair)))))
  258. (define (flatten-vector! vector)
  259. (let ((temp (vector-ref vector 0))
  260. (shared (make-shared)))
  261. (vector-set! vector 0 shared)
  262. (set-shared-saved! shared (flatten-value temp))
  263. (do ((i 1 (+ i 1)))
  264. ((= i (vector-length vector)))
  265. (vector-set! vector i (flatten-value (vector-ref vector i))))))
  266. ; Make top-level definitions for the bindings in the closure and then substitute
  267. ; the defined variables within the closure's code. The define variables are
  268. ; saved in the bindings in case they are shared with other closures (both for
  269. ; efficiency and because SET! requires it).
  270. (define (flatten-closure! closure)
  271. (let ((shared (make-shared)))
  272. (for-each flatten-closure-binding! (closure-env closure))
  273. (set-closure-temp! closure shared)
  274. (set-shared-shared?! shared #t) ; closures always need definitions
  275. (add-shared! closure)
  276. (receive (exp free)
  277. (substitute-in-expression (closure-node closure))
  278. (set-shared-saved! shared (cons exp free))
  279. (for-each clear-closure-binding! (closure-env closure)))))
  280. (define (clear-closure-binding! pair)
  281. (node-set! (car pair) 'substitute #f))
  282. ; PAIR is (<name-node> . <value>) if it hasn't been seen before and
  283. ; (<name-node> . <substitute-name-node>) if it has.
  284. (define (flatten-closure-binding! pair)
  285. (let* ((name (car pair))
  286. (subst (if (node? (cdr pair))
  287. (cdr pair)
  288. (let ((subst (make-name-node-subst name (cdr pair))))
  289. (set-cdr! pair subst)
  290. subst))))
  291. (node-set! name 'substitute subst)))
  292. (define (make-name-node-subst name value)
  293. (let ((var (add-package-definition! value (node-form name)))
  294. (subst (make-similar-node name (node-form name))))
  295. (node-set! subst 'binding (make-binding #f var #f))
  296. subst))
  297. (define op/literal (get-operator 'literal))
  298. (define op/name (get-operator 'name))
  299. ;----------------------------------------------------------------
  300. (define *closed-compiled-primitives* #f)
  301. (define (make-primitive-node primitive call?)
  302. (if (and call?
  303. (primitive-expands-in-place? primitive))
  304. (make-node op/primitive primitive)
  305. (let ((name-node (primitive->name-node primitive)))
  306. (note-variable-use! (name-node->variable name-node))
  307. name-node)))
  308. (define (name-node->variable name-node)
  309. (let ((binding (node-ref name-node 'binding)))
  310. (cond ((not (binding? binding))
  311. (bug "unbound variable ~S" (node-form name-node)))
  312. ((primitive? (binding-static binding))
  313. (primitive->name-node (binding-static binding)))
  314. (else
  315. (binding-place binding)))))
  316. (define (primitive->name-node primitive)
  317. (let ((id (primitive-id primitive)))
  318. (or (table-ref *closed-compiled-primitives* id)
  319. (let* ((var (add-package-definition!
  320. (make-top-level-closure
  321. (expand (primitive-source primitive)
  322. prescheme-compiler-env))
  323. id))
  324. (binding (make-binding #f var #f))
  325. (node (make-node op/name id)))
  326. (node-set! node 'binding (make-binding #f var #f))
  327. (table-set! *closed-compiled-primitives* id node)
  328. (set-variable-flags! var (cons 'closed-compiled-primitive
  329. (variable-flags var)))
  330. node))))
  331. (define op/primitive (get-operator 'primitive))
  332. ;----------------------------------------------------------------
  333. (define max-key-depth 5)
  334. (define (value-table-hash-function obj)
  335. (let recur ((obj obj) (depth 0))
  336. (cond ((= depth max-key-depth)
  337. 0)
  338. ((symbol? obj) (string-hash (symbol->string obj)))
  339. ((integer? obj)
  340. (if (< obj 0) (- -1 obj) obj))
  341. ((char? obj) (+ 333 (char->integer obj)))
  342. ((eq? obj #f) 3001)
  343. ((eq? obj #t) 3003)
  344. ((null? obj) 3005)
  345. ((pair? obj)
  346. (+ 3007
  347. (recur (car obj) (- depth 1))
  348. (* 3 (recur (cdr obj) (- depth 1)))))
  349. ((vector? obj)
  350. (let loop ((i 0) (hash (+ 3009 (vector-length obj))))
  351. (if (or (= i (vector-length obj))
  352. (= 0 (- depth i)))
  353. hash
  354. (loop (+ i 1) (+ hash (* i (recur (vector-ref obj i)
  355. (- depth i))))))))
  356. (else (error "value cannot be used as a table key" obj)))))
  357. (define make-value-table
  358. (make-table-maker eq? value-table-hash-function))