mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 13:00:26 +02:00
Predecessors and successors in DFG vectors
* module/language/cps/dfg.scm ($dfg, $block): Record predecessors and successors in vectors instead of in $block data structures. Adapt users.
This commit is contained in:
parent
f49e994b52
commit
21d6d183a9
1 changed files with 31 additions and 46 deletions
|
@ -101,12 +101,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 blocks defs uses min-label nlabels min-var nvars)
|
(make-dfg conts blocks preds succs defs uses min-label nlabels min-var nvars)
|
||||||
dfg?
|
dfg?
|
||||||
;; vector of label -> $kif, $kargs, etc
|
;; vector of label -> $kif, $kargs, etc
|
||||||
(conts dfg-cont-table)
|
(conts dfg-cont-table)
|
||||||
;; vector of label -> $block
|
;; vector of label -> $block
|
||||||
(blocks dfg-blocks)
|
(blocks dfg-blocks)
|
||||||
|
(preds dfg-preds)
|
||||||
|
(succs dfg-succs)
|
||||||
;; vector of var -> def label
|
;; vector of var -> def label
|
||||||
(defs dfg-defs)
|
(defs dfg-defs)
|
||||||
;; vector of var -> (use label ...)
|
;; vector of var -> (use label ...)
|
||||||
|
@ -118,15 +120,10 @@
|
||||||
(nvars dfg-nvars))
|
(nvars dfg-nvars))
|
||||||
|
|
||||||
(define-record-type $block
|
(define-record-type $block
|
||||||
(%make-block scope scope-level preds succs)
|
(make-block scope scope-level)
|
||||||
block?
|
block?
|
||||||
(scope block-scope set-block-scope!)
|
(scope block-scope)
|
||||||
(scope-level block-scope-level set-block-scope-level!)
|
(scope-level block-scope-level))
|
||||||
(preds block-preds set-block-preds!)
|
|
||||||
(succs block-succs set-block-succs!))
|
|
||||||
|
|
||||||
(define (make-block scope scope-level)
|
|
||||||
(%make-block scope scope-level '() '()))
|
|
||||||
|
|
||||||
;; Some analyses assume that the only relevant set of nodes is the set
|
;; Some analyses assume that the only relevant set of nodes is the set
|
||||||
;; that is reachable from some start node. Others need to include nodes
|
;; that is reachable from some start node. Others need to include nodes
|
||||||
|
@ -224,7 +221,7 @@ for quickest convergence."
|
||||||
(when (< n k-count)
|
(when (< n k-count)
|
||||||
(for-each (lambda (succ)
|
(for-each (lambda (succ)
|
||||||
(vector-push! succs n (cfa-k-idx cfa succ)))
|
(vector-push! succs n (cfa-k-idx cfa succ)))
|
||||||
(block-succs (lookup-block (cfa-k-sym cfa n) dfg)))
|
(lookup-successors (cfa-k-sym cfa n) dfg))
|
||||||
(lp (1+ n))))
|
(lp (1+ n))))
|
||||||
|
|
||||||
;; Iterate cfa backwards, to converge quickly.
|
;; Iterate cfa backwards, to converge quickly.
|
||||||
|
@ -324,7 +321,7 @@ BODY for each body continuation in the prompt."
|
||||||
(let ((succ (cfa-k-idx cfa succ)))
|
(let ((succ (cfa-k-idx cfa succ)))
|
||||||
(or (not (bitvector-ref body succ))
|
(or (not (bitvector-ref body succ))
|
||||||
(<= succ n))))
|
(<= succ n))))
|
||||||
(block-succs (lookup-block (cfa-k-sym cfa n) dfg))))
|
(lookup-successors (cfa-k-sym cfa n) dfg)))
|
||||||
(let lp ((n 0))
|
(let lp ((n 0))
|
||||||
(let ((n (bit-position #t body n)))
|
(let ((n (bit-position #t body n)))
|
||||||
(when n
|
(when n
|
||||||
|
@ -334,19 +331,15 @@ BODY for each body continuation in the prompt."
|
||||||
(find-prompt-bodies cfa dfg)))
|
(find-prompt-bodies cfa dfg)))
|
||||||
|
|
||||||
(define* (analyze-control-flow fun dfg #:key reverse? add-handler-preds?)
|
(define* (analyze-control-flow fun dfg #:key reverse? add-handler-preds?)
|
||||||
(define (build-cfa kentry block-succs block-preds forward-cfa)
|
(define (build-cfa kentry lookup-succs lookup-preds forward-cfa)
|
||||||
(define (block-accessor accessor)
|
(define (reachable-preds mapping)
|
||||||
(lambda (k)
|
|
||||||
(accessor (lookup-block k dfg))))
|
|
||||||
(define (reachable-preds mapping accessor)
|
|
||||||
;; It's possible for a predecessor to not be in the mapping, if
|
;; It's possible for a predecessor to not be in the mapping, if
|
||||||
;; the predecessor is not reachable from the entry node.
|
;; the predecessor is not reachable from the entry node.
|
||||||
(lambda (k)
|
(lambda (k)
|
||||||
(filter-map (cut hashq-ref mapping <>)
|
(filter-map (cut hashq-ref mapping <>) (lookup-preds k dfg))))
|
||||||
((block-accessor accessor) k))))
|
|
||||||
(let* ((order (reverse-post-order
|
(let* ((order (reverse-post-order
|
||||||
kentry
|
kentry
|
||||||
(block-accessor block-succs)
|
(lambda (k) (lookup-succs k dfg))
|
||||||
(if forward-cfa
|
(if forward-cfa
|
||||||
(lambda (f seed)
|
(lambda (f seed)
|
||||||
(let lp ((n (cfa-k-count forward-cfa)) (seed seed))
|
(let lp ((n (cfa-k-count forward-cfa)) (seed seed))
|
||||||
|
@ -356,8 +349,7 @@ BODY for each body continuation in the prompt."
|
||||||
(f (cfa-k-sym forward-cfa (1- n)) seed)))))
|
(f (cfa-k-sym forward-cfa (1- n)) seed)))))
|
||||||
(lambda (f seed) seed))))
|
(lambda (f seed) seed))))
|
||||||
(k-map (make-block-mapping order))
|
(k-map (make-block-mapping order))
|
||||||
(preds (convert-predecessors order
|
(preds (convert-predecessors order (reachable-preds k-map)))
|
||||||
(reachable-preds k-map block-preds)))
|
|
||||||
(cfa (make-cfa k-map order preds)))
|
(cfa (make-cfa k-map order preds)))
|
||||||
(when add-handler-preds?
|
(when add-handler-preds?
|
||||||
;; Any expression in the prompt body could cause an abort to the
|
;; Any expression in the prompt body could cause an abort to the
|
||||||
|
@ -385,10 +377,10 @@ BODY for each body continuation in the prompt."
|
||||||
(and entry
|
(and entry
|
||||||
($ $kentry self ($ $cont ktail tail) clauses))))
|
($ $kentry self ($ $cont ktail tail) clauses))))
|
||||||
(if reverse?
|
(if reverse?
|
||||||
(build-cfa ktail block-preds block-succs
|
(build-cfa ktail lookup-predecessors lookup-successors
|
||||||
(analyze-control-flow fun dfg #:reverse? #f
|
(analyze-control-flow fun dfg #:reverse? #f
|
||||||
#:add-handler-preds? #f))
|
#:add-handler-preds? #f))
|
||||||
(build-cfa kentry block-succs block-preds #f)))))
|
(build-cfa kentry lookup-successors lookup-predecessors #f)))))
|
||||||
|
|
||||||
;; Dominator analysis.
|
;; Dominator analysis.
|
||||||
(define-record-type $dominator-analysis
|
(define-record-type $dominator-analysis
|
||||||
|
@ -724,7 +716,7 @@ BODY for each body continuation in the prompt."
|
||||||
(vector-set! syms v (+ n min-var))
|
(vector-set! syms v (+ n min-var))
|
||||||
(for-each (lambda (def)
|
(for-each (lambda (def)
|
||||||
(vector-push! defv (cfa-k-idx cfa def) v))
|
(vector-push! defv (cfa-k-idx cfa def) v))
|
||||||
(block-preds (lookup-block def dfg)))
|
(lookup-predecessors def dfg))
|
||||||
(for-each (lambda (use)
|
(for-each (lambda (use)
|
||||||
(vector-push! usev (cfa-k-idx cfa use) v))
|
(vector-push! usev (cfa-k-idx cfa use) v))
|
||||||
(vector-ref uses n)))))
|
(vector-ref uses n)))))
|
||||||
|
@ -767,7 +759,7 @@ BODY for each body continuation in the prompt."
|
||||||
(newline)
|
(newline)
|
||||||
(lp (1+ n)))))))
|
(lp (1+ n)))))))
|
||||||
|
|
||||||
(define (visit-fun fun conts blocks defs uses min-label min-var global?)
|
(define (visit-fun fun conts blocks preds succs defs uses min-label min-var global?)
|
||||||
(define (add-def! var def-k)
|
(define (add-def! var def-k)
|
||||||
(vector-set! defs (- var min-var) def-k))
|
(vector-set! defs (- var min-var) def-k))
|
||||||
|
|
||||||
|
@ -784,12 +776,8 @@ BODY for each body continuation in the prompt."
|
||||||
(vector-set! blocks (- label min-label) (make-block parent level)))
|
(vector-set! blocks (- label min-label) (make-block parent level)))
|
||||||
|
|
||||||
(define (link-blocks! pred succ)
|
(define (link-blocks! pred succ)
|
||||||
(let ((pred-block (vector-ref blocks (- pred min-label)))
|
(vector-push! succs (- pred min-label) succ)
|
||||||
(succ-block (vector-ref blocks (- succ min-label))))
|
(vector-push! preds (- succ min-label) pred))
|
||||||
(unless (and pred-block succ-block)
|
|
||||||
(error "internal error" pred-block succ-block))
|
|
||||||
(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)
|
||||||
|
@ -825,7 +813,7 @@ BODY for each body continuation in the prompt."
|
||||||
(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
|
(for-each
|
||||||
(cut visit-fun <> conts blocks defs uses min-label min-var global?)
|
(cut visit-fun <> conts blocks preds succs defs uses min-label min-var global?)
|
||||||
funs)
|
funs)
|
||||||
(visit body exp-k))
|
(visit body exp-k))
|
||||||
|
|
||||||
|
@ -852,7 +840,7 @@ BODY for each body continuation in the prompt."
|
||||||
|
|
||||||
(($ $fun)
|
(($ $fun)
|
||||||
(when global?
|
(when global?
|
||||||
(visit-fun exp conts blocks defs uses min-label min-var global?)))
|
(visit-fun exp conts blocks preds succs defs uses min-label min-var global?)))
|
||||||
|
|
||||||
(_ #f)))))
|
(_ #f)))))
|
||||||
|
|
||||||
|
@ -915,10 +903,12 @@ BODY for each body continuation in the prompt."
|
||||||
(nvars (- (1+ max-var) min-var))
|
(nvars (- (1+ max-var) min-var))
|
||||||
(conts (make-vector nlabels #f))
|
(conts (make-vector nlabels #f))
|
||||||
(blocks (make-vector nlabels #f))
|
(blocks (make-vector nlabels #f))
|
||||||
|
(preds (make-vector nlabels '()))
|
||||||
|
(succs (make-vector nlabels '()))
|
||||||
(defs (make-vector nvars #f))
|
(defs (make-vector nvars #f))
|
||||||
(uses (make-vector nvars '())))
|
(uses (make-vector nvars '())))
|
||||||
(visit-fun fun conts blocks defs uses min-label min-var global?)
|
(visit-fun fun conts blocks preds succs defs uses min-label min-var global?)
|
||||||
(make-dfg conts blocks defs uses
|
(make-dfg conts blocks preds succs defs uses
|
||||||
min-label label-count min-var var-count)))))
|
min-label label-count min-var var-count)))))
|
||||||
|
|
||||||
(define (lookup-cont label dfg)
|
(define (lookup-cont label dfg)
|
||||||
|
@ -933,26 +923,23 @@ BODY for each body continuation in the prompt."
|
||||||
(error "Unknown continuation!" k))
|
(error "Unknown continuation!" k))
|
||||||
res))
|
res))
|
||||||
|
|
||||||
(define (lookup-scope-level k dfg)
|
|
||||||
(match (lookup-block k dfg)
|
|
||||||
(($ $block _ scope-level) scope-level)))
|
|
||||||
|
|
||||||
(define (lookup-def var dfg)
|
(define (lookup-def var dfg)
|
||||||
(vector-ref (dfg-defs dfg) (- var (dfg-min-var dfg))))
|
(vector-ref (dfg-defs dfg) (- var (dfg-min-var dfg))))
|
||||||
|
|
||||||
(define (lookup-uses var dfg)
|
(define (lookup-uses var dfg)
|
||||||
(vector-ref (dfg-uses dfg) (- var (dfg-min-var dfg))))
|
(vector-ref (dfg-uses dfg) (- var (dfg-min-var dfg))))
|
||||||
|
|
||||||
|
(define (lookup-scope-level k dfg)
|
||||||
|
(block-scope-level (lookup-block k dfg)))
|
||||||
|
|
||||||
(define (lookup-block-scope k dfg)
|
(define (lookup-block-scope k dfg)
|
||||||
(block-scope (lookup-block k dfg)))
|
(block-scope (lookup-block k dfg)))
|
||||||
|
|
||||||
(define (lookup-predecessors k dfg)
|
(define (lookup-predecessors k dfg)
|
||||||
(match (lookup-block k dfg)
|
(vector-ref (dfg-preds dfg) (- k (dfg-min-label dfg))))
|
||||||
(($ $block _ _ preds succs) preds)))
|
|
||||||
|
|
||||||
(define (lookup-successors k dfg)
|
(define (lookup-successors k dfg)
|
||||||
(match (lookup-block k dfg)
|
(vector-ref (dfg-succs dfg) (- k (dfg-min-label dfg))))
|
||||||
(($ $block _ _ preds succs) succs)))
|
|
||||||
|
|
||||||
(define (find-defining-term sym dfg)
|
(define (find-defining-term sym dfg)
|
||||||
(match (lookup-predecessors (lookup-def sym dfg) dfg)
|
(match (lookup-predecessors (lookup-def sym dfg) dfg)
|
||||||
|
@ -1045,9 +1032,7 @@ BODY for each body continuation in the prompt."
|
||||||
(lp scope))))))))
|
(lp scope))))))))
|
||||||
|
|
||||||
(define (continuation-bound-in? k use-k dfg)
|
(define (continuation-bound-in? k use-k dfg)
|
||||||
(match (lookup-block k dfg)
|
(continuation-scope-contains? (lookup-block-scope k dfg) use-k dfg))
|
||||||
(($ $block def-k)
|
|
||||||
(continuation-scope-contains? def-k use-k dfg))))
|
|
||||||
|
|
||||||
(define (variable-free-in? var k dfg)
|
(define (variable-free-in? var k dfg)
|
||||||
(or-map (lambda (use)
|
(or-map (lambda (use)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue