Skip to content

Commit 8518ed5

Browse files
authored
Merge pull request #4093 from johanneskloos/ai-overview
Document ait; first stab at concurrency_aware_ait.
2 parents 33e1656 + f6b24fb commit 8518ed5

File tree

1 file changed

+68
-3
lines changed

1 file changed

+68
-3
lines changed

src/analyses/ai.h

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,46 @@ class ai_baset
354354
virtual std::unique_ptr<statet> make_temporary_state(const statet &s)=0;
355355
};
356356

357-
// domainT is expected to be derived from ai_domain_baseT
357+
/// Base class for abstract interpretation. An actual analysis
358+
/// must (a) inherit from this class and (b) provide a domain class as a
359+
/// type argument, which must, in turn, inherit from \ref ai_domain_baset.
360+
///
361+
/// From a user's perspective, this class provides three main groups of
362+
/// functions:
363+
///
364+
/// 1. Running an analysis, via
365+
/// \ref ai_baset#operator()(const irep_idt&,const goto_programt&, <!--
366+
/// --> const namespacet&),
367+
/// \ref ai_baset#operator()(const goto_functionst&,const namespacet&)
368+
/// and \ref ai_baset#operator()(const goto_modelt&)
369+
/// 2. Accessing the results of an analysis, by looking up the result
370+
/// for a given location \p l using
371+
/// \ref ait#operator[](goto_programt::const_targett).
372+
/// 3. Outputting the results of the analysis; see
373+
/// \ref ai_baset#output(const namespacet&, const irep_idt&,
374+
/// const goto_programt&, std::ostream&)const et cetera.
375+
///
376+
/// A typical usage pattern would be to call the analysis first,
377+
/// and use `operator[]` afterwards to retrieve the results. The fixed
378+
/// point algorithm used is a standard worklist algorithm; the current
379+
/// implementation is flow- and path-sensitive, but not context-sensitive.
380+
///
381+
/// From an analysis developer's perspective, an analysis is implemented by
382+
/// inheriting from this class (or, if a concurrency-sensitive analysis is
383+
/// required, from \ref concurrency_aware_ait), providing a class implementing
384+
/// the abstract domain as the type for the \p domainT parameter. Most of the
385+
/// actual analysis functions (in particular, the minimal element, the lattice
386+
/// join, and the state transformer) are supplied using \p domainT.
387+
///
388+
/// To control the analysis in more detail, you can also override the following
389+
/// methods:
390+
/// - \ref ait#initialize(const irep_idt&, const goto_programt&),
391+
/// \ref ait#initialize(const irep_idt&,
392+
/// const goto_functionst::goto_functiont&) and
393+
/// \ref ait#initialize(const goto_functionst&), for pre-analysis
394+
/// initialization
395+
/// - \ref ait#finalize(), for post-analysis cleanup.
396+
///
358397
template<typename domainT>
359398
class ait:public ai_baset
360399
{
@@ -366,6 +405,7 @@ class ait:public ai_baset
366405

367406
typedef goto_programt::const_targett locationt;
368407

408+
/// Find the analysis result for a given location.
369409
domainT &operator[](locationt l)
370410
{
371411
typename state_mapt::iterator it=state_map.find(l);
@@ -375,6 +415,7 @@ class ait:public ai_baset
375415
return it->second;
376416
}
377417

418+
/// Find the analysis result for a given location.
378419
const domainT &operator[](locationt l) const
379420
{
380421
typename state_mapt::const_iterator it=state_map.find(l);
@@ -384,6 +425,7 @@ class ait:public ai_baset
384425
return it->second;
385426
}
386427

428+
/// Used internally by the analysis.
387429
std::unique_ptr<statet> abstract_state_before(locationt t) const override
388430
{
389431
typename state_mapt::const_iterator it = state_map.find(t);
@@ -397,25 +439,31 @@ class ait:public ai_baset
397439
return util_make_unique<domainT>(it->second);
398440
}
399441

442+
/// Remove all analysis results.
400443
void clear() override
401444
{
402445
state_map.clear();
403446
ai_baset::clear();
404447
}
405448

406449
protected:
450+
/// Map from locations to domain elements, for the results of a static
451+
/// analysis.
407452
typedef std::
408453
unordered_map<locationt, domainT, const_target_hash, pointee_address_equalt>
409454
state_mapt;
410455
state_mapt state_map;
411456

412-
// this one creates states, if need be
457+
/// Look up the analysis state for a given location, instantiating a new state
458+
/// if required. Used internally by the analysis.
413459
virtual statet &get_state(locationt l) override
414460
{
415461
return state_map[l]; // calls default constructor
416462
}
417463

418-
// this one just finds states
464+
/// Look up the analysis state for a given location, throwing an exception if
465+
/// no state is known.
466+
/// Used internally by the analysis.
419467
const statet &find_state(locationt l) const override
420468
{
421469
typename state_mapt::const_iterator it=state_map.find(l);
@@ -425,18 +473,24 @@ class ait:public ai_baset
425473
return it->second;
426474
}
427475

476+
/// Merge the state \p src, flowing from location \p from to
477+
/// location \p to, into the state currently stored for location \p to.
428478
bool merge(const statet &src, locationt from, locationt to) override
429479
{
430480
statet &dest=get_state(to);
431481
return static_cast<domainT &>(dest).merge(
432482
static_cast<const domainT &>(src), from, to);
433483
}
434484

485+
/// Make a copy of \p s.
435486
std::unique_ptr<statet> make_temporary_state(const statet &s) override
436487
{
437488
return util_make_unique<domainT>(static_cast<const domainT &>(s));
438489
}
439490

491+
/// Internal: implementation of the fixed point function using
492+
/// \ref ai_baset#sequential_fixedpoint(const goto_functionst&,
493+
/// const namespacet&).
440494
void fixedpoint(
441495
const goto_functionst &goto_functions,
442496
const namespacet &ns) override
@@ -457,6 +511,17 @@ class ait:public ai_baset
457511
}
458512
};
459513

514+
/// Base class for concurrency-aware abstract interpretation. See
515+
/// \ref ait for details.
516+
/// The only difference is that after the sequential fixed point construction,
517+
/// as done by \ref ait, another step is added to account for
518+
/// concurrently-executed instructions.
519+
/// Basically, it makes the analysis flow-insensitive by feeding results of a
520+
/// sequential execution back into the entry point, thereby accounting for any
521+
/// values computed by different threads. Compare
522+
/// [Martin Rinard, "Analysis of Multi-Threaded Programs", SAS 2001](
523+
/// http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.28.4747&<!--
524+
/// -->rep=rep1&type=pdf).
460525
template<typename domainT>
461526
class concurrency_aware_ait:public ait<domainT>
462527
{

0 commit comments

Comments
 (0)