diff --git a/src/CFGraph/IR_domTree.cpp b/src/CFGraph/IR_domTree.cpp new file mode 100644 index 0000000..cfab670 --- /dev/null +++ b/src/CFGraph/IR_domTree.cpp @@ -0,0 +1,100 @@ +#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& 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()) { + 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& blocks) { + DominatorFinder finder(blocks); + } +} \ No newline at end of file