base.scm 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. (define (simplify-letrec1 call)
  4. (let* ((cont (call-arg call 0))
  5. (next (lambda-body cont))
  6. (var (car (lambda-variables cont))))
  7. (if (not (and (calls-this-primop? next 'letrec2)
  8. (= 1 (length (variable-refs var)))
  9. (eq? next (node-parent (car (variable-refs var))))
  10. (= 1 (node-index (car (variable-refs var))))))
  11. (error "badly formed LETREC ~S ~S" call (node-parent call)))
  12. (simplify-args call 0)
  13. (check-letrec-scoping call cont next)
  14. (if (every? unused? (cdr (lambda-variables cont)))
  15. (replace-body call (detach-body (lambda-body (call-arg next 0)))))))
  16. (define (check-letrec-scoping letrec1 binder letrec2)
  17. (let ((values (sub-vector->list (call-args letrec2) 2))
  18. (body (call-arg letrec2 0)))
  19. (for-each (lambda (n) (set-node-flag! n 'okay)) values)
  20. (set-node-flag! body 'okay)
  21. (for-each (lambda (var)
  22. (for-each (lambda (ref)
  23. (set-node-flag! (marked-ancestor ref) 'lose))
  24. (variable-refs var)))
  25. (cdr (lambda-variables binder)))
  26. (let ((non-recur (filter (lambda (p)
  27. (eq? (node-flag (car p)) 'okay))
  28. (map cons values (cdr (lambda-variables binder))))))
  29. (for-each (lambda (n) (set-node-flag! n #f)) values)
  30. (set-node-flag! body #f)
  31. (if (not (null? non-recur))
  32. (letrec->let (map car non-recur)
  33. (map cdr non-recur)
  34. letrec1 binder letrec2)))))
  35. (define (letrec->let vals vars letrec1 binder letrec2)
  36. (for-each detach vals)
  37. (remove-null-arguments letrec2
  38. (- (vector-length (call-args letrec2))
  39. (length vals)))
  40. (set-lambda-variables!
  41. binder
  42. (filter (lambda (v) (not (memq v vars)))
  43. (lambda-variables binder)))
  44. (move-body letrec1
  45. (lambda (letrec1)
  46. (let-nodes ((call (let 1 l1 . vals))
  47. (l1 vars letrec1))
  48. call))))
  49. ; (return (lambda (a) ...) x)
  50. ; =>
  51. ; (let (lambda (a) ...) x)
  52. (define (simplify-ps-return call)
  53. (let ((cont (call-arg call 0))
  54. (value (call-arg call 1)))
  55. (cond ((not (lambda-node? cont))
  56. (default-simplifier call))
  57. (else
  58. (set-call-primop! call (get-primop (enum primop let)))
  59. (set-call-exits! call 1)
  60. (set-node-simplified?! call #f)))))
  61. (make-primop 'dispatch #f #f default-simplifier (lambda (call) 1) #f)
  62. (make-primop 'let #f #f simplify-let (lambda (call) 1) #f)
  63. (make-primop 'letrec1 #f #f (lambda (call)
  64. (simplify-letrec1 call)) (lambda (call) 1) #f)
  65. (make-primop 'letrec2 #f #f default-simplifier (lambda (call) 1) #f)
  66. (make-primop 'undefined-value #t #f default-simplifier
  67. (lambda (call) 1)
  68. (lambda (call) type/null))
  69. (make-primop 'undefined-effect #t #f default-simplifier
  70. (lambda (call) 1)
  71. (lambda (call) type/null))
  72. (make-primop 'global-ref #t 'read default-simplifier
  73. (lambda (call) 1)
  74. (lambda (call)
  75. (variable-type (reference-variable (call-arg call 0)))))
  76. ;(make-primop 'allocate #f #f 'allocate simplify-allocation (lambda (call) 1))
  77. (make-primop 'global-set! #f 'write default-simplifier
  78. (lambda (call) 1) #f)
  79. (make-proc-primop 'call 'write simplify-known-call
  80. (lambda (call) 1) 1)
  81. (make-proc-primop 'tail-call 'write simplify-known-tail-call
  82. (lambda (call) 1) 1)
  83. (make-proc-primop 'return #f simplify-ps-return (lambda (call) 1) 0)
  84. (make-proc-primop 'jump #f simplify-jump (lambda (call) 1) 0)
  85. (make-proc-primop 'throw #f default-simplifier (lambda (call) 1) 0)
  86. ; This delays simplifying the arguments until we see if the procedure
  87. ; is a lambda-node.
  88. (define (simplify-unknown-call call)
  89. (simplify-arg call 1) ; simplify the procedure
  90. (let ((proc (call-arg call 1)))
  91. (cond ((lambda-node? proc)
  92. (determine-lambda-protocol proc (list proc))
  93. (mark-changed proc))
  94. ((and (reference-node? proc)
  95. (variable-simplifier (reference-variable proc)))
  96. => (lambda (proc)
  97. (proc call)))
  98. (else
  99. (simplify-args call 0))))) ; simplify all arguments
  100. (make-proc-primop 'unknown-call 'write simplify-unknown-call
  101. (lambda (call) 1) 1)
  102. (make-proc-primop 'unknown-tail-call 'write simplify-unknown-call
  103. (lambda (call) 1) 1)
  104. (make-proc-primop 'unknown-return #f default-simplifier
  105. (lambda (call) 1) 0)
  106. (define (simplify-unspecific call)
  107. (let ((node (make-undefined-literal)))
  108. (set-literal-type! node type/null)
  109. (replace call node)))
  110. (define-scheme-primop unspecific #f type/null simplify-unspecific)
  111. (define-scheme-primop uninitialized-value type/null)
  112. (define-scheme-primop null-pointer? type/boolean)
  113. (define-polymorphic-scheme-primop null-pointer
  114. (lambda (call)
  115. (literal-value (call-arg call 0))))
  116. (define-scheme-primop eq? type/boolean) ; should have a simplifier
  117. ;(define (exp->type exp)
  118. ; (if (quote-exp? exp)
  119. ; (real-exp->type (quote-exp-value exp))
  120. ; (error "can't turn ~S into a type" exp)))
  121. ;
  122. ;(define (real-exp->type exp)
  123. ; (let ((lose (lambda () (error "can't turn ~S into a type" exp))))
  124. ; (let label ((exp exp))
  125. ; (cond ((pair? exp)
  126. ; (case (car exp)
  127. ; ((pointer)
  128. ; (make-pointer-type (label (cadr exp))))
  129. ; ((arrow)
  130. ; (make-arrow-type (map label (cadr exp)) (caddr exp)))
  131. ; (else
  132. ; (lose))))
  133. ; ((and (symbol? exp)
  134. ; (lookup-type exp))
  135. ; => identity)
  136. ; (else
  137. ; (lose))))))
  138. (define-scheme-cond-primop test simplify-test expand-test simplify-test?)
  139. ;(define-primitive-expander 'unspecific 0
  140. ; (lambda (source args cenv)
  141. ; (make-quote-exp the-undefined-value type/unknown)))