mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-30 15:00:21 +02:00
DFG refactor to allow dominator tree construction
* module/language/cps/dfg.scm: Refactor so that we can think about building a dominator tree. Split continuations out of use maps and put them in a separate table, which will have more flow information. (visit-fun): Mark clauses as using their bodies. (lookup-predecessors, lookup-successors): New exports. (find-defining-expression): Add an exception for clauses, now that clauses are in the flow graph. (continuation-bound-in?): Rename from variable-bound-in?, as it can currently only be used for continuations. * module/language/cps/contification.scm (contify): Adapt to use lookup-predecessors and continuation-bound-in?.
This commit is contained in:
parent
6b71a76713
commit
f22979db66
2 changed files with 143 additions and 116 deletions
|
@ -90,7 +90,7 @@
|
||||||
(define (bound-symbol k)
|
(define (bound-symbol k)
|
||||||
(match (lookup-cont k cont-table)
|
(match (lookup-cont k cont-table)
|
||||||
(($ $kargs (_) (sym))
|
(($ $kargs (_) (sym))
|
||||||
(match (lookup-uses k dfg)
|
(match (lookup-predecessors k dfg)
|
||||||
((_)
|
((_)
|
||||||
;; K has one predecessor, the one that defined SYM.
|
;; K has one predecessor, the one that defined SYM.
|
||||||
sym)
|
sym)
|
||||||
|
@ -148,7 +148,7 @@
|
||||||
;; We have a common continuation. High fives!
|
;; We have a common continuation. High fives!
|
||||||
;;
|
;;
|
||||||
;; (1) Find the scope at which to contify.
|
;; (1) Find the scope at which to contify.
|
||||||
(let ((scope (if (variable-bound-in? k term-k dfg)
|
(let ((scope (if (continuation-bound-in? k term-k dfg)
|
||||||
term-k
|
term-k
|
||||||
(lookup-def k dfg))))
|
(lookup-def k dfg))))
|
||||||
;; (2) Mark all SYMs for replacement in calls, and
|
;; (2) Mark all SYMs for replacement in calls, and
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
;;; Many passes rely on a local or global static analysis of a function.
|
;;; Many passes rely on a local or global static analysis of a function.
|
||||||
;;; This module implements a simple data-flow graph (DFG) analysis,
|
;;; This module implements a simple data-flow graph (DFG) analysis,
|
||||||
;;; tracking the definitions and uses of variables and continuations.
|
;;; tracking the definitions and uses of variables and continuations.
|
||||||
;;; It also builds a table of continuations and parent links, to be able
|
;;; It also builds a table of continuations and scope links, to be able
|
||||||
;;; to easily determine if one continuation is in the scope of another,
|
;;; to easily determine if one continuation is in the scope of another,
|
||||||
;;; and to get to the expression inside a continuation.
|
;;; and to get to the expression inside a continuation.
|
||||||
;;;
|
;;;
|
||||||
|
@ -48,13 +48,15 @@
|
||||||
dfg-cont-table
|
dfg-cont-table
|
||||||
lookup-def
|
lookup-def
|
||||||
lookup-uses
|
lookup-uses
|
||||||
|
lookup-predecessors
|
||||||
|
lookup-successors
|
||||||
find-call
|
find-call
|
||||||
call-expression
|
call-expression
|
||||||
find-expression
|
find-expression
|
||||||
find-defining-expression
|
find-defining-expression
|
||||||
find-constant-value
|
find-constant-value
|
||||||
lift-definition!
|
lift-definition!
|
||||||
variable-bound-in?
|
continuation-bound-in?
|
||||||
variable-free-in?
|
variable-free-in?
|
||||||
constant-needs-allocation?
|
constant-needs-allocation?
|
||||||
dead-after-def?
|
dead-after-def?
|
||||||
|
@ -86,14 +88,14 @@
|
||||||
|
|
||||||
;; Data-flow graph for CPS: both for values and continuations.
|
;; Data-flow graph for CPS: both for values and continuations.
|
||||||
(define-record-type $dfg
|
(define-record-type $dfg
|
||||||
(make-dfg conts use-maps uplinks)
|
(make-dfg conts blocks use-maps)
|
||||||
dfg?
|
dfg?
|
||||||
;; hash table of sym -> $kargs, $kif, etc
|
;; hash table of sym -> $kif, $kargs, etc
|
||||||
(conts dfg-cont-table)
|
(conts dfg-cont-table)
|
||||||
|
;; hash table of sym -> $block
|
||||||
|
(blocks dfg-blocks)
|
||||||
;; hash table of sym -> $use-map
|
;; hash table of sym -> $use-map
|
||||||
(use-maps dfg-use-maps)
|
(use-maps dfg-use-maps))
|
||||||
;; hash table of sym -> $parent-link
|
|
||||||
(uplinks dfg-uplinks))
|
|
||||||
|
|
||||||
(define-record-type $use-map
|
(define-record-type $use-map
|
||||||
(make-use-map sym def uses)
|
(make-use-map sym def uses)
|
||||||
|
@ -102,13 +104,21 @@
|
||||||
(def use-map-def)
|
(def use-map-def)
|
||||||
(uses use-map-uses set-use-map-uses!))
|
(uses use-map-uses set-use-map-uses!))
|
||||||
|
|
||||||
(define-record-type $uplink
|
(define-record-type $block
|
||||||
(make-uplink parent level)
|
(%make-block scope scope-level preds succs idom dom-level loop-header)
|
||||||
uplink?
|
block?
|
||||||
(parent uplink-parent)
|
(scope block-scope set-block-scope!)
|
||||||
(level uplink-level))
|
(scope-level block-scope-level set-block-scope-level!)
|
||||||
|
(preds block-preds set-block-preds!)
|
||||||
|
(succs block-succs set-block-succs!)
|
||||||
|
(idom block-idom set-block-idom!)
|
||||||
|
(dom-level block-dom-level set-block-dom-level!)
|
||||||
|
(loop-header block-loop-header set-block-loop-header!))
|
||||||
|
|
||||||
(define (visit-fun fun conts use-maps uplinks global?)
|
(define (make-block scope scope-level)
|
||||||
|
(%make-block scope scope-level '() '() #f #f #f))
|
||||||
|
|
||||||
|
(define (visit-fun fun conts blocks use-maps global?)
|
||||||
(define (add-def! sym def-k)
|
(define (add-def! sym def-k)
|
||||||
(unless def-k
|
(unless def-k
|
||||||
(error "Term outside labelled continuation?"))
|
(error "Term outside labelled continuation?"))
|
||||||
|
@ -120,25 +130,34 @@
|
||||||
((and use-map ($ $use-map sym def uses))
|
((and use-map ($ $use-map sym def uses))
|
||||||
(set-use-map-uses! use-map (cons use-k uses)))))
|
(set-use-map-uses! use-map (cons use-k uses)))))
|
||||||
|
|
||||||
(define (link-parent! k parent)
|
(define* (declare-block! label cont parent
|
||||||
(match (hashq-ref uplinks parent)
|
#:optional (level
|
||||||
(($ $uplink _ level)
|
(1+ (lookup-scope-level parent blocks))))
|
||||||
(hashq-set! uplinks k (make-uplink parent (1+ level))))))
|
(hashq-set! conts label cont)
|
||||||
|
(hashq-set! blocks label (make-block parent level)))
|
||||||
|
|
||||||
|
(define (link-blocks! pred succ)
|
||||||
|
(let ((pred-block (hashq-ref blocks pred))
|
||||||
|
(succ-block (hashq-ref blocks succ)))
|
||||||
|
(unless (and pred-block succ-block)
|
||||||
|
(error "internal error"))
|
||||||
|
(set-block-succs! pred-block (cons succ (block-succs pred-block)))
|
||||||
|
(set-block-preds! succ-block (cons pred (block-preds succ-block)))))
|
||||||
|
|
||||||
(define (visit exp exp-k)
|
(define (visit exp exp-k)
|
||||||
(define (def! sym)
|
(define (def! sym)
|
||||||
(add-def! sym exp-k))
|
(add-def! sym exp-k))
|
||||||
(define (use! sym)
|
(define (use! sym)
|
||||||
(add-use! sym exp-k))
|
(add-use! sym exp-k))
|
||||||
|
(define (use-k! sym)
|
||||||
|
(link-blocks! exp-k sym))
|
||||||
(define (recur exp)
|
(define (recur exp)
|
||||||
(visit exp exp-k))
|
(visit exp exp-k))
|
||||||
(match exp
|
(match exp
|
||||||
(($ $letk (($ $cont k src cont) ...) body)
|
(($ $letk (($ $cont k src cont) ...) body)
|
||||||
;; Set up recursive environment before visiting cont bodies.
|
;; Set up recursive environment before visiting cont bodies.
|
||||||
(for-each (lambda (cont k)
|
(for-each (lambda (cont k)
|
||||||
(def! k)
|
(declare-block! k cont exp-k))
|
||||||
(hashq-set! conts k cont)
|
|
||||||
(link-parent! k exp-k))
|
|
||||||
cont k)
|
cont k)
|
||||||
(for-each visit cont k)
|
(for-each visit cont k)
|
||||||
(recur body))
|
(recur body))
|
||||||
|
@ -148,21 +167,21 @@
|
||||||
(recur body))
|
(recur body))
|
||||||
|
|
||||||
(($ $kif kt kf)
|
(($ $kif kt kf)
|
||||||
(use! kt)
|
(use-k! kt)
|
||||||
(use! kf))
|
(use-k! kf))
|
||||||
|
|
||||||
(($ $ktrunc arity k)
|
(($ $ktrunc arity k)
|
||||||
(use! k))
|
(use-k! k))
|
||||||
|
|
||||||
(($ $letrec names syms funs body)
|
(($ $letrec names syms funs body)
|
||||||
(unless global?
|
(unless global?
|
||||||
(error "$letrec should not be present when building a local DFG"))
|
(error "$letrec should not be present when building a local DFG"))
|
||||||
(for-each def! syms)
|
(for-each def! syms)
|
||||||
(for-each (cut visit-fun <> conts use-maps uplinks global?) funs)
|
(for-each (cut visit-fun <> conts blocks use-maps global?) funs)
|
||||||
(visit body exp-k))
|
(visit body exp-k))
|
||||||
|
|
||||||
(($ $continue k exp)
|
(($ $continue k exp)
|
||||||
(use! k)
|
(use-k! k)
|
||||||
(match exp
|
(match exp
|
||||||
(($ $var sym)
|
(($ $var sym)
|
||||||
(use! sym))
|
(use! sym))
|
||||||
|
@ -179,11 +198,11 @@
|
||||||
|
|
||||||
(($ $prompt escape? tag handler)
|
(($ $prompt escape? tag handler)
|
||||||
(use! tag)
|
(use! tag)
|
||||||
(use! handler))
|
(use-k! handler))
|
||||||
|
|
||||||
(($ $fun)
|
(($ $fun)
|
||||||
(when global?
|
(when global?
|
||||||
(visit-fun exp conts use-maps uplinks global?)))
|
(visit-fun exp conts blocks use-maps global?)))
|
||||||
|
|
||||||
(_ #f)))))
|
(_ #f)))))
|
||||||
|
|
||||||
|
@ -192,44 +211,45 @@
|
||||||
($ $cont kentry src
|
($ $cont kentry src
|
||||||
(and entry
|
(and entry
|
||||||
($ $kentry self ($ $cont ktail _ tail) clauses))))
|
($ $kentry self ($ $cont ktail _ tail) clauses))))
|
||||||
;; Treat the fun continuation as its own parent.
|
(declare-block! kentry entry #f 0)
|
||||||
(add-def! kentry kentry)
|
|
||||||
(add-def! self kentry)
|
(add-def! self kentry)
|
||||||
(hashq-set! uplinks kentry (make-uplink #f 0))
|
|
||||||
(hashq-set! conts kentry entry)
|
|
||||||
|
|
||||||
(add-def! ktail kentry)
|
(declare-block! ktail tail kentry)
|
||||||
(hashq-set! conts ktail tail)
|
|
||||||
(link-parent! ktail kentry)
|
|
||||||
|
|
||||||
(for-each
|
(for-each
|
||||||
(match-lambda
|
(match-lambda
|
||||||
(($ $cont kclause _
|
(($ $cont kclause _
|
||||||
(and clause ($ $kclause arity ($ $cont kbody _ body))))
|
(and clause ($ $kclause arity ($ $cont kbody _ body))))
|
||||||
(add-def! kclause kentry)
|
(declare-block! kclause clause kentry)
|
||||||
(hashq-set! conts kclause clause)
|
(link-blocks! kentry kclause)
|
||||||
(link-parent! kclause kentry)
|
|
||||||
|
|
||||||
(add-def! kbody kclause)
|
(declare-block! kbody body kclause)
|
||||||
(hashq-set! conts kbody body)
|
(link-blocks! kclause kbody)
|
||||||
(link-parent! kbody kclause)
|
|
||||||
|
|
||||||
(visit body kbody)))
|
(visit body kbody)))
|
||||||
|
|
||||||
|
#;
|
||||||
|
(compute-dominator-tree kentry use-maps dnodes)
|
||||||
|
|
||||||
clauses))))
|
clauses))))
|
||||||
|
|
||||||
(define* (compute-dfg fun #:key (global? #t))
|
(define* (compute-dfg fun #:key (global? #t))
|
||||||
(let* ((conts (make-hash-table))
|
(let* ((conts (make-hash-table))
|
||||||
(use-maps (make-hash-table))
|
(blocks (make-hash-table))
|
||||||
(uplinks (make-hash-table)))
|
(use-maps (make-hash-table)))
|
||||||
(visit-fun fun conts use-maps uplinks global?)
|
(visit-fun fun conts blocks use-maps global?)
|
||||||
(make-dfg conts use-maps uplinks)))
|
(make-dfg conts blocks use-maps)))
|
||||||
|
|
||||||
(define (lookup-uplink k uplinks)
|
(define (lookup-block k blocks)
|
||||||
(let ((res (hashq-ref uplinks k)))
|
(let ((res (hashq-ref blocks k)))
|
||||||
(unless res
|
(unless res
|
||||||
(error "Unknown continuation!" k (hash-fold acons '() uplinks)))
|
(error "Unknown continuation!" k (hash-fold acons '() blocks)))
|
||||||
res))
|
res))
|
||||||
|
|
||||||
|
(define (lookup-scope-level k blocks)
|
||||||
|
(match (lookup-block k blocks)
|
||||||
|
(($ $block _ scope-level) scope-level)))
|
||||||
|
|
||||||
(define (lookup-use-map sym use-maps)
|
(define (lookup-use-map sym use-maps)
|
||||||
(let ((res (hashq-ref use-maps sym)))
|
(let ((res (hashq-ref use-maps sym)))
|
||||||
(unless res
|
(unless res
|
||||||
|
@ -238,20 +258,28 @@
|
||||||
|
|
||||||
(define (lookup-def sym dfg)
|
(define (lookup-def sym dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
def)))))
|
def)))))
|
||||||
|
|
||||||
(define (lookup-uses sym dfg)
|
(define (lookup-uses sym dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
uses)))))
|
uses)))))
|
||||||
|
|
||||||
|
(define (lookup-predecessors k dfg)
|
||||||
|
(match (lookup-block k (dfg-blocks dfg))
|
||||||
|
(($ $block _ _ preds succs) preds)))
|
||||||
|
|
||||||
|
(define (lookup-successors k dfg)
|
||||||
|
(match (lookup-block k (dfg-blocks dfg))
|
||||||
|
(($ $block _ _ preds succs) succs)))
|
||||||
|
|
||||||
(define (find-defining-term sym dfg)
|
(define (find-defining-term sym dfg)
|
||||||
(match (lookup-uses (lookup-def sym dfg) dfg)
|
(match (lookup-predecessors (lookup-def sym dfg) dfg)
|
||||||
((def-exp-k)
|
((def-exp-k)
|
||||||
(lookup-cont def-exp-k (dfg-cont-table dfg)))
|
(lookup-cont def-exp-k (dfg-cont-table dfg)))
|
||||||
(else #f)))
|
(else #f)))
|
||||||
|
@ -274,6 +302,7 @@
|
||||||
(match (find-defining-term sym dfg)
|
(match (find-defining-term sym dfg)
|
||||||
(#f #f)
|
(#f #f)
|
||||||
(($ $ktrunc) #f)
|
(($ $ktrunc) #f)
|
||||||
|
(($ $kclause) #f)
|
||||||
(term (find-expression term))))
|
(term (find-expression term))))
|
||||||
|
|
||||||
(define (find-constant-value sym dfg)
|
(define (find-constant-value sym dfg)
|
||||||
|
@ -292,7 +321,7 @@
|
||||||
(($ $letk conts body) (find-exp body))
|
(($ $letk conts body) (find-exp body))
|
||||||
(else term)))
|
(else term)))
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map _ def uses)
|
(($ $use-map _ def uses)
|
||||||
(or-map
|
(or-map
|
||||||
|
@ -315,45 +344,50 @@
|
||||||
(_ #t)))
|
(_ #t)))
|
||||||
uses))))))
|
uses))))))
|
||||||
|
|
||||||
(define (continuation-scope-contains? parent-k k uplinks)
|
(define (continuation-scope-contains? scope-k k blocks)
|
||||||
(match (lookup-uplink parent-k uplinks)
|
(let ((scope-level (lookup-scope-level scope-k blocks)))
|
||||||
(($ $uplink _ parent-level)
|
|
||||||
(let lp ((k k))
|
(let lp ((k k))
|
||||||
(or (eq? parent-k k)
|
(or (eq? scope-k k)
|
||||||
(match (lookup-uplink k uplinks)
|
(match (lookup-block k blocks)
|
||||||
(($ $uplink parent level)
|
(($ $block scope level)
|
||||||
(and (< parent-level level)
|
(and (< scope-level level)
|
||||||
(lp parent)))))))))
|
(lp scope))))))))
|
||||||
|
|
||||||
(define (lift-definition! k parent-k dfg)
|
;; FIXME: Splice preds, succs, dom tree.
|
||||||
|
(define (lift-definition! k scope-k dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-uplink parent-k uplinks)
|
(let ((scope-level (1+ (lookup-scope-level scope-k blocks))))
|
||||||
(($ $uplink parent level)
|
;; Fix parent scope link of K.
|
||||||
(hashq-set! uplinks k
|
(match (lookup-block k blocks)
|
||||||
(make-uplink parent-k (1+ level)))
|
((and block ($ $block))
|
||||||
;; Lift definitions of all conts in K.
|
(set-block-scope! block scope-k)))
|
||||||
|
;; Fix up scope levels of K and all contained scopes.
|
||||||
|
(let update-levels! ((k k) (level scope-level))
|
||||||
|
(match (lookup-block k blocks)
|
||||||
|
((and block ($ $block))
|
||||||
|
(set-block-scope-level! block scope-level)))
|
||||||
(let lp ((cont (lookup-cont k conts)))
|
(let lp ((cont (lookup-cont k conts)))
|
||||||
(match cont
|
(match cont
|
||||||
(($ $letk (($ $cont kid) ...) body)
|
(($ $letk (($ $cont kid) ...) body)
|
||||||
(for-each (cut lift-definition! <> k dfg) kid)
|
(for-each (cut update-levels! <> (1+ scope-level)) kid)
|
||||||
(lp body))
|
(lp body))
|
||||||
(($ $letrec names syms funs body)
|
(($ $letrec names syms funs body)
|
||||||
(lp body))
|
(lp body))
|
||||||
(_ #t))))))))
|
(_ #t))))))))
|
||||||
|
|
||||||
(define (variable-bound-in? var k dfg)
|
(define (continuation-bound-in? k use-k dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map var use-maps)
|
(match (lookup-block k blocks)
|
||||||
(($ $use-map sym def uses)
|
(($ $block def-k)
|
||||||
(continuation-scope-contains? def k uplinks))))))
|
(continuation-scope-contains? def-k use-k blocks))))))
|
||||||
|
|
||||||
(define (variable-free-in? var k dfg)
|
(define (variable-free-in? var k dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(or-map (lambda (use)
|
(or-map (lambda (use)
|
||||||
(continuation-scope-contains? k use uplinks))
|
(continuation-scope-contains? k use blocks))
|
||||||
(match (lookup-use-map var use-maps)
|
(match (lookup-use-map var use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
uses))))))
|
uses))))))
|
||||||
|
@ -366,59 +400,52 @@
|
||||||
;; relationship. See
|
;; relationship. See
|
||||||
;; http://mlton.org/pipermail/mlton/2003-January/023054.html for a
|
;; http://mlton.org/pipermail/mlton/2003-January/023054.html for a
|
||||||
;; deeper discussion.
|
;; deeper discussion.
|
||||||
(define (conservatively-dominates? k1 k2 uplinks)
|
(define (conservatively-dominates? k1 k2 blocks)
|
||||||
(continuation-scope-contains? k1 k2 uplinks))
|
(continuation-scope-contains? k1 k2 blocks))
|
||||||
|
|
||||||
(define (dead-after-def? sym dfg)
|
(define (dead-after-def? sym dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
(null? uses))))))
|
(null? uses))))))
|
||||||
|
|
||||||
(define (dead-after-use? sym use-k dfg)
|
(define (dead-after-use? sym use-k dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
;; If all other uses dominate this use, it is now dead. There
|
;; If all other uses dominate this use, it is now dead. There
|
||||||
;; are other ways for it to be dead, but this is an
|
;; are other ways for it to be dead, but this is an
|
||||||
;; approximation. A better check would be if the successor
|
;; approximation. A better check would be if the successor
|
||||||
;; post-dominates all uses.
|
;; post-dominates all uses.
|
||||||
(and-map (cut conservatively-dominates? <> use-k uplinks)
|
(and-map (cut conservatively-dominates? <> use-k blocks)
|
||||||
uses))))))
|
uses))))))
|
||||||
|
|
||||||
;; A continuation is a "branch" if all of its predecessors are $kif
|
;; A continuation is a "branch" if all of its predecessors are $kif
|
||||||
;; continuations.
|
;; continuations.
|
||||||
(define (branch? k dfg)
|
(define (branch? k dfg)
|
||||||
(match dfg
|
(let ((preds (lookup-predecessors k dfg)))
|
||||||
(($ $dfg conts use-maps uplinks)
|
(and (not (null? preds))
|
||||||
(match (lookup-use-map k use-maps)
|
|
||||||
(($ $use-map sym def uses)
|
|
||||||
(and (not (null? uses))
|
|
||||||
(and-map (lambda (k)
|
(and-map (lambda (k)
|
||||||
(match (lookup-cont k conts)
|
(match (lookup-cont k (dfg-cont-table dfg))
|
||||||
(($ $kif) #t)
|
(($ $kif) #t)
|
||||||
(_ #f)))
|
(_ #f)))
|
||||||
uses)))))))
|
preds))))
|
||||||
|
|
||||||
(define (find-other-branches k dfg)
|
(define (find-other-branches k dfg)
|
||||||
(match dfg
|
|
||||||
(($ $dfg conts use-maps uplinks)
|
|
||||||
(match (lookup-use-map k use-maps)
|
|
||||||
(($ $use-map sym def (uses ..1))
|
|
||||||
(map (lambda (kif)
|
(map (lambda (kif)
|
||||||
(match (lookup-cont kif conts)
|
(match (lookup-cont kif (dfg-cont-table dfg))
|
||||||
(($ $kif (? (cut eq? <> k)) kf)
|
(($ $kif (? (cut eq? <> k)) kf)
|
||||||
kf)
|
kf)
|
||||||
(($ $kif kt (? (cut eq? <> k)))
|
(($ $kif kt (? (cut eq? <> k)))
|
||||||
kt)
|
kt)
|
||||||
(_ (error "Not all predecessors are branches"))))
|
(_ (error "Not all predecessors are branches"))))
|
||||||
uses))))))
|
(lookup-predecessors k dfg)))
|
||||||
|
|
||||||
(define (dead-after-branch? sym branch other-branches dfg)
|
(define (dead-after-branch? sym branch other-branches dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-use-map sym use-maps)
|
(match (lookup-use-map sym use-maps)
|
||||||
(($ $use-map sym def uses)
|
(($ $use-map sym def uses)
|
||||||
(and-map
|
(and-map
|
||||||
|
@ -426,15 +453,15 @@
|
||||||
;; A symbol is dead after a branch if at least one of the
|
;; A symbol is dead after a branch if at least one of the
|
||||||
;; other branches dominates a use of the symbol, and all
|
;; other branches dominates a use of the symbol, and all
|
||||||
;; other uses of the symbol dominate the test.
|
;; other uses of the symbol dominate the test.
|
||||||
(if (or-map (cut conservatively-dominates? <> use-k uplinks)
|
(if (or-map (cut conservatively-dominates? <> use-k blocks)
|
||||||
other-branches)
|
other-branches)
|
||||||
(not (conservatively-dominates? branch use-k uplinks))
|
(not (conservatively-dominates? branch use-k blocks))
|
||||||
(conservatively-dominates? use-k branch uplinks)))
|
(conservatively-dominates? use-k branch blocks)))
|
||||||
uses))))))
|
uses))))))
|
||||||
|
|
||||||
(define (lookup-bound-syms k dfg)
|
(define (lookup-bound-syms k dfg)
|
||||||
(match dfg
|
(match dfg
|
||||||
(($ $dfg conts use-maps uplinks)
|
(($ $dfg conts blocks use-maps)
|
||||||
(match (lookup-cont k conts)
|
(match (lookup-cont k conts)
|
||||||
(($ $kargs names syms body)
|
(($ $kargs names syms body)
|
||||||
syms)))))
|
syms)))))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue