2025-05-30 11:57:39 +03:00
|
|
|
#include "dvm.h"
|
|
|
|
|
#include "IR_domTree.h"
|
|
|
|
|
|
|
|
|
|
namespace SAPFOR {
|
|
|
|
|
void DominatorFinder::DFS(BasicBlock* v, int parent_num) {
|
|
|
|
|
dfs_num[v] = n;
|
|
|
|
|
vertex[n] = n;
|
|
|
|
|
semi[n] = n;
|
|
|
|
|
label[n] = n;
|
|
|
|
|
ancestor[n] = -1;
|
|
|
|
|
parent[n] = parent_num;
|
|
|
|
|
vertices[n++] = v;
|
|
|
|
|
|
|
|
|
|
for (const auto& w : v->getNext()) {
|
|
|
|
|
if (dfs_num[w] == -1)
|
|
|
|
|
DFS(w, dfs_num[v]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DominatorFinder::Compress(int v) {
|
|
|
|
|
if (ancestor[ancestor[v]] != -1) {
|
|
|
|
|
Compress(ancestor[v]);
|
|
|
|
|
|
|
|
|
|
if (semi[label[ancestor[v]]] < semi[label[v]])
|
|
|
|
|
label[v] = label[ancestor[v]];
|
|
|
|
|
ancestor[v] = ancestor[ancestor[v]];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DominatorFinder::Eval(int v) {
|
|
|
|
|
if (ancestor[v] == -1)
|
|
|
|
|
return v;
|
|
|
|
|
|
|
|
|
|
Compress(v);
|
|
|
|
|
return label[v];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DominatorFinder::Link(int v, int w) {
|
|
|
|
|
ancestor[w] = v;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DominatorFinder::DominatorFinder(std::vector<BasicBlock*>& blocks) {
|
|
|
|
|
if (blocks.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
entry = blocks[0];
|
|
|
|
|
n = 0;
|
|
|
|
|
|
|
|
|
|
for (auto block : blocks)
|
|
|
|
|
dfs_num[block] = -1;
|
|
|
|
|
|
|
|
|
|
int max_size = blocks.size();
|
|
|
|
|
vertices.resize(max_size);
|
|
|
|
|
parent.assign(max_size, -1);
|
|
|
|
|
semi.assign(max_size, -1);
|
|
|
|
|
vertex.assign(max_size, -1);
|
|
|
|
|
ancestor.assign(max_size, -1);
|
|
|
|
|
label.assign(max_size, -1);
|
|
|
|
|
bucket.resize(max_size);
|
|
|
|
|
|
|
|
|
|
DFS(entry, -1);
|
|
|
|
|
|
|
|
|
|
for (int i = n - 1; i > 0; --i) {
|
|
|
|
|
int w = vertex[i];
|
|
|
|
|
|
|
|
|
|
for (BasicBlock* v : vertices[w]->getPrev()) {
|
2025-06-04 09:18:24 +03:00
|
|
|
if (dfs_num[v] == -1)
|
|
|
|
|
continue;
|
2025-05-30 11:57:39 +03:00
|
|
|
int u = Eval(dfs_num[v]);
|
|
|
|
|
|
|
|
|
|
if (semi[u] < semi[w])
|
|
|
|
|
semi[w] = semi[u];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bucket[vertex[semi[w]]].push_back(w);
|
|
|
|
|
Link(parent[w], w);
|
|
|
|
|
|
|
|
|
|
for (int v : bucket[parent[w]])
|
|
|
|
|
{
|
|
|
|
|
int u = Eval(v);
|
|
|
|
|
if (semi[u] < semi[v])
|
|
|
|
|
vertices[v]->setDom(vertices[u]);
|
|
|
|
|
else
|
|
|
|
|
vertices[v]->setDom(vertices[parent[w]]);
|
|
|
|
|
}
|
|
|
|
|
bucket[parent[w]].clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i = 1; i < n; ++i) {
|
|
|
|
|
int w = vertex[i];
|
|
|
|
|
|
|
|
|
|
if (vertices[w]->getDom() != vertices[vertex[semi[w]]])
|
|
|
|
|
vertices[w]->setDom(vertices[w]->getDom()->getDom());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entry->setDom(nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void buildDominatorTree(std::vector<BasicBlock*>& blocks) {
|
|
|
|
|
DominatorFinder finder(blocks);
|
|
|
|
|
}
|
2025-06-04 09:18:24 +03:00
|
|
|
}
|