Skip to content

Commit d7bb1d4

Browse files
authored
Merge pull request #3975 from JohnDumbell/jd/doc/symex
Additional goto-symex documentation
2 parents 698a44a + 20a84fb commit d7bb1d4

File tree

4 files changed

+68
-3
lines changed

4 files changed

+68
-3
lines changed

src/analyses/dirty.h

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Date: March 2013
2020
#include <util/invariant.h>
2121
#include <goto-programs/goto_functions.h>
2222

23+
/// Dirty variables are ones which have their address taken so we can't
24+
/// reliably work out where they may be assigned and are also considered shared
25+
/// state in the presence of multi-threading.
2326
class dirtyt
2427
{
2528
private:

src/goto-symex/goto_symex.h

+5
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,11 @@ class goto_symext
462462
}
463463
};
464464

465+
/// Transition to the next instruction, which increments the internal program
466+
/// counter and initializes the loop counter when it detects a loop (or
467+
/// recursion) being entered. 'Next instruction' in this situation refers
468+
/// to the next one in program order, so it ignores things like unconditional
469+
/// GOTOs, and only goes until the end of the current function.
465470
void symex_transition(goto_symext::statet &state);
466471

467472
void symex_transition(

src/goto-symex/goto_symex_state.h

+57-3
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,14 @@ Author: Daniel Kroening, [email protected]
3030
#include "renaming_level.h"
3131
#include "symex_target_equation.h"
3232

33-
// central data structure: state
33+
/// Central data structure: state.
34+
35+
/// The state is a persistent data structure that symex maintains as it
36+
/// executes. As we walk over each instruction, state will be updated reflecting
37+
/// their effects until a branch occurs (such as an if), where parts of the
38+
/// state will be copied into a \ref goto_statet, stored in a map for later
39+
/// reference and then merged again (via merge_goto) once it reaches a
40+
/// control-flow graph convergence.
3441
class goto_symex_statet final
3542
{
3643
public:
@@ -54,6 +61,11 @@ class goto_symex_statet final
5461
/// distance from entry
5562
unsigned depth;
5663

64+
// A guard is a particular condition that has to pass for an instruction
65+
// to be executed. The easiest example is an if/else: each instruction along
66+
// the if branch will be guarded by the condition of the if (and if there
67+
// is an else branch then instructions on it will be guarded by the negation
68+
// of the condition of the if).
5769
guardt guard{true_exprt{}};
5870
symex_targett::sourcet source;
5971
symex_target_equationt *symex_target;
@@ -65,13 +77,43 @@ class goto_symex_statet final
6577
symex_level1t level1;
6678
symex_level2t level2;
6779

68-
// Map L1 names to (L2) constants
80+
// Map L1 names to (L2) constants. Values will be evicted from this map
81+
// when they become non-constant. This is used to propagate values that have
82+
// been worked out to only have one possible value.
83+
//
84+
// "constants" can include symbols, but only in the context of an address-of
85+
// op (i.e. &x can be propagated), and an address-taken thing should only be
86+
// L1.
6987
std::map<irep_idt, exprt> propagation;
7088
void output_propagation_map(std::ostream &);
7189

90+
// Symex renaming levels.
7291
enum levelt { L0=0, L1=1, L2=2 };
7392

74-
// performs renaming _up to_ the given level
93+
/// Rewrites symbol expressions in \ref exprt, applying a suffix to each
94+
/// symbol reflecting its most recent version, which differs depending on
95+
/// which level you requested. Each level also updates its predecessors, so
96+
/// a L1 rename will update L1 and L0. A L2 will update L2, L1 and L0.
97+
///
98+
/// What happens at each level:
99+
/// L0. Applies a suffix giving the current thread number. (Excludes
100+
/// guards, dynamic objects and anything not considered thread-local)
101+
/// L1. Applies a suffix giving the current loop iteration or recursive
102+
/// function invocation.
103+
/// L2. Applies a suffix giving the generation of this variable.
104+
///
105+
/// Renaming will not increment any of these values, just update the
106+
/// expression with them. Levels matter when reading a variable, for
107+
/// example: reading the value of x really means reading the particular x
108+
/// symbol for this thread (L0 renaming, if applicable), the most recent
109+
/// instance of x (L1 renaming), and the most recent write to x (L2 renaming).
110+
///
111+
/// The above example after being renamed could look like this: 'x!0@0#42'.
112+
/// That states it's the 42nd generation of this variable, on the first
113+
/// thread, in the first frame.
114+
///
115+
/// A full explanation of SSA (which is why we do this renaming) is in
116+
/// the SSA section of background-concepts.md.
75117
void rename(exprt &expr, const namespacet &ns, levelt level=L2);
76118
void rename(
77119
typet &type,
@@ -93,8 +135,13 @@ class goto_symex_statet final
93135
protected:
94136
void rename_address(exprt &expr, const namespacet &ns, levelt level);
95137

138+
/// Update level 0 values.
96139
void set_l0_indices(ssa_exprt &expr, const namespacet &ns);
140+
141+
/// Update level 0 and 1 values.
97142
void set_l1_indices(ssa_exprt &expr, const namespacet &ns);
143+
144+
/// Update level 0, 1 and 2 values.
98145
void set_l2_indices(ssa_exprt &expr, const namespacet &ns);
99146

100147
// this maps L1 names to (L2) types
@@ -108,6 +155,10 @@ class goto_symex_statet final
108155
// do dereferencing
109156
value_sett value_set;
110157

158+
/// Container for data that varies per program point, e.g. the constant
159+
/// propagator state, when state needs to branch. This is copied out of
160+
/// goto_symex_statet at a control-flow fork and then back into it at a
161+
/// control-flow merge.
111162
class goto_statet
112163
{
113164
public:
@@ -266,6 +317,9 @@ class goto_symex_statet final
266317
bool l2_thread_write_encoding(const ssa_exprt &expr, const namespacet &ns);
267318

268319
bool record_events;
320+
321+
// Local variables are considered 'dirty' if they've had an address taken and
322+
// therefore may be referred to by a pointer.
269323
incremental_dirtyt dirty;
270324

271325
goto_programt::const_targett saved_target;

src/goto-symex/symex_target_equation.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,9 @@ void symex_target_equationt::convert_io(
659659
}
660660
}
661661

662+
/// Merging causes identical ireps to be shared.
663+
/// This is only enabled if the definition SHARING is defined.
664+
/// \param SSA_step The step you want to have shared values.
662665
void symex_target_equationt::merge_ireps(SSA_stept &SSA_step)
663666
{
664667
merge_irep(SSA_step.guard);

0 commit comments

Comments
 (0)