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]
18 redef fun is_forward
do return true
20 redef fun visit
( node
)
22 node
.accept_reaching_defs_analysis
( self, current_in
, current_out
.as(not null) )
26 if a
== null then return b
27 if b
== null then return a
31 redef fun backup_in
(bb
) do return bb
.backup_reaching_defs_in
32 redef fun backup_out
(bb
) do return bb
.backup_reaching_defs_out
33 redef fun backup_in
=(bb
, v
) do bb
.backup_reaching_defs_in
= v
34 redef fun backup_out
=(bb
, v
) do bb
.backup_reaching_defs_out
= v
36 redef fun line_in
(line
) do return line
.reaching_defs_in
37 redef fun line_out
(line
) do return line
.reaching_defs_out
38 redef fun line_in
=(line
, v
) do line
.reaching_defs_in
= v
39 redef fun line_out
=(line
, v
) do line
.reaching_defs_out
= v
41 redef fun default_in_set
do return new ReachingDefsMap
42 redef fun empty_set
do return new ReachingDefsMap
46 fun accept_reaching_defs_analysis
(v
: ReachingDefsAnalysis, ins
: nullable ReachingDefsMap, outs
: ReachingDefsMap) do visit_all
(v
)
49 redef class AInstruction
50 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
52 if ins
!= null then outs
.recover_with
(ins
)
56 redef class ALoadInstruction
57 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
59 if ins
!= null then outs
.recover_with
(ins
)
61 var variable
= def_var
62 if variable
!= null then
64 var set
= new HashSet[ALine]
65 set
.add
(parent
.as(ALine))
73 redef class AStoreInstruction
74 redef fun accept_reaching_defs_analysis
(v
, ins
, outs
)
76 if ins
!= null then outs
.recover_with
(ins
)
78 var variable
= def_var
79 if variable
!= null then
81 var set
= new HashSet[ALine]
82 set
.add
(parent
.as(ALine))
91 super HashMap[Var,Set[ALine]]
93 fun union
(o
: ReachingDefsMap): ReachingDefsMap
95 var n
= new ReachingDefsMap
97 n
[k
] = new HashSet[ALine]
101 if not n
.has_key
(k
) then n
[k
] = new HashSet[ALine]
107 fun intersection
(o
: ReachingDefsMap): ReachingDefsMap
109 var n
= new ReachingDefsMap
110 for k
, v
in self do if n
.has_key
(k
) then n
[k
].add_all
(v
)
111 for k
, v
in o
do if n
.has_key
(k
) then n
[k
].add_all
(v
)
115 redef fun to_s
do return join
(";", ":")
119 if o
!= null and o
isa ReachingDefsMap then
120 if length
!= o
.length
then return false
122 if not o
.has_key
(k
) then return false
124 if v
.length
!= ok
.length
then return false
125 for l
in v
do if not ok
.has
(l
) then return false
135 var reaching_defs_in
: nullable ReachingDefsMap = null
136 var reaching_defs_out
: nullable ReachingDefsMap = null
139 redef class BasicBlock
140 var backup_reaching_defs_in
: nullable ReachingDefsMap = null
141 var backup_reaching_defs_out
: nullable ReachingDefsMap = null
143 redef fun dot_node_header
145 if lines
.is_empty
then
146 if backup_reaching_defs_in
!= null then
147 return "{super}-- r defs in = \{{backup_reaching_defs_in.to_s}\}\\l"
149 else if lines
.first
.reaching_defs_in
!= null then return "{super}-- r defs in = \{{lines.first.reaching_defs_in.to_s}\}\\l"
152 redef fun dot_node_footer
154 if lines
.is_empty
then
155 if backup_reaching_defs_out
!= null then
156 return "{super}-- r defs out = \{{backup_reaching_defs_out.to_s}\}\\l"
158 else if lines
.first
.reaching_defs_out
!= null then return "{super}-- r defs out = \{{lines.last.reaching_defs_out.to_s}\}\\l"
164 redef class HashSet[E
]
165 redef fun to_s
do return join
(",")