mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-13 15:10:34 +02:00
mvoe tree-il=? and tree-il-hash to tree-il.scm
* module/language/tree-il.scm (tree-il=?, tree-il-hash): Move these helpers here, from cse.scm. Export them. * module/language/tree-il/cse.scm (cse): Adapt accordingly.
This commit is contained in:
parent
3742d778fb
commit
1fb39dc55f
2 changed files with 76 additions and 64 deletions
|
@ -59,7 +59,10 @@
|
||||||
tree-il-fold
|
tree-il-fold
|
||||||
make-tree-il-folder
|
make-tree-il-folder
|
||||||
post-order!
|
post-order!
|
||||||
pre-order!))
|
pre-order!
|
||||||
|
|
||||||
|
tree-il=?
|
||||||
|
tree-il-hash))
|
||||||
|
|
||||||
(define (print-tree-il exp port)
|
(define (print-tree-il exp port)
|
||||||
(format port "#<tree-il ~S>" (unparse-tree-il exp)))
|
(format port "#<tree-il ~S>" (unparse-tree-il exp)))
|
||||||
|
@ -647,3 +650,67 @@ This is an implementation of `foldts' as described by Andy Wingo in
|
||||||
|
|
||||||
(else #f))
|
(else #f))
|
||||||
x)))
|
x)))
|
||||||
|
|
||||||
|
;; FIXME: We should have a better primitive than this.
|
||||||
|
(define (struct-nfields x)
|
||||||
|
(/ (string-length (symbol->string (struct-layout x))) 2))
|
||||||
|
|
||||||
|
(define (tree-il=? a b)
|
||||||
|
(cond
|
||||||
|
((struct? a)
|
||||||
|
(and (struct? b)
|
||||||
|
(eq? (struct-vtable a) (struct-vtable b))
|
||||||
|
;; Assume that all structs are tree-il, so we skip over the
|
||||||
|
;; src slot.
|
||||||
|
(let lp ((n (1- (struct-nfields a))))
|
||||||
|
(or (zero? n)
|
||||||
|
(and (tree-il=? (struct-ref a n) (struct-ref b n))
|
||||||
|
(lp (1- n)))))))
|
||||||
|
((pair? a)
|
||||||
|
(and (pair? b)
|
||||||
|
(tree-il=? (car a) (car b))
|
||||||
|
(tree-il=? (cdr a) (cdr b))))
|
||||||
|
(else
|
||||||
|
(equal? a b))))
|
||||||
|
|
||||||
|
(define-syntax hash-bits
|
||||||
|
(make-variable-transformer
|
||||||
|
(lambda (x)
|
||||||
|
(syntax-case x ()
|
||||||
|
(var
|
||||||
|
(identifier? #'var)
|
||||||
|
(logcount most-positive-fixnum))))))
|
||||||
|
|
||||||
|
(define (tree-il-hash exp)
|
||||||
|
(let ((hash-depth 4)
|
||||||
|
(hash-width 3))
|
||||||
|
(define (hash-exp exp depth)
|
||||||
|
(define (rotate x bits)
|
||||||
|
(logior (ash x (- bits))
|
||||||
|
(ash (logand x (1- (ash 1 bits))) (- hash-bits bits))))
|
||||||
|
(define (mix h1 h2)
|
||||||
|
(logxor h1 (rotate h2 8)))
|
||||||
|
(define (hash-struct s)
|
||||||
|
(let ((len (struct-nfields s))
|
||||||
|
(h (hashq (struct-vtable s) most-positive-fixnum)))
|
||||||
|
(if (zero? depth)
|
||||||
|
h
|
||||||
|
(let lp ((i (max (- len hash-width) 1)) (h h))
|
||||||
|
(if (< i len)
|
||||||
|
(lp (1+ i) (mix (hash-exp (struct-ref s i) (1+ depth)) h))
|
||||||
|
h)))))
|
||||||
|
(define (hash-list l)
|
||||||
|
(let ((h (hashq 'list most-positive-fixnum)))
|
||||||
|
(if (zero? depth)
|
||||||
|
h
|
||||||
|
(let lp ((l l) (width 0) (h h))
|
||||||
|
(if (< width hash-width)
|
||||||
|
(lp (cdr l) (1+ width)
|
||||||
|
(mix (hash-exp (car l) (1+ depth)) h))
|
||||||
|
h)))))
|
||||||
|
(cond
|
||||||
|
((struct? exp) (hash-struct exp))
|
||||||
|
((list? exp) (hash-list exp))
|
||||||
|
(else (hash exp most-positive-fixnum))))
|
||||||
|
|
||||||
|
(hash-exp exp 0)))
|
||||||
|
|
|
@ -189,67 +189,12 @@
|
||||||
(define (bailout? exp)
|
(define (bailout? exp)
|
||||||
(causes-effects? (compute-effects exp) &definite-bailout))
|
(causes-effects? (compute-effects exp) &definite-bailout))
|
||||||
|
|
||||||
(define (struct-nfields x)
|
|
||||||
(/ (string-length (symbol->string (struct-layout x))) 2))
|
|
||||||
|
|
||||||
(define hash-bits (logcount most-positive-fixnum))
|
|
||||||
(define hash-depth 4)
|
|
||||||
(define hash-width 3)
|
|
||||||
(define (hash-expression exp)
|
|
||||||
(define (hash-exp exp depth)
|
|
||||||
(define (rotate x bits)
|
|
||||||
(logior (ash x (- bits))
|
|
||||||
(ash (logand x (1- (ash 1 bits))) (- hash-bits bits))))
|
|
||||||
(define (mix h1 h2)
|
|
||||||
(logxor h1 (rotate h2 8)))
|
|
||||||
(define (hash-struct s)
|
|
||||||
(let ((len (struct-nfields s))
|
|
||||||
(h (hashq (struct-vtable s) most-positive-fixnum)))
|
|
||||||
(if (zero? depth)
|
|
||||||
h
|
|
||||||
(let lp ((i (max (- len hash-width) 1)) (h h))
|
|
||||||
(if (< i len)
|
|
||||||
(lp (1+ i) (mix (hash-exp (struct-ref s i) (1+ depth)) h))
|
|
||||||
h)))))
|
|
||||||
(define (hash-list l)
|
|
||||||
(let ((h (hashq 'list most-positive-fixnum)))
|
|
||||||
(if (zero? depth)
|
|
||||||
h
|
|
||||||
(let lp ((l l) (width 0) (h h))
|
|
||||||
(if (< width hash-width)
|
|
||||||
(lp (cdr l) (1+ width)
|
|
||||||
(mix (hash-exp (car l) (1+ depth)) h))
|
|
||||||
h)))))
|
|
||||||
(cond
|
|
||||||
((struct? exp) (hash-struct exp))
|
|
||||||
((list? exp) (hash-list exp))
|
|
||||||
(else (hash exp most-positive-fixnum))))
|
|
||||||
(hash-exp exp 0))
|
|
||||||
|
|
||||||
(define (expressions-equal? a b)
|
|
||||||
(cond
|
|
||||||
((struct? a)
|
|
||||||
(and (struct? b)
|
|
||||||
(eq? (struct-vtable a) (struct-vtable b))
|
|
||||||
;; Assume that all structs are tree-il, so we skip over the
|
|
||||||
;; src slot.
|
|
||||||
(let lp ((n (1- (struct-nfields a))))
|
|
||||||
(or (zero? n)
|
|
||||||
(and (expressions-equal? (struct-ref a n) (struct-ref b n))
|
|
||||||
(lp (1- n)))))))
|
|
||||||
((pair? a)
|
|
||||||
(and (pair? b)
|
|
||||||
(expressions-equal? (car a) (car b))
|
|
||||||
(expressions-equal? (cdr a) (cdr b))))
|
|
||||||
(else
|
|
||||||
(equal? a b))))
|
|
||||||
|
|
||||||
(define (hasher n)
|
(define (hasher n)
|
||||||
(lambda (x size) (modulo n size)))
|
(lambda (x size) (modulo n size)))
|
||||||
|
|
||||||
(define (add-to-db exp effects ctx db)
|
(define (add-to-db exp effects ctx db)
|
||||||
(let ((v (vector exp effects ctx))
|
(let ((v (vector exp effects ctx))
|
||||||
(h (hash-expression exp)))
|
(h (tree-il-hash exp)))
|
||||||
(vhash-cons v h db (hasher h))))
|
(vhash-cons v h db (hasher h))))
|
||||||
|
|
||||||
(define (control-flow-boundary db)
|
(define (control-flow-boundary db)
|
||||||
|
@ -260,12 +205,12 @@
|
||||||
(define (entry-matches? v1 v2)
|
(define (entry-matches? v1 v2)
|
||||||
(match (if (vector? v1) v1 v2)
|
(match (if (vector? v1) v1 v2)
|
||||||
(#(exp* effects* ctx*)
|
(#(exp* effects* ctx*)
|
||||||
(and (expressions-equal? exp exp*)
|
(and (tree-il=? exp exp*)
|
||||||
(or (not ctx) (eq? ctx* ctx))))
|
(or (not ctx) (eq? ctx* ctx))))
|
||||||
(_ #f)))
|
(_ #f)))
|
||||||
|
|
||||||
(let ((len (vlist-length db))
|
(let ((len (vlist-length db))
|
||||||
(h (hash-expression exp)))
|
(h (tree-il-hash exp)))
|
||||||
(and (vhash-assoc #t db entry-matches? (hasher h))
|
(and (vhash-assoc #t db entry-matches? (hasher h))
|
||||||
(let lp ((n 0))
|
(let lp ((n 0))
|
||||||
(and (< n len)
|
(and (< n len)
|
||||||
|
@ -282,7 +227,7 @@
|
||||||
(unparse-tree-il exp*) effects* ctx*)
|
(unparse-tree-il exp*) effects* ctx*)
|
||||||
(or (and (= h h*)
|
(or (and (= h h*)
|
||||||
(or (not ctx) (eq? ctx ctx*))
|
(or (not ctx) (eq? ctx ctx*))
|
||||||
(expressions-equal? exp exp*))
|
(tree-il=? exp exp*))
|
||||||
(and (effects-commute? effects effects*)
|
(and (effects-commute? effects effects*)
|
||||||
(lp (1+ n)))))))))))
|
(lp (1+ n)))))))))))
|
||||||
|
|
||||||
|
@ -333,7 +278,7 @@
|
||||||
|
|
||||||
(define (add-to-env exp name sym db env)
|
(define (add-to-env exp name sym db env)
|
||||||
(let* ((v (vector exp name sym (vlist-length db)))
|
(let* ((v (vector exp name sym (vlist-length db)))
|
||||||
(h (hash-expression exp)))
|
(h (tree-il-hash exp)))
|
||||||
(vhash-cons v h env (hasher h))))
|
(vhash-cons v h env (hasher h))))
|
||||||
|
|
||||||
(define (augment-env env names syms exps db)
|
(define (augment-env env names syms exps db)
|
||||||
|
@ -350,7 +295,7 @@
|
||||||
(define (entry-matches? v1 v2)
|
(define (entry-matches? v1 v2)
|
||||||
(match (if (vector? v1) v1 v2)
|
(match (if (vector? v1) v1 v2)
|
||||||
(#(exp* name sym db)
|
(#(exp* name sym db)
|
||||||
(expressions-equal? exp exp*))
|
(tree-il=? exp exp*))
|
||||||
(_ #f)))
|
(_ #f)))
|
||||||
|
|
||||||
(define (unroll db base n)
|
(define (unroll db base n)
|
||||||
|
@ -364,7 +309,7 @@
|
||||||
(and (effects-commute? effects effects*)
|
(and (effects-commute? effects effects*)
|
||||||
(unroll db (1+ base) (1- n)))))))
|
(unroll db (1+ base) (1- n)))))))
|
||||||
|
|
||||||
(let ((h (hash-expression exp)))
|
(let ((h (tree-il-hash exp)))
|
||||||
(and (effect-free? (exclude-effects effects &type-check))
|
(and (effect-free? (exclude-effects effects &type-check))
|
||||||
(vhash-assoc exp env entry-matches? (hasher h))
|
(vhash-assoc exp env entry-matches? (hasher h))
|
||||||
(let ((env-len (vlist-length env))
|
(let ((env-len (vlist-length env))
|
||||||
|
@ -374,7 +319,7 @@
|
||||||
(match (vlist-ref env n)
|
(match (vlist-ref env n)
|
||||||
((#(exp* name sym db-len*) . h*)
|
((#(exp* name sym db-len*) . h*)
|
||||||
(and (unroll db m (- db-len db-len*))
|
(and (unroll db m (- db-len db-len*))
|
||||||
(if (and (= h h*) (expressions-equal? exp* exp))
|
(if (and (= h h*) (tree-il=? exp* exp))
|
||||||
(make-lexical-ref (tree-il-src exp) name sym)
|
(make-lexical-ref (tree-il-src exp) name sym)
|
||||||
(lp (1+ n) (- db-len db-len*))))))))))))
|
(lp (1+ n) (- db-len db-len*))))))))))))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue