123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 |
- ;;; Ported from Scheme 48 1.9. See file COPYING for notices and license.
- ;;;
- ;;; Port Author: Andrew Whatson
- ;;;
- ;;; Original Authors: Richard Kelsey
- ;;;
- ;;; scheme48-1.9.2/ps-compiler/simp/simplify.scm
- ;;;
- ;;; Post-CPS optimizer. All simplifications are done by changing the
- ;;; structure of the node tree.
- ;;;
- ;;; There are two requirements for the simplifiers:
- ;;; 1) Only the node being simplified and its descendents may be changed.
- ;;; 2) If a node is changed the NODE-SIMPLIFIED? flag of that node and all
- ;;; its ancestors must be set to false.
- ;;;
- ;;; No way to simplify literal or reference nodes.
- (define-module (ps-compiler simp simplify)
- #:use-module (ps-compiler node let-nodes)
- #:use-module (ps-compiler node node)
- #:use-module (ps-compiler node node-util)
- #:use-module (ps-compiler node primop)
- #:use-module (ps-compiler node variable)
- #:use-module (ps-compiler node vector)
- #:export (simplify-node
- default-simplifier
- simplify-arg
- simplify-args
- simplify-lambda-body
- simplify-known-lambda))
- (define (simplify-node node)
- (cond ((call-node? node)
- (simplify-call node))
- ((lambda-node? node)
- (simplify-lambda-body node))))
- (define (simplify-global-reference ref)
- (let ((value (variable-known-value (reference-variable ref))))
- (if value
- (replace ref (vector->node value)))))
- (define (simplify-lambda-body lambda-node)
- (let loop ()
- (let ((node (lambda-body lambda-node)))
- (cond ((not (node-simplified? node))
- (set-node-simplified?! node #t)
- (simplify-call node)
- (loop))))))
- (define (default-simplifier call)
- (simplify-args call 0))
- ;; Utility used by many simplifiers - simplify the specified children.
- (define (simplify-args call start)
- (let* ((vec (call-args call))
- (len (vector-length vec)))
- (do ((i start (+ i '1)))
- ((>= i len))
- (really-simplify-arg vec i))))
- ;; Keep simplifying a node until it stops changing.
- (define (simplify-arg call index)
- (really-simplify-arg (call-args call) index))
- (define (really-simplify-arg vec index)
- (let loop ((node (vector-ref vec index)))
- (cond ((not (node-simplified? node))
- (set-node-simplified?! node #t)
- (case (node-variant node)
- ((reference)
- (if (global-variable? (reference-variable node))
- (simplify-global-reference node)))
- ((call)
- (simplify-call node))
- ((lambda)
- (simplify-lambda-body node)))
- (loop (vector-ref vec index))))))
- ;; Remove any unused arguments to L-NODE
- ;; Could substitute identical arguments as well...
- (define (simplify-known-lambda l-node)
- (let ((unused (filter (lambda (var) (not (used? var)))
- (if (eq? 'proc (lambda-type l-node))
- (cdr (lambda-variables l-node))
- (lambda-variables l-node)))))
- (if (not (null? unused))
- (let ((refs (find-calls l-node)))
- (for-each (lambda (var)
- (let ((index (+ 1 (variable-index var))))
- (for-each (lambda (ref)
- (remove-ith-argument (node-parent ref)
- index
- var))
- refs)
- (remove-variable l-node var)))
- unused)))))
- ;; VAR is used to get the appropriate representation
- (define (remove-ith-argument call index var)
- (let ((value (detach (call-arg call index))))
- (remove-call-arg call index)
- (move-body call
- (lambda (call)
- (let-nodes ((c1 (let 1 l1 value))
- (l1 (var) call))
- c1)))))
|