mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-13 15:10:34 +02:00
The reference graph in `-Wunused-toplevel' may contain cycles.
* module/language/tree-il/analyze.scm (<reference-graph>, dag-reachable-nodes, dag-reachable-nodes*, unused-toplevel-analysis): Replace occurrences of "dag" by "graph".
This commit is contained in:
parent
c5661d2860
commit
628ddb80aa
1 changed files with 43 additions and 43 deletions
|
@ -642,20 +642,20 @@ accurate information is missing from a given `tree-il' element."
|
||||||
;;; Unused top-level variable analysis.
|
;;; Unused top-level variable analysis.
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
;; <reference-dag> record top-level definitions that are made, references to
|
;; <reference-graph> record top-level definitions that are made, references to
|
||||||
;; top-level definitions and their context (the top-level definition in which
|
;; top-level definitions and their context (the top-level definition in which
|
||||||
;; the reference appears), as well as the current context (the top-level
|
;; the reference appears), as well as the current context (the top-level
|
||||||
;; definition we're currently in). The second part (`refs' below) is
|
;; definition we're currently in). The second part (`refs' below) is
|
||||||
;; effectively a DAG from which we can determine unused top-level definitions.
|
;; effectively a graph from which we can determine unused top-level definitions.
|
||||||
(define-record-type <reference-dag>
|
(define-record-type <reference-graph>
|
||||||
(make-reference-dag refs defs toplevel-context)
|
(make-reference-graph refs defs toplevel-context)
|
||||||
reference-dag?
|
reference-graph?
|
||||||
(defs reference-dag-defs) ;; ((NAME . LOC) ...)
|
(defs reference-graph-defs) ;; ((NAME . LOC) ...)
|
||||||
(refs reference-dag-refs) ;; ((REF-CONTEXT REF ...) ...)
|
(refs reference-graph-refs) ;; ((REF-CONTEXT REF ...) ...)
|
||||||
(toplevel-context reference-dag-toplevel-context)) ;; NAME | #f
|
(toplevel-context reference-graph-toplevel-context)) ;; NAME | #f
|
||||||
|
|
||||||
(define (dag-reachable-nodes root refs)
|
(define (graph-reachable-nodes root refs)
|
||||||
;; Return the list of nodes reachable from ROOT in DAG REFS. REFS is an alist
|
;; Return the list of nodes reachable from ROOT in graph REFS. REFS is an alist
|
||||||
;; representing edges: ((A B C) (B A) (C)) corresponds to
|
;; representing edges: ((A B C) (B A) (C)) corresponds to
|
||||||
;;
|
;;
|
||||||
;; ,-------.
|
;; ,-------.
|
||||||
|
@ -681,26 +681,26 @@ accurate information is missing from a given `tree-il' element."
|
||||||
result
|
result
|
||||||
children))))))))
|
children))))))))
|
||||||
|
|
||||||
(define (dag-reachable-nodes* roots refs)
|
(define (graph-reachable-nodes* roots refs)
|
||||||
;; Return the list of nodes in REFS reachable from the nodes listed in ROOTS.
|
;; Return the list of nodes in REFS reachable from the nodes listed in ROOTS.
|
||||||
;; FIXME: Choose a more efficient algorithm.
|
;; FIXME: Choose a more efficient algorithm.
|
||||||
(apply lset-union eq?
|
(apply lset-union eq?
|
||||||
(map (lambda (node)
|
(map (lambda (node)
|
||||||
(cons node (dag-reachable-nodes node refs)))
|
(cons node (graph-reachable-nodes node refs)))
|
||||||
roots)))
|
roots)))
|
||||||
|
|
||||||
(define unused-toplevel-analysis
|
(define unused-toplevel-analysis
|
||||||
;; Report unused top-level definitions that are not exported.
|
;; Report unused top-level definitions that are not exported.
|
||||||
(let ((add-ref-from-context
|
(let ((add-ref-from-context
|
||||||
(lambda (dag name)
|
(lambda (graph name)
|
||||||
;; Add an edge CTX -> NAME in DAG.
|
;; Add an edge CTX -> NAME in GRAPH.
|
||||||
(let* ((refs (reference-dag-refs dag))
|
(let* ((refs (reference-graph-refs graph))
|
||||||
(defs (reference-dag-defs dag))
|
(defs (reference-graph-defs graph))
|
||||||
(ctx (reference-dag-toplevel-context dag))
|
(ctx (reference-graph-toplevel-context graph))
|
||||||
(ctx-refs (or (assoc-ref refs ctx) '())))
|
(ctx-refs (or (assoc-ref refs ctx) '())))
|
||||||
(make-reference-dag (alist-cons ctx (cons name ctx-refs)
|
(make-reference-graph (alist-cons ctx (cons name ctx-refs)
|
||||||
(alist-delete ctx refs eq?))
|
(alist-delete ctx refs eq?))
|
||||||
defs ctx)))))
|
defs ctx)))))
|
||||||
(define (macro-variable? name env)
|
(define (macro-variable? name env)
|
||||||
(and (module? env)
|
(and (module? env)
|
||||||
(let ((var (module-variable env name)))
|
(let ((var (module-variable env name)))
|
||||||
|
@ -708,44 +708,44 @@ accurate information is missing from a given `tree-il' element."
|
||||||
(macro? (variable-ref var))))))
|
(macro? (variable-ref var))))))
|
||||||
|
|
||||||
(make-tree-analysis
|
(make-tree-analysis
|
||||||
(lambda (x dag env locs)
|
(lambda (x graph env locs)
|
||||||
;; X is a leaf.
|
;; X is a leaf.
|
||||||
(let ((ctx (reference-dag-toplevel-context dag)))
|
(let ((ctx (reference-graph-toplevel-context graph)))
|
||||||
(record-case x
|
(record-case x
|
||||||
((<toplevel-ref> name src)
|
((<toplevel-ref> name src)
|
||||||
(add-ref-from-context dag name))
|
(add-ref-from-context graph name))
|
||||||
(else dag))))
|
(else graph))))
|
||||||
|
|
||||||
(lambda (x dag env locs)
|
(lambda (x graph env locs)
|
||||||
;; Going down into X.
|
;; Going down into X.
|
||||||
(let ((ctx (reference-dag-toplevel-context dag))
|
(let ((ctx (reference-graph-toplevel-context graph))
|
||||||
(refs (reference-dag-refs dag))
|
(refs (reference-graph-refs graph))
|
||||||
(defs (reference-dag-defs dag)))
|
(defs (reference-graph-defs graph)))
|
||||||
(record-case x
|
(record-case x
|
||||||
((<toplevel-define> name src)
|
((<toplevel-define> name src)
|
||||||
(let ((refs refs)
|
(let ((refs refs)
|
||||||
(defs (alist-cons name (or src (find pair? locs))
|
(defs (alist-cons name (or src (find pair? locs))
|
||||||
defs)))
|
defs)))
|
||||||
(make-reference-dag refs defs name)))
|
(make-reference-graph refs defs name)))
|
||||||
((<toplevel-set> name src)
|
((<toplevel-set> name src)
|
||||||
(add-ref-from-context dag name))
|
(add-ref-from-context graph name))
|
||||||
(else dag))))
|
(else graph))))
|
||||||
|
|
||||||
(lambda (x dag env locs)
|
(lambda (x graph env locs)
|
||||||
;; Leaving X's scope.
|
;; Leaving X's scope.
|
||||||
(record-case x
|
(record-case x
|
||||||
((<toplevel-define>)
|
((<toplevel-define>)
|
||||||
(let ((refs (reference-dag-refs dag))
|
(let ((refs (reference-graph-refs graph))
|
||||||
(defs (reference-dag-defs dag)))
|
(defs (reference-graph-defs graph)))
|
||||||
(make-reference-dag refs defs #f)))
|
(make-reference-graph refs defs #f)))
|
||||||
(else dag)))
|
(else graph)))
|
||||||
|
|
||||||
(lambda (dag env)
|
(lambda (graph env)
|
||||||
;; Process the resulting reference DAG: determine all private definitions
|
;; Process the resulting reference graph: determine all private definitions
|
||||||
;; not reachable from any public definition. Macros
|
;; not reachable from any public definition. Macros
|
||||||
;; (syntax-transformers), which are globally bound, never considered
|
;; (syntax-transformers), which are globally bound, never considered
|
||||||
;; unused since we can't tell whether a macro is actually used; in
|
;; unused since we can't tell whether a macro is actually used; in
|
||||||
;; addition, macros are considered roots of the DAG since they may use
|
;; addition, macros are considered roots of the graph since they may use
|
||||||
;; private bindings. FIXME: The `make-syntax-transformer' calls don't
|
;; private bindings. FIXME: The `make-syntax-transformer' calls don't
|
||||||
;; contain any literal `toplevel-ref' of the global bindings they use so
|
;; contain any literal `toplevel-ref' of the global bindings they use so
|
||||||
;; this strategy fails.
|
;; this strategy fails.
|
||||||
|
@ -759,10 +759,10 @@ accurate information is missing from a given `tree-il' element."
|
||||||
(let ((name (car name+src)))
|
(let ((name (car name+src)))
|
||||||
(or (exported? name)
|
(or (exported? name)
|
||||||
(macro-variable? name env))))
|
(macro-variable? name env))))
|
||||||
(reference-dag-defs dag))))
|
(reference-graph-defs graph))))
|
||||||
(let* ((roots (cons #f (map car public-defs)))
|
(let* ((roots (cons #f (map car public-defs)))
|
||||||
(refs (reference-dag-refs dag))
|
(refs (reference-graph-refs graph))
|
||||||
(reachable (dag-reachable-nodes* roots refs))
|
(reachable (graph-reachable-nodes* roots refs))
|
||||||
(unused (filter (lambda (name+src)
|
(unused (filter (lambda (name+src)
|
||||||
;; FIXME: This is inefficient when
|
;; FIXME: This is inefficient when
|
||||||
;; REACHABLE is large (e.g., boot-9.scm);
|
;; REACHABLE is large (e.g., boot-9.scm);
|
||||||
|
@ -775,7 +775,7 @@ accurate information is missing from a given `tree-il' element."
|
||||||
(warning 'unused-toplevel loc name)))
|
(warning 'unused-toplevel loc name)))
|
||||||
(reverse unused)))))
|
(reverse unused)))))
|
||||||
|
|
||||||
(make-reference-dag '() '() #f))))
|
(make-reference-graph '() '() #f))))
|
||||||
|
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue