1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Analysis that determines which definitions may reach a given point in the code.
20 # Determines wich variables definitions reach each statement.
21 class ReachingDefsAnalysis
24 redef type FLOW: FlowHashSet[VarDef]
26 # New initial flows are empty (conservative analysis).
27 redef fun new_initial_flow
do return new FlowHashSet[VarDef]
29 # Perform set union (used for **some path** analysis).
30 redef fun merge
(s1
, s2
) do return s1
.flow_union
(s2
)
32 redef fun visit
(n
) do n
.accept_reaching_defs
(self)
34 # Generate a new variable definition in the `current_outset`.
35 fun gen
(variable
: Variable, location
: Location) do
36 current_outset
.add
(new VarDef(variable
, location
))
39 # Kill a variable definition in the `current_outset`.
40 fun kill
(variable
: Variable) do
41 for vardef
in current_outset
.to_a
do
42 if vardef
.variable
== variable
then current_outset
.remove
(vardef
)
46 redef fun pretty_print
do
47 for node
, outset
in outsets
do
48 if outset
.is_empty
then continue
49 var values
= outset
.to_a
50 default_comparator
.sort
(values
)
51 print
"{node.location.line_end}: {values.join(", ")} out of {node.class_name}"
58 # Apply a ReachingDefsAnalysis to `self`.
59 fun accept_reaching_defs
(v
: ReachingDefsAnalysis) do accept_forward_analysis
(v
)
62 redef class AVardeclExpr
63 redef fun accept_reaching_defs
(v
) do
65 v
.kill
(variable
.as(not null))
66 v
.gen
(variable
.as(not null), location
)
70 redef class AVarAssignExpr
71 redef fun accept_reaching_defs
(v
) do
73 v
.kill
(variable
.as(not null))
74 v
.gen
(variable
.as(not null), location
)
78 redef class AVarReassignExpr
79 redef fun accept_reaching_defs
(v
) do
81 v
.kill
(variable
.as(not null))
82 v
.gen
(variable
.as(not null), location
)
86 # A Variable definition.
88 # Associates a variable to the location of its definition.
92 redef type OTHER: VarDef
94 # Variable this definition is about.
95 var variable
: Variable
97 # Location of this definition in the source code.
98 var location
: Location
101 return o
isa OTHER and variable
== o
.variable
and location
== o
.location
105 if variable
.name
== o
.variable
.name
then
106 return location
.line_start
<=> o
.location
.line_start
108 return variable
.name
<=> o
.variable
.name
112 redef fun hash
do return variable
.hash
+ location
.hash
113 redef fun to_s
do return "\{{variable}: {location.line_start}\}"