1 ! Copyright (C) 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs deques dlists kernel locals sequences lexer
4 namespaces functors compiler.cfg.rpo compiler.cfg.utilities
6 IN: compiler.cfg.dataflow-analysis
8 GENERIC: join-sets ( sets dfa -- set )
9 GENERIC: transfer-set ( in-set bb dfa -- out-set )
10 GENERIC: block-order ( cfg dfa -- bbs )
11 GENERIC: successors ( bb dfa -- seq )
12 GENERIC: predecessors ( bb dfa -- seq )
16 MIXIN: dataflow-analysis
18 : <dfa-worklist> ( cfg dfa -- queue )
19 block-order <hashed-dlist> [ push-all-front ] keep ;
21 GENERIC# compute-in-set 2 ( bb out-sets dfa -- set )
23 ! M: kill-block compute-in-set 3drop f ;
25 M:: basic-block compute-in-set ( bb out-sets dfa -- set )
26 bb dfa predecessors [ out-sets at ] map dfa join-sets ;
28 :: update-in-set ( bb in-sets out-sets dfa -- ? )
29 bb out-sets dfa compute-in-set
30 bb in-sets maybe-set-at ; inline
32 GENERIC# compute-out-set 2 ( bb out-sets dfa -- set )
34 ! M: kill-block compute-out-set 3drop f ;
36 M:: basic-block compute-out-set ( bb in-sets dfa -- set )
37 bb in-sets at bb dfa transfer-set ;
39 :: update-out-set ( bb in-sets out-sets dfa -- ? )
40 bb in-sets dfa compute-out-set
41 bb out-sets maybe-set-at ; inline
43 :: dfa-step ( bb in-sets out-sets dfa work-list -- )
44 bb in-sets out-sets dfa update-in-set [
45 bb in-sets out-sets dfa update-out-set [
46 bb dfa successors work-list push-all-front
50 :: run-dataflow-analysis ( cfg dfa -- in-sets out-sets )
52 H{ } clone :> out-sets
53 cfg dfa <dfa-worklist> :> work-list
54 work-list [ in-sets out-sets dfa work-list dfa-step ] slurp-deque
58 M: dataflow-analysis join-sets drop assoc-refine ;
60 FUNCTOR: define-analysis ( name -- )
62 name-analysis DEFINES-CLASS ${name}-analysis
63 name-ins DEFINES ${name}-ins
64 name-outs DEFINES ${name}-outs
65 name-in DEFINES ${name}-in
66 name-out DEFINES ${name}-out
70 SINGLETON: name-analysis
74 : name-in ( bb -- set ) name-ins get at ;
78 : name-out ( bb -- set ) name-outs get at ;
82 ! ! ! Forward dataflow analysis
84 MIXIN: forward-analysis
85 INSTANCE: forward-analysis dataflow-analysis
87 M: forward-analysis block-order drop reverse-post-order ;
88 M: forward-analysis successors drop successors>> ;
89 M: forward-analysis predecessors drop predecessors>> ;
91 FUNCTOR: define-forward-analysis ( name -- )
93 name-analysis IS ${name}-analysis
94 name-ins IS ${name}-ins
95 name-outs IS ${name}-outs
96 compute-name-sets DEFINES compute-${name}-sets
100 INSTANCE: name-analysis forward-analysis
102 : compute-name-sets ( cfg -- )
103 name-analysis run-dataflow-analysis
104 [ name-ins set ] [ name-outs set ] bi* ;
108 ! ! ! Backward dataflow analysis
110 MIXIN: backward-analysis
111 INSTANCE: backward-analysis dataflow-analysis
113 M: backward-analysis block-order drop post-order ;
114 M: backward-analysis successors drop predecessors>> ;
115 M: backward-analysis predecessors drop successors>> ;
117 FUNCTOR: define-backward-analysis ( name -- )
119 name-analysis IS ${name}-analysis
120 name-ins IS ${name}-ins
121 name-outs IS ${name}-outs
122 compute-name-sets DEFINES compute-${name}-sets
126 INSTANCE: name-analysis backward-analysis
128 : compute-name-sets ( cfg -- )
129 \ name-analysis run-dataflow-analysis
130 [ name-outs set ] [ name-ins set ] bi* ;
136 SYNTAX: FORWARD-ANALYSIS:
137 scan [ define-analysis ] [ define-forward-analysis ] bi ;
139 SYNTAX: BACKWARD-ANALYSIS:
140 scan [ define-analysis ] [ define-backward-analysis ] bi ;