Skip to content

Commit 3c8db85

Browse files
author
Your Name
committed
Add evalcache
1 parent 39a8d02 commit 3c8db85

1 file changed

Lines changed: 14 additions & 8 deletions

File tree

lib/programmemory.cpp

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -571,9 +571,11 @@ void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty, const To
571571

572572
ProgramMemoryState::FindChangedFn ProgramMemoryState::getCachedFindExpressionChanged(bool skipDeadCode) const
573573
{
574-
// The structural findExpressionChanged() is pure, so memoize it in changedCache (never
575-
// invalidated). skipDeadCode gates it as a pre-filter for the dead-code walk, which needs state.
576-
return [cache = changedCache, sp = &settings, statePtr = &state, skipDeadCode](const Token* expr, const Token* start, const Token* end) -> const Token* {
574+
// Structural findExpressionChanged() is pure, so memoize it in changedCache (never invalidated).
575+
// skipDeadCode adds the dead-code walk; it evaluates guards against a fixed state snapshot (so every
576+
// variable follows the same path) and memoizes those evals in evalCache for the closure's lifetime.
577+
using EvalCache = std::map<const Token*, std::vector<MathLib::bigint>>;
578+
return [cache = changedCache, sp = &settings, snapshot = (skipDeadCode ? state : ProgramMemory{}), skipDeadCode, evalCache = std::make_shared<EvalCache>()](const Token* expr, const Token* start, const Token* end) -> const Token* {
577579
const auto key = std::make_tuple(expr, start, end);
578580
const auto it = cache->find(key);
579581
const Token* modified = (it != cache->end())
@@ -582,13 +584,17 @@ ProgramMemoryState::FindChangedFn ProgramMemoryState::getCachedFindExpressionCha
582584
if (!skipDeadCode || !modified)
583585
return modified;
584586
auto eval = [&](const Token* cond) -> std::vector<MathLib::bigint> {
585-
ProgramMemory pm2 = *statePtr;
587+
const auto cit = evalCache->find(cond);
588+
if (cit != evalCache->end())
589+
return cit->second;
590+
ProgramMemory pm2 = snapshot;
586591
const auto result = execute(cond, pm2, *sp);
592+
std::vector<MathLib::bigint> r;
587593
if (isTrue(result))
588-
return {1};
589-
if (isFalse(result))
590-
return {0};
591-
return {};
594+
r = {1};
595+
else if (isFalse(result))
596+
r = {0};
597+
return evalCache->emplace(cond, std::move(r)).first->second;
592598
};
593599
return findExpressionChangedSkipDeadCode(expr, start, end, *sp, eval);
594600
};

0 commit comments

Comments
 (0)