simplify.scm 3.8 KB

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