@@ -121,6 +121,144 @@ is covered in a separate subsection.
121
121
122
122
A basic description for how a natural loop works is here: https://web.cs.wpi.edu/~kal/PLT/PLT8.6.4.html
123
123
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
+
124
262
\subsection analyses-reaching-definitions Reaching definitions (reaching_definitions_analysist)
125
263
126
264
To be documented.
0 commit comments