mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
fixup! Implementation of Lengauer-Tarjan algorithm to find dominators
This commit is contained in:
parent
e4bac1340d
commit
b7ec9d3fdd
@ -27,6 +27,11 @@
|
|||||||
#include <libyul/backends/evm/ControlFlowGraph.h>
|
#include <libyul/backends/evm/ControlFlowGraph.h>
|
||||||
#include <libsolutil/Visitor.h>
|
#include <libsolutil/Visitor.h>
|
||||||
|
|
||||||
|
#include <range/v3/algorithm.hpp>
|
||||||
|
#include <range/v3/view/drop.hpp>
|
||||||
|
#include <range/v3/view/reverse.hpp>
|
||||||
|
#include <range/v3/view/transform.hpp>
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -117,8 +122,8 @@ public:
|
|||||||
solAssert(!m_immediateDominator.empty());
|
solAssert(!m_immediateDominator.empty());
|
||||||
|
|
||||||
//Ignoring the entry node since no one dominates it.
|
//Ignoring the entry node since no one dominates it.
|
||||||
for (size_t i = 1; i < m_immediateDominator.size(); ++i)
|
for (size_t idomIdx: m_immediateDominator | ranges::views::drop(1))
|
||||||
m_dominatorTree[m_immediateDominator[i]].emplace_back(i);
|
m_dominatorTree[idomIdx].emplace_back(idomIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Path compression updates the ancestors of vertices along
|
// Path compression updates the ancestors of vertices along
|
||||||
@ -177,6 +182,8 @@ public:
|
|||||||
return _v;
|
return _v;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
auto toIdx = [&](Vertex const& v) { return m_vertexIndex[v]; };
|
||||||
|
|
||||||
// step 1
|
// step 1
|
||||||
std::set<Vertex> visited;
|
std::set<Vertex> visited;
|
||||||
// predecessors(w): The set of vertices ``v`` such that (``v``, ``w``) is an edge of the graph.
|
// predecessors(w): The set of vertices ``v`` such that (``v``, ``w``) is an edge of the graph.
|
||||||
@ -210,9 +217,8 @@ public:
|
|||||||
dfs(_entry, dfs);
|
dfs(_entry, dfs);
|
||||||
|
|
||||||
// Process the vertices in decreasing order of the dfs number
|
// Process the vertices in decreasing order of the dfs number
|
||||||
for (auto it = m_vertex.rbegin(); it != m_vertex.rend(); ++it)
|
for (size_t w: m_vertex | ranges::views::reverse | ranges::views::transform(toIdx))
|
||||||
{
|
{
|
||||||
Vertex const& w = m_vertexIndex[*it];
|
|
||||||
// step 3
|
// step 3
|
||||||
// NOTE: this is an optimization, i.e. performing the step 3 before step 2.
|
// NOTE: this is an optimization, i.e. performing the step 3 before step 2.
|
||||||
// The goal is to process the bucket in the beginning of the loop for the vertex ``w``
|
// The goal is to process the bucket in the beginning of the loop for the vertex ``w``
|
||||||
@ -220,9 +226,8 @@ public:
|
|||||||
// Inverting those steps ensures that a bucket is only processed once and
|
// Inverting those steps ensures that a bucket is only processed once and
|
||||||
// it does not need to be erased.
|
// it does not need to be erased.
|
||||||
// The optimization proposal is available here: https://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf pg.77
|
// The optimization proposal is available here: https://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf pg.77
|
||||||
for_each(
|
ranges::for_each(
|
||||||
bucket[w].begin(),
|
bucket[w],
|
||||||
bucket[w].end(),
|
|
||||||
[&](size_t v)
|
[&](size_t v)
|
||||||
{
|
{
|
||||||
size_t u = eval(v);
|
size_t u = eval(v);
|
||||||
@ -243,12 +248,10 @@ public:
|
|||||||
|
|
||||||
// step 4
|
// step 4
|
||||||
idom[0] = 0;
|
idom[0] = 0;
|
||||||
for (auto it = m_vertex.begin() + 1; it != m_vertex.end(); ++it)
|
for (size_t w: m_vertex | ranges::views::drop(1) | ranges::views::transform(toIdx))
|
||||||
{
|
|
||||||
size_t w = m_vertexIndex[*it];
|
|
||||||
if (idom[w] != semi[w])
|
if (idom[w] != semi[w])
|
||||||
idom[w] = idom[idom[w]];
|
idom[w] = idom[idom[w]];
|
||||||
}
|
|
||||||
return idom;
|
return idom;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user