simplify.scm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 variable)
  24. #:use-module (ps-compiler node vector)
  25. #:export (simplify-node
  26. default-simplifier
  27. simplify-arg
  28. simplify-args
  29. simplify-lambda-body
  30. simplify-known-lambda))
  31. (define (simplify-node node)
  32. (cond ((call-node? node)
  33. (simplify-call node))
  34. ((lambda-node? node)
  35. (simplify-lambda-body node))))
  36. (define (simplify-global-reference ref)
  37. (let ((value (variable-known-value (reference-variable ref))))
  38. (if value
  39. (replace ref (vector->node value)))))
  40. (define (simplify-lambda-body lambda-node)
  41. (let loop ()
  42. (let ((node (lambda-body lambda-node)))
  43. (cond ((not (node-simplified? node))
  44. (set-node-simplified?! node #t)
  45. (simplify-call node)
  46. (loop))))))
  47. (define (default-simplifier call)
  48. (simplify-args call 0))
  49. ;; Utility used by many simplifiers - simplify the specified children.
  50. (define (simplify-args call start)
  51. (let* ((vec (call-args call))
  52. (len (vector-length vec)))
  53. (do ((i start (+ i '1)))
  54. ((>= i len))
  55. (really-simplify-arg vec i))))
  56. ;; Keep simplifying a node until it stops changing.
  57. (define (simplify-arg call index)
  58. (really-simplify-arg (call-args call) index))
  59. (define (really-simplify-arg vec index)
  60. (let loop ((node (vector-ref vec index)))
  61. (cond ((not (node-simplified? node))
  62. (set-node-simplified?! node #t)
  63. (case (node-variant node)
  64. ((reference)
  65. (if (global-variable? (reference-variable node))
  66. (simplify-global-reference node)))
  67. ((call)
  68. (simplify-call node))
  69. ((lambda)
  70. (simplify-lambda-body node)))
  71. (loop (vector-ref vec index))))))
  72. ;; Remove any unused arguments to L-NODE
  73. ;; Could substitute identical arguments as well...
  74. (define (simplify-known-lambda l-node)
  75. (let ((unused (filter (lambda (var) (not (used? var)))
  76. (if (eq? 'proc (lambda-type l-node))
  77. (cdr (lambda-variables l-node))
  78. (lambda-variables l-node)))))
  79. (if (not (null? unused))
  80. (let ((refs (find-calls l-node)))
  81. (for-each (lambda (var)
  82. (let ((index (+ 1 (variable-index var))))
  83. (for-each (lambda (ref)
  84. (remove-ith-argument (node-parent ref)
  85. index
  86. var))
  87. refs)
  88. (remove-variable l-node var)))
  89. unused)))))
  90. ;; VAR is used to get the appropriate representation
  91. (define (remove-ith-argument call index var)
  92. (let ((value (detach (call-arg call index))))
  93. (remove-call-arg call index)
  94. (move-body call
  95. (lambda (call)
  96. (let-nodes ((c1 (let 1 l1 value))
  97. (l1 (var) call))
  98. c1)))))