Skip to content

Commit ff41c1c

Browse files
committed
Description of rd_range_domaint of reaching_definitions.h(cpp) module.
1 parent 3469b19 commit ff41c1c

File tree

1 file changed

+138
-0
lines changed

1 file changed

+138
-0
lines changed

src/analyses/README.md

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,144 @@ is covered in a separate subsection.
121121

122122
A basic description for how a natural loop works is here: https://web.cs.wpi.edu/~kal/PLT/PLT8.6.4.html
123123

124+
### Reaching definitions
125+
126+
This module implements the reaching definitions data-flow analysis
127+
(see https://en.wikipedia.org/wiki/Reaching_definition for basic introduction)
128+
on multi-threaded GOTO programs.
129+
130+
The domain element is defined in a class `rd_range_domaint` and the actual
131+
analysis is implemented in a class `reaching_definitions_analysist`. Beside
132+
these classes there are more data structures necessary in the computation.
133+
We discuss all of them in the following sub-sections.
134+
135+
#### Struct `reaching_definitiont`
136+
137+
Identifies a GOTO instruction where a given variable is defined (i.e. it is set
138+
a certain value). In consists of these data:
139+
- `identifier` The name of the variable which was defined.
140+
- `definition_at` The iterator to the GOTO instruction where the variable is
141+
- `bit_begin` and `bit_end` These two integers define a range of bits (i.e. the
142+
begin and end bit indices) which represent the value of the variable. Clearly,
143+
`0 <= bit_begin < bit_end`. However, `bit_end` can also be set a special value
144+
`-`, which means infinite/unknown index.
145+
146+
There is defined an order of instances of this structure. But its purpose is
147+
only for to be able to use instances as keys in ordered containers, like
148+
`std::map`.
149+
150+
#### Class `sparse_bitvector_analysist`
151+
152+
An instance of this class provides an assignment of unique numeric `ID` to each
153+
inserted `reaching_definitionst` instance. Internally, the class holds two data
154+
members:
155+
156+
- `value_map` It is (an unordered) map from names of program variables to a set
157+
of pairs (`reaching_definitiont`, `ID`). Formally, the map is defined as
158+
`value_map: var_names -> (reaching_definitionst -> ID)`.
159+
- `values` It is a map from an `ID` to the corresponding `reaching_definitiont`
160+
instance inside the map `value_map`. Namely, the map is implemented as an
161+
`std::vector` of iterators to elements of the map `value_map`. An index to
162+
`values` vector is the `ID` of the related `reaching_definitionst` instance.
163+
164+
#### Class `rd_range_domaint`
165+
166+
Because the class is inherited from `ai_domain_baset`, its instance represents
167+
an element of a domain of the reaching definitions abstract interpretation
168+
analysis. Each instance is thus associated with exactly one instruction in
169+
an analysed GOTO program. And so, the instance holds information for individual
170+
program variables about their reaching definitions, at that instruction. The
171+
information is held in these data members:
172+
173+
- `has_value` This (three value logic) flag determines, whether the instance
174+
represents `top`, `bottom`, or any other element of the lattice, by values
175+
`TRUE`, `FALSE`, and `UNKNOW` respectively. Initially it is set to `FALSE`.
176+
- `bv_container` It is a pointer to a
177+
`sparse_bitvector_analysist<reaching_definitiont>` instance. It holds the
178+
actual reaching definitions data of individual program variables. This
179+
pointer is initially `nullptr` and it is later set (by
180+
`reaching_definitions_analysist` instance using the method
181+
`set_bitvector_container`) to a valid pointer, which is actually shared by
182+
all `rd_range_domaint` instances. NOTE: `reaching_definitions_analysist`
183+
inherits from `sparse_bitvector_analysist<reaching_definitiont>` and so
184+
`this` is passed to `set_bitvector_container` for all instances.
185+
- `values` It is (an ordered) map from program variable names to `ID`s of
186+
`reaching_definitiont` instances stored in map pointed to by `bv_container`.
187+
The map is not empty only if `has_value` is `UNKNOWN`. Variables in the map
188+
are all those which are live at the associated instruction.
189+
- `export_cache` It is a helper data structure. It consists of data already
190+
stored in `values` and `bv_container`. The purpose of this structure is to
191+
provide a boost for certain operations (discussed below). It is basically
192+
(an ordered) map from (a subset of) variables in `values` to iterators to
193+
GOTO instructions where the variables are defined. Moreover, each such
194+
iterator is also associated with a range of bits defining the value of that
195+
variable at that GOTO instruction. Both the iterators and the corresponding
196+
bit ranges are simply taken from `reaching_definitiont` instances obtained
197+
for `ID`s in `values[var_name]`.
198+
199+
##### Method `merge`
200+
201+
Implements the `join` operation of two instances `a` and `b`. It operates only
202+
on `a.values` and `b.values`. The keys in the resulting map is the union of
203+
variable names in both `a.values` and `b.values`. And for each variable
204+
`v` appearing in both maps `a.values` and `b.values` the resulting mapped set
205+
of `ID`s is the set union of `a.values[v]` and `b.values[v]`.
206+
207+
NOTE: The operation actually does not produce a new `join` element. The element
208+
`a` is modified to become the `join` element.
209+
210+
NOTE: When union of `a.values[v]` and `b.values[v]` is computed, then `v` must
211+
removed from the cache `export_cache`
212+
213+
##### Method `transform`
214+
215+
Computes an instance obtained from a source instance `a` by transformation over
216+
a passed GOTO instruction. The method implements a switch according to a type of
217+
instruction and then calls a dedicated `transform_*` method for the recognised
218+
instruction. The dedicated methods are described below.
219+
220+
221+
##### Method `transform_dead`
222+
223+
Computes an instance obtained from a source instance `a` by transformation over
224+
`DEAD v` GOTO instruction. The operation simply removes `v` from `a.values` (an
225+
from the `export_cache`).
226+
227+
##### Method `transform_start_thread`
228+
229+
TODO!
230+
231+
##### Method `transform_function_call`
232+
233+
TODO!
234+
235+
##### Method `transform_end_function`
236+
237+
TODO!
238+
239+
##### Method `transform_assign`
240+
241+
TODO!
242+
243+
##### Method `kill`
244+
245+
TODO!
246+
247+
##### Method `gen`
248+
249+
A utility function which updates internal data structures by inserting a
250+
new reaching definition record, for a passed variable name, written in given
251+
GOTO instruction (identified by an iterator), at same range of bits.
252+
253+
##### Method `polulate_cache`
254+
255+
Given a variable name `v` it collects data from `bv_container` for each `ID`
256+
in `values[v]` and stores them into `export_cache[v]`. Namely, for each
257+
`reaching_definitiont` instance `rd` obtained from `bv_container` it associates
258+
`rd.definition_at` with the bit-range `(rd.bit_begin, rd.bit_end)`.
259+
260+
### Class `reaching_definitions_analysist`
261+
124262
\subsection analyses-reaching-definitions Reaching definitions (reaching_definitions_analysist)
125263

126264
To be documented.

0 commit comments

Comments
 (0)