# Determines wich variables definitions reach each statement.
class ReachingDefsAnalysis
super ForwardAnalysis
redef type FLOW: FlowHashSet[VarDef]
# New initial flows are empty (conservative analysis).
redef fun new_initial_flow do return new FlowHashSet[VarDef]
# New initial flows for methods contains the parameters.
redef fun new_initial_method_flow(n) do
var flow = new_initial_flow
var n_signature = n.n_signature
if n_signature == null then return flow
for n_param in n_signature.n_params do
var variable = n_param.variable
if variable == null then continue
flow.add(new VarDef(variable, n_param.location))
end
return flow
end
# Perform set union (used for **some path** analysis).
redef fun merge(s1, s2) do return s1.flow_union(s2)
redef fun visit(n) do n.accept_reaching_defs(self)
# Generate a new variable definition in the `current_outset`.
fun gen(variable: Variable, location: Location) do
current_outset.add(new VarDef(variable, location))
end
# Kill a variable definition in the `current_outset`.
fun kill(variable: Variable) do
for vardef in current_outset.to_a do
if vardef.variable == variable then current_outset.remove(vardef)
end
end
redef fun pretty_print do
for node, outset in outsets do
if outset.is_empty then continue
var values = outset.to_a
default_comparator.sort(values)
print "{node.location.line_end}: {values.join(", ")} out of {node.class_name}"
end
end
end
src/saf/reaching_defs.nit:20,1--67,3