This commit is contained in:
Leonardo Alt 2021-01-05 14:05:30 +01:00
parent fce6d99900
commit ced79497f5
2 changed files with 22 additions and 20 deletions

View File

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

View File

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