Skip to content

Commit 1a9a2ad

Browse files
committed
Adding additional symex documentation
1 parent 91a6d39 commit 1a9a2ad

File tree

4 files changed

+70
-3
lines changed

4 files changed

+70
-3
lines changed

src/analyses/dirty.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ 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. All variables of this sort
25+
/// escape their local scope and are also considered shared state in the
26+
/// presence of multi-threading.
2327
class dirtyt
2428
{
2529
private:

src/goto-symex/goto_symex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,11 @@ class goto_symext
473473
}
474474
};
475475

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

478483
void symex_transition(

src/goto-symex/goto_symex_state.h

Lines changed: 58 additions & 3 deletions
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 once it reaches a control-flow graph
40+
/// convergence.
3441
class goto_symex_statet final
3542
{
3643
public:
@@ -54,24 +61,60 @@ 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;
6072

6173
// we remember all L1 renamings
6274
std::set<irep_idt> l1_history;
6375

76+
// Objects which hold the separate renaming logic for each level that a
77+
// symex variable can be on. L0 relates to thread ID, L1 relates to frame ID
78+
// (the number of times a function has been called), and L2 relates to
79+
// generation ID.
80+
//
81+
// If looking at the VCC they are shown as !{threadID}@{frameID}#{generationID}
82+
// on the end of a variables name.
6483
symex_level0t level0;
6584
symex_level1t level1;
6685
symex_level2t level2;
6786

68-
// Map L1 names to (L2) constants
87+
// Map L1 names to (L2) constants. Values will be evicted from this map
88+
// when they become non-constant. This is used to propagate values that have
89+
// been worked out to only have one viable value.
90+
//
91+
// "constants" can include symbols, but only in the context of an address-of
92+
// op (i.e. &x can be propagated), and an address-taken thing should only be
93+
// L1. Actual integer literals (for example) aren't symbols, and so aren't
94+
// L-anything.
6995
std::map<irep_idt, exprt> propagation;
7096
void output_propagation_map(std::ostream &);
7197

98+
// Symex renaming levels.
7299
enum levelt { L0=0, L1=1, L2=2 };
73100

74-
// performs renaming _up to_ the given level
101+
/// Rewrites symbol expressions in \ref exprt, applying a suffix to each
102+
/// symbol reflecting its most recent version, which differs depending on
103+
/// which level you requested. Each level also updates its predecessors, so
104+
/// a L1 rename will update L1 and L0. A L2 will update L2, L1 and L0.
105+
///
106+
/// What happens at each level:
107+
/// L0. Applies a suffix giving the current thread number. (Excludes
108+
/// guards, dynamic objects and anything not considered thread-local)
109+
/// L1. Applies a suffix giving the current loop iteration or recursive
110+
/// function invocation.
111+
/// L2. Applies a suffix giving the latest generation of this variable.
112+
///
113+
/// Renaming will not increment any of these values, just update the
114+
/// expression with them. Levels matter when reading a variable, for
115+
/// example: reading the value of x really means reading the particular x
116+
/// symbol for this thread (L0 renaming, if applicable), the most recent
117+
/// instance of x (L1 renaming), and the most recent write to x (L2 renaming).
75118
void rename(exprt &expr, const namespacet &ns, levelt level=L2);
76119
void rename(
77120
typet &type,
@@ -93,8 +136,13 @@ class goto_symex_statet final
93136
protected:
94137
void rename_address(exprt &expr, const namespacet &ns, levelt level);
95138

139+
/// Update level 0 values.
96140
void set_l0_indices(ssa_exprt &expr, const namespacet &ns);
141+
142+
/// Update level 0 and 1 values.
97143
void set_l1_indices(ssa_exprt &expr, const namespacet &ns);
144+
145+
/// Update level 0, 1 and 2 values.
98146
void set_l2_indices(ssa_exprt &expr, const namespacet &ns);
99147

100148
// this maps L1 names to (L2) types
@@ -108,6 +156,10 @@ class goto_symex_statet final
108156
// do dereferencing
109157
value_sett value_set;
110158

159+
/// Container for data that varies per program point, e.g. the constant
160+
/// propagator state, when state needs to branch. This is copied out of
161+
/// goto_symex_statet at a control-flow fork and then back into it (at some
162+
/// point) and not the other way around.
111163
class goto_statet
112164
{
113165
public:
@@ -266,6 +318,9 @@ class goto_symex_statet final
266318
bool l2_thread_write_encoding(const ssa_exprt &expr, const namespacet &ns);
267319

268320
bool record_events;
321+
322+
// Local variables are considered 'dirty' if they've had an address taken and
323+
// therefore may be referred to by a pointer.
269324
incremental_dirtyt dirty;
270325

271326
goto_programt::const_targett saved_target;

src/goto-symex/symex_target_equation.cpp

Lines changed: 3 additions & 0 deletions
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)