5 redef class AnalysisManager
6 fun do_reaching_defs_analysis
(cfg
: CFG)
8 cfg
.start
.backup_reaching_defs_out
= new ReachingDefsMap
9 var reaching_defs_analysis
= new ReachingDefsAnalysis
10 reaching_defs_analysis
.analyze
(cfg
)
14 class ReachingDefsAnalysis
15 super FineFlowAnalysis[ReachingDefsMap]
17 redef fun is_forward
do return true
19 redef fun visit
( node
)
21 node
.accept_reaching_defs_analysis
( self, current_in
, current_out
.as(not null) )
25 if a
== null then return b
26 if b
== null then return a
30 redef fun backup_in
(bb
) do return bb
.backup_reaching_defs_in
31 redef fun backup_out
(bb
) do return bb
.backup_reaching_defs_out
32 redef fun backup_in
=(bb
, v
) do bb
.backup_reaching_defs_in
= v
33 redef fun backup_out
=(bb
, v
) do bb
.backup_reaching_defs_out
= v
35 redef fun line_in
(line
) do return line
.reaching_defs_in
36 redef fun line_out
(line
) do return line
.reaching_defs_out
37 redef fun line_in
=(line
, v
) do line
.reaching_defs_in
= v
38 redef fun line_out
=(line
, v
) do line
.reaching_defs_out
= v
40 redef fun default_in_set
do return new ReachingDefsMap
41 redef fun empty_set
do return new ReachingDefsMap
45 fun accept_reaching_defs_analysis
(v
: ReachingDefsAnalysis, ins
: nullable ReachingDefsMap, outs
: ReachingDefsMap) do visit_all
(v
)
48 redef class AInstruction
49 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
51 if ins
!= null then outs
.add_all
(ins
)
55 redef class ALoadInstruction
56 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
58 if ins
!= null then outs
.add_all
(ins
)
60 var variable
= def_var
61 if variable
!= null then
63 var set
= new HashSet[ALine]
64 set
.add
(parent
.as(ALine))
72 redef class AStoreInstruction
73 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
75 if ins
!= null then outs
.add_all
(ins
)
77 var variable
= def_var
78 if variable
!= null then
80 var set
= new HashSet[ALine]
81 set
.add
(parent
.as(ALine))
90 super HashMap[Var,Set[ALine]]
92 fun union
(o
: ReachingDefsMap): ReachingDefsMap
94 var n
= new ReachingDefsMap
96 n
[k
] = new HashSet[ALine]
100 if not n
.has_key
(k
) then n
[k
] = new HashSet[ALine]
106 fun intersection
(o
: ReachingDefsMap): ReachingDefsMap
108 var n
= new ReachingDefsMap
109 for k
, v
in self do if n
.has_key
(k
) then n
[k
].add_all
(v
)
110 for k
, v
in o
do if n
.has_key
(k
) then n
[k
].add_all
(v
)
114 redef fun to_s
do return join
(";", ":")
118 if o
!= null and o
isa ReachingDefsMap then
119 if length
!= o
.length
then return false
121 if not o
.has_key
(k
) then return false
123 if v
.length
!= ok
.length
then return false
124 for l
in v
do if not ok
.has
(l
) then return false
134 var reaching_defs_in
: nullable ReachingDefsMap = null
135 var reaching_defs_out
: nullable ReachingDefsMap = null
138 redef class BasicBlock
139 var backup_reaching_defs_in
: nullable ReachingDefsMap = null
140 var backup_reaching_defs_out
: nullable ReachingDefsMap = null
142 redef fun dot_node_header
144 if lines
.is_empty
then
145 if backup_reaching_defs_in
!= null then
146 return "{super}-- reaching defs in = \{{backup_reaching_defs_in.to_s}\}\\l"
148 else if lines
.first
.reaching_defs_in
!= null then return "{super}-- reaching defs in = \{{lines.first.reaching_defs_in.to_s}\}\\l"
151 redef fun dot_node_footer
153 if lines
.is_empty
then
154 if backup_reaching_defs_out
!= null then
155 return "{super}-- reaching defs out = \{{backup_reaching_defs_out.to_s}\}\\l"
157 else if lines
.first
.reaching_defs_out
!= null then return "{super}-- reaching defs out = \{{lines.last.reaching_defs_out.to_s}\}\\l"
163 redef class HashSet[E
]
164 redef fun to_s
do return join
(",")