@@ -231,6 +231,7 @@ ai_baset::locationt ai_baset::get_next(
231
231
}
232
232
233
233
bool ai_baset::fixedpoint (
234
+ const irep_idt &function_identifier,
234
235
const goto_programt &goto_program,
235
236
const goto_functionst &goto_functions,
236
237
const namespacet &ns)
@@ -250,14 +251,16 @@ bool ai_baset::fixedpoint(
250
251
locationt l=get_next (working_set);
251
252
252
253
// goto_program is really only needed for iterator manipulation
253
- if (visit (l, working_set, goto_program, goto_functions, ns))
254
+ if (visit (
255
+ function_identifier, l, working_set, goto_program, goto_functions, ns))
254
256
new_data=true ;
255
257
}
256
258
257
259
return new_data;
258
260
}
259
261
260
262
bool ai_baset::visit (
263
+ const irep_idt &function_identifier,
261
264
locationt l,
262
265
working_sett &working_set,
263
266
const goto_programt &goto_program,
@@ -288,18 +291,22 @@ bool ai_baset::visit(
288
291
to_code_function_call (l->code );
289
292
290
293
if (do_function_call_rec (
291
- l, to_l,
292
- code.function (),
293
- code.arguments (),
294
- goto_functions, ns))
294
+ function_identifier,
295
+ l,
296
+ to_l,
297
+ code.function (),
298
+ code.arguments (),
299
+ goto_functions,
300
+ ns))
295
301
have_new_values=true ;
296
302
}
297
303
else
298
304
{
299
305
// initialize state, if necessary
300
306
get_state (to_l);
301
307
302
- new_values.transform (l, to_l, *this , ns);
308
+ new_values.transform (
309
+ function_identifier, l, function_identifier, to_l, *this , ns);
303
310
304
311
if (merge (new_values, l, to_l))
305
312
have_new_values=true ;
@@ -316,7 +323,9 @@ bool ai_baset::visit(
316
323
}
317
324
318
325
bool ai_baset::do_function_call (
319
- locationt l_call, locationt l_return,
326
+ const irep_idt &calling_function_identifier,
327
+ locationt l_call,
328
+ locationt l_return,
320
329
const goto_functionst &goto_functions,
321
330
const goto_functionst::function_mapt::const_iterator f_it,
322
331
const exprt::operandst &,
@@ -334,7 +343,13 @@ bool ai_baset::do_function_call(
334
343
{
335
344
// if we don't have a body, we just do an edige call -> return
336
345
std::unique_ptr<statet> tmp_state (make_temporary_state (get_state (l_call)));
337
- tmp_state->transform (l_call, l_return, *this , ns);
346
+ tmp_state->transform (
347
+ calling_function_identifier,
348
+ l_call,
349
+ calling_function_identifier,
350
+ l_return,
351
+ *this ,
352
+ ns);
338
353
339
354
return merge (*tmp_state, l_call, l_return);
340
355
}
@@ -351,7 +366,8 @@ bool ai_baset::do_function_call(
351
366
352
367
// do the edge from the call site to the beginning of the function
353
368
std::unique_ptr<statet> tmp_state (make_temporary_state (get_state (l_call)));
354
- tmp_state->transform (l_call, l_begin, *this , ns);
369
+ tmp_state->transform (
370
+ calling_function_identifier, l_call, f_it->first , l_begin, *this , ns);
355
371
356
372
bool new_data=false ;
357
373
@@ -361,7 +377,7 @@ bool ai_baset::do_function_call(
361
377
362
378
// do we need to do/re-do the fixedpoint of the body?
363
379
if (new_data)
364
- fixedpoint (goto_function.body , goto_functions, ns);
380
+ fixedpoint (f_it-> first , goto_function.body , goto_functions, ns);
365
381
}
366
382
367
383
// This is the edge from function end to return site.
@@ -378,15 +394,18 @@ bool ai_baset::do_function_call(
378
394
return false ; // function exit point not reachable
379
395
380
396
std::unique_ptr<statet> tmp_state (make_temporary_state (end_state));
381
- tmp_state->transform (l_end, l_return, *this , ns);
397
+ tmp_state->transform (
398
+ f_it->first , l_end, calling_function_identifier, l_return, *this , ns);
382
399
383
400
// Propagate those
384
401
return merge (*tmp_state, l_end, l_return);
385
402
}
386
403
}
387
404
388
405
bool ai_baset::do_function_call_rec (
389
- locationt l_call, locationt l_return,
406
+ const irep_idt &calling_function_identifier,
407
+ locationt l_call,
408
+ locationt l_return,
390
409
const exprt &function,
391
410
const exprt::operandst &arguments,
392
411
const goto_functionst &goto_functions,
@@ -411,8 +430,14 @@ bool ai_baset::do_function_call_rec(
411
430
it != goto_functions.function_map .end (),
412
431
" Function " + id2string (identifier) + " not in function map" );
413
432
414
- new_data =
415
- do_function_call (l_call, l_return, goto_functions, it, arguments, ns);
433
+ new_data = do_function_call (
434
+ calling_function_identifier,
435
+ l_call,
436
+ l_return,
437
+ goto_functions,
438
+ it,
439
+ arguments,
440
+ ns);
416
441
417
442
return new_data;
418
443
}
@@ -425,7 +450,7 @@ void ai_baset::sequential_fixedpoint(
425
450
f_it=goto_functions.function_map .find (goto_functions.entry_point ());
426
451
427
452
if (f_it!=goto_functions.function_map .end ())
428
- fixedpoint (f_it->second .body , goto_functions, ns);
453
+ fixedpoint (f_it->first , f_it-> second .body , goto_functions, ns);
429
454
}
430
455
431
456
void ai_baset::concurrent_fixedpoint (
@@ -443,16 +468,32 @@ void ai_baset::concurrent_fixedpoint(
443
468
goto_programt::const_targett sh_target=tmp.instructions .begin ();
444
469
statet &shared_state=get_state (sh_target);
445
470
446
- typedef std::list<std::pair<goto_programt const *,
447
- goto_programt::const_targett> > thread_wlt;
471
+ struct wl_entryt
472
+ {
473
+ wl_entryt (
474
+ const irep_idt &_function_identifier,
475
+ const goto_programt &_goto_program,
476
+ locationt _location)
477
+ : function_identifier(_function_identifier),
478
+ goto_program (&_goto_program),
479
+ location(_location)
480
+ {
481
+ }
482
+
483
+ irep_idt function_identifier;
484
+ const goto_programt *goto_program;
485
+ locationt location;
486
+ };
487
+
488
+ typedef std::list<wl_entryt> thread_wlt;
448
489
thread_wlt thread_wl;
449
490
450
491
forall_goto_functions (it, goto_functions)
451
492
forall_goto_program_instructions(t_it, it->second.body)
452
493
{
453
494
if (is_threaded (t_it))
454
495
{
455
- thread_wl.push_back (std::make_pair (&( it->second .body ) , t_it));
496
+ thread_wl.push_back (wl_entryt ( it->first , it-> second .body , t_it));
456
497
457
498
goto_programt::const_targett l_end=
458
499
it->second .body .instructions .end ();
@@ -469,19 +510,25 @@ void ai_baset::concurrent_fixedpoint(
469
510
{
470
511
new_shared=false ;
471
512
472
- for (const auto &wl_pair : thread_wl)
513
+ for (const auto &wl_entry : thread_wl)
473
514
{
474
515
working_sett working_set;
475
- put_in_working_set (working_set, wl_pair. second );
516
+ put_in_working_set (working_set, wl_entry. location );
476
517
477
- statet &begin_state= get_state (wl_pair. second );
478
- merge (begin_state, sh_target, wl_pair. second );
518
+ statet &begin_state = get_state (wl_entry. location );
519
+ merge (begin_state, sh_target, wl_entry. location );
479
520
480
521
while (!working_set.empty ())
481
522
{
482
523
goto_programt::const_targett l=get_next (working_set);
483
524
484
- visit (l, working_set, *(wl_pair.first ), goto_functions, ns);
525
+ visit (
526
+ wl_entry.function_identifier ,
527
+ l,
528
+ working_set,
529
+ *(wl_entry.goto_program ),
530
+ goto_functions,
531
+ ns);
485
532
486
533
// the underlying domain must make sure that the final state
487
534
// carries all possible values; otherwise we would need to
0 commit comments