simplify.scm 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. ; Part of Scheme 48 1.9. See file COPYING for notices and license.
  2. ; Authors: Richard Kelsey
  3. ; Post-CPS optimizer. All simplifications are done by changing the
  4. ; structure of the node tree.
  5. ;
  6. ; There are two requirements for the simplifiers:
  7. ; 1) Only the node being simplified and its descendents may be changed.
  8. ; 2) If a node is changed the NODE-SIMPLIFIED? flag of that node and all
  9. ; its ancestors must be set to false.
  10. ; No way to simplify literal or reference nodes.
  11. (define (simplify-node node)
  12. (cond ((call-node? node)
  13. (simplify-call node))
  14. ((lambda-node? node)
  15. (simplify-lambda-body node))))
  16. (define (simplify-global-reference ref)
  17. (let ((value (variable-known-value (reference-variable ref))))
  18. (if value
  19. (replace ref (vector->node value)))))
  20. (define (simplify-lambda-body lambda-node)
  21. (let loop ()
  22. (let ((node (lambda-body lambda-node)))
  23. (cond ((not (node-simplified? node))
  24. (set-node-simplified?! node #t)
  25. (simplify-call node)
  26. (loop))))))
  27. (define (default-simplifier call)
  28. (simplify-args call 0))
  29. ; Utility used by many simplifiers - simplify the specified children.
  30. (define (simplify-args call start)
  31. (let* ((vec (call-args call))
  32. (len (vector-length vec)))
  33. (do ((i start (+ i '1)))
  34. ((>= i len))
  35. (really-simplify-arg vec i))))
  36. ; Keep simplifying a node until it stops changing.
  37. (define (simplify-arg call index)
  38. (really-simplify-arg (call-args call) index))
  39. (define (really-simplify-arg vec index)
  40. (let loop ((node (vector-ref vec index)))
  41. (cond ((not (node-simplified? node))
  42. (set-node-simplified?! node #t)
  43. (case (node-variant node)
  44. ((reference)
  45. (if (global-variable? (reference-variable node))
  46. (simplify-global-reference node)))
  47. ((call)
  48. (simplify-call node))
  49. ((lambda)
  50. (simplify-lambda-body node)))
  51. (loop (vector-ref vec index))))))
  52. ; Remove any unused arguments to L-NODE
  53. ; Could substitute identical arguments as well...
  54. (define (simplify-known-lambda l-node)
  55. (let ((unused (filter (lambda (var) (not (used? var)))
  56. (if (eq? 'proc (lambda-type l-node))
  57. (cdr (lambda-variables l-node))
  58. (lambda-variables l-node)))))
  59. (if (not (null? unused))
  60. (let ((refs (find-calls l-node)))
  61. (for-each (lambda (var)
  62. (let ((index (+ 1 (variable-index var))))
  63. (for-each (lambda (ref)
  64. (remove-ith-argument (node-parent ref)
  65. index
  66. var))
  67. refs)
  68. (remove-variable l-node var)))
  69. unused)))))
  70. ; VAR is used to get the appropriate representation
  71. (define (remove-ith-argument call index var)
  72. (let ((value (detach (call-arg call index))))
  73. (remove-call-arg call index)
  74. (move-body call
  75. (lambda (call)
  76. (let-nodes ((c1 (let 1 l1 value))
  77. (l1 (var) call))
  78. c1)))))