; Copyright (c) 1993-1999 by Richard Kelsey. See file COPYING. ; Determining if two nodes are functionally identical. (define (node-equal? n1 n2) (if (call-node? n1) (and (call-node? n2) (call-node-eq? n1 n2)) (value-node-eq? n1 n2))) ; Compare two call nodes. The arguments to the nodes are compared ; starting from the back to do leaf nodes first (usually). (define (call-node-eq? n1 n2) (and (= (call-arg-count n1) (call-arg-count n2)) (= (call-exits n1) (call-exits n2)) (eq? (call-primop n1) (call-primop n2)) (let ((v1 (call-args n1)) (v2 (call-args n2))) (let loop ((i (- (vector-length v1) '1))) (cond ((< i '0) #t) ((node-equal? (vector-ref v1 i) (vector-ref v2 i)) (loop (- i '1))) (else #f)))))) ; Compare two value nodes. Reference nodes are the same if they refer to the ; same variable or if they refer to corresponding variables in the two node ; trees. Primop and literal nodes must be identical. Lambda nodes are compared ; by their own procedure. (define (value-node-eq? n1 n2) (cond ((neq? (node-variant n1) (node-variant n2)) #f) ((reference-node? n1) (let ((v1 (reference-variable n1)) (v2 (reference-variable n2))) (or (eq? v1 v2) (eq? v1 (variable-flag v2))))) ((literal-node? n1) (and (eq? (literal-value n1) (literal-value n2)) (eq? (literal-type n1) (literal-type n2)))) ((lambda-node? n1) (lambda-node-eq? n1 n2)))) ; Lambda nodes are identical if they have identical variable lists and identical ; bodies. The variables of N1 are stored in the flag fields of the variables of ; N2 for the use of VALUE-NODE-EQ?. (define (lambda-node-eq? n1 n2) (let ((v1 (lambda-variables n1)) (v2 (lambda-variables n2))) (let ((ok? (let loop ((v1 v1) (v2 v2)) (cond ((null? v1) (if (null? v2) (call-node-eq? (lambda-body n1) (lambda-body n2)) #f)) ((null? v2) #f) ((variable-eq? (car v1) (car v2)) (loop (cdr v1) (cdr v2))) (else #f))))) (map (lambda (v) (if v (set-variable-flag! v #f))) v2) ok?))) (define (variable-eq? v1 v2) (cond ((not v1) (not v2)) ((not v2) #f) ((eq? (variable-type v1) (variable-type v2)) (set-variable-flag! v2 v1) #t) (else #f)))