Merge pull request #10716 from ethereum/rename_bfs

Make BFS correct again
This commit is contained in:
Leonardo 2021-01-06 11:55:34 +01:00 committed by GitHub
commit 130fc0701b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 20 deletions

View File

@ -79,8 +79,7 @@ private:
/** /**
* Generic breadth first search. * Generic breadth first search.
* *
* Note that V needs to be a comparable value type. If it is not, use a pointer type, * Note that V needs to be a comparable value type or a pointer.
* but note that this might lead to non-deterministic traversal.
* *
* Example: Gather all (recursive) children in a graph starting at (and including) ``root``: * Example: Gather all (recursive) children in a graph starting at (and including) ``root``:
* *
@ -104,13 +103,14 @@ struct BreadthFirstSearch
{ {
while (!verticesToTraverse.empty()) while (!verticesToTraverse.empty())
{ {
V v = *verticesToTraverse.begin(); V v = std::move(verticesToTraverse.front());
verticesToTraverse.erase(verticesToTraverse.begin()); verticesToTraverse.pop_front();
visited.insert(v); visited.insert(v);
_forEachChild(v, [this](V _vertex) { _forEachChild(v, [this](V _vertex) {
if (!visited.count(_vertex)) if (!visited.count(_vertex))
verticesToTraverse.emplace(std::move(_vertex)); verticesToTraverse.emplace_back(std::move(_vertex));
}); });
} }
return *this; return *this;
@ -120,7 +120,7 @@ struct BreadthFirstSearch
verticesToTraverse.clear(); verticesToTraverse.clear();
} }
std::set<V> verticesToTraverse; std::list<V> verticesToTraverse;
std::set<V> visited{}; std::set<V> visited{};
}; };

View File

@ -125,21 +125,23 @@ map<YulString, SideEffects> SideEffectsPropagator::sideEffects(
{ {
YulString funName = call.first; YulString funName = call.first;
SideEffects sideEffects; SideEffects sideEffects;
util::BreadthFirstSearch<YulString>{call.second, {funName}}.run( auto _visit = [&, visited = std::set<YulString>{}](YulString _function, auto&& _recurse) mutable {
[&](YulString _function, auto&& _addChild) { if (!visited.insert(_function).second)
if (sideEffects == SideEffects::worst()) return;
return; if (sideEffects == SideEffects::worst())
if (BuiltinFunction const* f = _dialect.builtin(_function)) return;
sideEffects += f->sideEffects; if (BuiltinFunction const* f = _dialect.builtin(_function))
else sideEffects += f->sideEffects;
{ else
if (ret.count(_function)) {
sideEffects += ret[_function]; if (ret.count(_function))
for (YulString callee: _directCallGraph.functionCalls.at(_function)) sideEffects += ret[_function];
_addChild(callee); for (YulString callee: _directCallGraph.functionCalls.at(_function))
} _recurse(callee, _recurse);
} }
); };
for (auto const& _v: call.second)
_visit(_v, _visit);
ret[funName] += sideEffects; ret[funName] += sideEffects;
} }
return ret; return ret;