|
ESBMC
Efficient SMT-based Context-Bounded Model Checker
|
Class for the symex-slicer, this slicer is to be executed on SSA formula in order to remove every symbol that does not depends on it. More...
#include <slice.h>
Public Member Functions | |
| symex_slicet (const optionst &options) | |
| bool | run (symex_target_equationt::SSA_stepst &eq) override |
| Iterate over all steps of the \eq in REVERSE order, getting symbol dependencies. | |
| Public Member Functions inherited from slicer | |
| slicer () | |
| BigInt | ignored () const override |
| How many steps were ignored after this algorithm. | |
| Public Member Functions inherited from ssa_step_algorithm | |
| ssa_step_algorithm (bool sideffect) | |
| void | run_on_step (symex_target_equationt::SSA_stept &) |
| virtual void | run_on_output (symex_target_equationt::SSA_stept &) |
| virtual void | run_on_skip (symex_target_equationt::SSA_stept &) |
| virtual void | run_on_branching (symex_target_equationt::SSA_stept &) |
| Public Member Functions inherited from algorithm< symex_target_equationt::SSA_stepst > | |
| algorithm (bool sideeffect) | |
| virtual | ~algorithm ()=default |
| bool | has_sideeffect () |
| Says wether the algorithm is a plain analysis or if it also changes the structure. | |
Static Public Member Functions | |
| static expr2tc | get_nondet_symbol (const expr2tc &expr) |
Public Attributes | |
| std::unordered_set< std::string > | depends |
| Holds the symbols the current equation depends on. | |
| std::unordered_set< const expr2t * > | collected_cache |
| BLACK set (two-color DFS in collect_dependencies): nodes already fully collected into depends. | |
| std::unordered_map< std::string, std::unordered_set< size_t > > | index_reads |
| Per-array-version read map: versioned array-symbol name -> set of constant indices that are actually read. | |
| std::unordered_set< std::string > | array_disqualified |
| Array versions whose element reads cannot be reasoned about per-index (whole-array use, symbolic index, array-as-value, …). | |
| std::unordered_set< const expr2t * > | scanned_cache |
| BLACK set for the scan_array_uses two-color DFS — independent of collected_cache. | |
Protected Member Functions | |
| void | collect_dependencies (const expr2tc &expr) |
| Collect every symbol of \expr into depends (mutating "reverse-taint" accumulation). | |
| void | scan_array_uses (const expr2tc &expr) |
| Record the array-element reads in \expr into index_reads, and disqualify (array_disqualified) any array version used in a way that defeats per-index reasoning. | |
| bool | depends_on_tracked (const expr2tc &expr) |
| Read-only: does \expr reference a tracked dependency (a symbol in depends or a no_slice symbol)? | |
| void | run_on_assert (symex_target_equationt::SSA_stept &SSA_step) override |
| Asserts are never sliced: collect the step's guard/cond symbols into depends and record their array reads. | |
| void | run_on_assume (symex_target_equationt::SSA_stept &SSA_step) override |
| Remove unneeded assumes from the formula. | |
| void | run_on_assignment (symex_target_equationt::SSA_stept &SSA_step) override |
| Remove unneeded assignments from the formula. | |
| void | run_on_renumber (symex_target_equationt::SSA_stept &SSA_step) override |
| Remove unneeded renumbers from the formula. | |
Protected Attributes | |
| const bool | slice_assumes |
| whether assumes should be sliced | |
| const bool | slice_nondet |
| Whether we should slice nondet symbols. | |
| Protected Attributes inherited from slicer | |
| BigInt | sliced = 0 |
| tracks how many steps were sliced | |
| Protected Attributes inherited from algorithm< symex_target_equationt::SSA_stepst > | |
| const bool | sideeffect |
Class for the symex-slicer, this slicer is to be executed on SSA formula in order to remove every symbol that does not depends on it.
It works by constructing a symbol dependency list by transversing the SSA formula in reverse order. If any assume, assignment, or renumber step does not belong into this dependency, then it will be ignored.
|
inlineexplicit |
|
protected |
Read-only: does \expr reference a tracked dependency (a symbol in depends or a no_slice symbol)?
Used only on shallow exprs (an SSA lhs symbol, or an assume cond), never the deep guard, so it stays recursive and is NOT memoised — depends mutates across steps, so a node-memo would be unsound.
| expr | expression to test |
|
inlineoverridevirtual |
Iterate over all steps of the \eq in REVERSE order, getting symbol dependencies.
Assignment and renumber steps whose lhs is untracked are ignored; assume steps additionally require –slice-assumes.
| eq | symex formula to be sliced |
Implements algorithm< symex_target_equationt::SSA_stepst >.
|
overrideprotectedvirtual |
Asserts are never sliced: collect the step's guard/cond symbols into depends and record their array reads.
| SSA_step | an assert step |
Reimplemented from ssa_step_algorithm.
|
overrideprotectedvirtual |
Remove unneeded assignments from the formula.
Check if the LHS symbol is in the depends, if it is not then mark the \SSA_Step as ignored.
If the LHS is tracked, collect the guard and rhs symbols into depends (with dead array-store elision — see the implementation).
| SSA_step | an assignment step |
Reimplemented from ssa_step_algorithm.
|
overrideprotectedvirtual |
Remove unneeded assumes from the formula.
Check if the Assume cond symbol is in the depends, if it is not then mark the \SSA_Step as ignored.
If the assume cond is in the depends, then add its guards and cond into the depends
Note 1: All the conditions operands are going to be added into the depends. This makes that the condition itself as a "reverse taint"
TODO: What happens if the ASSUME would result in false?
| SSA_step | an assume step |
Reimplemented from ssa_step_algorithm.
|
overrideprotectedvirtual |
Remove unneeded renumbers from the formula.
Check if the LHS symbol is in the depends, if it is not then mark the \SSA_Step as ignored. Renumber steps never contribute dependencies.
| SSA_step | a renumber step |
Reimplemented from ssa_step_algorithm.
|
protected |
Record the array-element reads in \expr into index_reads, and disqualify (array_disqualified) any array version used in a way that defeats per-index reasoning.
Run on the guard/cond/rhs of every RETAINED step so that, by the time a store is examined in reverse order, every downstream read of that array version has already been recorded.
Walked with the same explicit two-color worklist as collect_dependencies but with its own memo (scanned_cache); both outputs are insert-only, so skipping an already-scanned subtree is sound and keeps the scan O(N).
| expr | expression whose array reads are recorded |
| std::unordered_set<std::string> symex_slicet::array_disqualified |
Array versions whose element reads cannot be reasoned about per-index (whole-array use, symbolic index, array-as-value, …).
INSERT-ONLY. A disqualified array never has any of its stores dropped.
| std::unordered_set<const expr2t *> symex_slicet::collected_cache |
BLACK set (two-color DFS in collect_dependencies): nodes already fully collected into depends.
Persists across steps so the shared guard and-chain prefix is walked once overall (Θ(N²) -> O(N)). Collection is purely monotone (depends.insert only), so the memo is unconditional.
| std::unordered_set<std::string> symex_slicet::depends |
Holds the symbols the current equation depends on.
| std::unordered_map<std::string, std::unordered_set<size_t> > symex_slicet::index_reads |
Per-array-version read map: versioned array-symbol name -> set of constant indices that are actually read.
Propagation through a kept store inserts the live-out set minus the overwritten index, preserving any direct reads already recorded for the source version. A store to an index NOT present here is provably dead and may be elided. Populated by scan_array_uses, consulted by run_on_assignment to drop dead array stores.
| std::unordered_set<const expr2t *> symex_slicet::scanned_cache |
BLACK set for the scan_array_uses two-color DFS — independent of collected_cache.
Sound for the same reason: index_reads/array_disqualified are insert-only, so re-skipping an already-scanned subtree adds nothing.
|
protected |
whether assumes should be sliced
|
protected |
Whether we should slice nondet symbols.