Skip to content

Commit 0f7f11d

Browse files
committed
[Documentation] Document ait; first stab at concurrency_aware_ait.
The full documentation of concurrency_aware_ait needs input from someone who really understands the algorithm.
1 parent eef01a1 commit 0f7f11d

File tree

1 file changed

+65
-3
lines changed

1 file changed

+65
-3
lines changed

src/analyses/ai.h

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,48 @@ 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 static analyses. Any actual static 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 classes of
362+
/// functions:
363+
///
364+
/// 1. Running a static 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 a static 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 static 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+
///
397+
// For the <!-- --> trick above, see
398+
// https://stackoverflow.com/questions/46744573/
358399
template<typename domainT>
359400
class ait:public ai_baset
360401
{
@@ -366,6 +407,7 @@ class ait:public ai_baset
366407

367408
typedef goto_programt::const_targett locationt;
368409

410+
/// Find the analysis result for a given location.
369411
domainT &operator[](locationt l)
370412
{
371413
typename state_mapt::iterator it=state_map.find(l);
@@ -375,6 +417,7 @@ class ait:public ai_baset
375417
return it->second;
376418
}
377419

420+
/// Find the analysis result for a given location.
378421
const domainT &operator[](locationt l) const
379422
{
380423
typename state_mapt::const_iterator it=state_map.find(l);
@@ -384,6 +427,7 @@ class ait:public ai_baset
384427
return it->second;
385428
}
386429

430+
/// Used internally by the analysis.
387431
std::unique_ptr<statet> abstract_state_before(locationt t) const override
388432
{
389433
typename state_mapt::const_iterator it = state_map.find(t);
@@ -397,25 +441,31 @@ class ait:public ai_baset
397441
return util_make_unique<domainT>(it->second);
398442
}
399443

444+
/// Remove all analysis results.
400445
void clear() override
401446
{
402447
state_map.clear();
403448
ai_baset::clear();
404449
}
405450

406451
protected:
452+
/// Map from locations to domain elements, for the results of a static
453+
/// analysis.
407454
typedef std::
408455
unordered_map<locationt, domainT, const_target_hash, pointee_address_equalt>
409456
state_mapt;
410457
state_mapt state_map;
411458

412-
// this one creates states, if need be
459+
/// Look up the analysis state for a given location, instantiating a new state
460+
/// if required. Used internally by the analysis.
413461
virtual statet &get_state(locationt l) override
414462
{
415463
return state_map[l]; // calls default constructor
416464
}
417465

418-
// this one just finds states
466+
/// Look up the analysis state for a given location, throwing an exception if
467+
/// no state is known.
468+
/// Used internally by the analysis.
419469
const statet &find_state(locationt l) const override
420470
{
421471
typename state_mapt::const_iterator it=state_map.find(l);
@@ -425,18 +475,24 @@ class ait:public ai_baset
425475
return it->second;
426476
}
427477

478+
/// Merge the state \p src, flowing from location \p from to
479+
/// location \p to, into the state currently stored for location \p to.
428480
bool merge(const statet &src, locationt from, locationt to) override
429481
{
430482
statet &dest=get_state(to);
431483
return static_cast<domainT &>(dest).merge(
432484
static_cast<const domainT &>(src), from, to);
433485
}
434486

487+
/// Make a copy of \p s.
435488
std::unique_ptr<statet> make_temporary_state(const statet &s) override
436489
{
437490
return util_make_unique<domainT>(static_cast<const domainT &>(s));
438491
}
439492

493+
/// Internal: implementation of the fixed point function using
494+
/// \ref ai_baset#sequential_fixedpoint(const goto_functionst&,
495+
/// const namespacet&).
440496
void fixedpoint(
441497
const goto_functionst &goto_functions,
442498
const namespacet &ns) override
@@ -457,6 +513,12 @@ class ait:public ai_baset
457513
}
458514
};
459515

516+
/// Base class for concurrency-aware static analyses. See
517+
/// \ref ait for details.
518+
/// The only difference is that after the sequential fixed point construction,
519+
/// as done by \ref ait, another step is added to account for
520+
/// concurrently-executed instructions.
521+
/// TODO: Somebody who truly understands this algorithm should document it!
460522
template<typename domainT>
461523
class concurrency_aware_ait:public ait<domainT>
462524
{

0 commit comments

Comments
 (0)