00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
00028
#include "ShDomTree.hpp"
00029
#include <iostream>
00030
#include "ShDebug.hpp"
00031
#include "ShUtility.hpp"
00032
00033
00034
namespace SH {
00035
00036 ShDomTree::ShDomTree(ShCtrlGraphPtr graph)
00037 : m_graph(graph),
00038 m_n(0)
00039 {
00040 m_vertex.push_back(0);
00041
00042 dfs(m_graph->entry());
00043
00044
00045
for (
int i = m_n; i >= 2; i--) {
00046 ShCtrlGraphNodePtr w = m_vertex[i];
00047
00048 PredSet& pred = m_pred[w];
00049
for (PredSet::iterator I = pred.begin(); I != pred.end(); ++I) {
00050 ShCtrlGraphNodePtr v = *I;
00051 ShCtrlGraphNodePtr u = eval(v);
00052
if (m_semi[u] < m_semi[v]) m_semi[w] = m_semi[u];
00053 }
00054 m_bucket[m_vertex[m_semi[w]]].insert(w);
00055 link(m_parent[w], w);
00056
00057
00058 BucketSet& bucket = m_bucket[m_parent[w]];
00059
while (!bucket.empty()) {
00060 BucketSet::iterator I = bucket.begin();
00061 ShCtrlGraphNodePtr v = *I;
00062 bucket.erase(I);
00063 ShCtrlGraphNodePtr u = eval(v);
00064 m_dom[v] = (m_semi[u] < m_semi[v] ? u : m_parent[w]);
00065 }
00066 }
00067
00068
00069
for (
int i = 2; i <= m_n; i++) {
00070 ShCtrlGraphNodePtr w = m_vertex[i];
00071
if (m_dom[w] != m_vertex[m_semi[w]]) m_dom[w] = m_dom[m_dom[w]];
00072 }
00073 m_dom[m_graph->entry()] = 0;
00074 }
00075
00076
struct DebugDumper {
00077 DebugDumper(
const ShDomTree& tree)
00078 : tree(tree)
00079 {
00080 }
00081
void operator()(ShCtrlGraphNodePtr node,
int level) {
00082
00083
shPrintIndent(std::cerr, level);
00084 SH_DEBUG_PRINT(
"Node with numbering " << tree.numbering(node));
00085 }
00086
const ShDomTree& tree;
00087 };
00088
00089
void ShDomTree::debugDump()
00090 {
00091
#ifdef SH_DEBUG
00092
SH_DEBUG_PRINT(
"Debug Dump");
00093 DebugDumper d(*
this);
00094 preorder(d);
00095 SH_DEBUG_PRINT(
"Debug Dump End");
00096
#endif
00097
}
00098
00099
void ShDomTree::dfs(ShCtrlGraphNodePtr v)
00100 {
00101
if (!v)
return;
00102 m_n++;
00103 m_semi[v] = m_n;
00104 m_vertex.push_back(v);
00105 m_ancestor[v] = 0;
00106 m_label[v] = v;
00107
00108
for (std::vector<ShCtrlGraphBranch>::const_iterator I = v->successors.begin();
00109 I != v->successors.end(); ++I) {
00110 ShCtrlGraphNodePtr w = I->node;
00111
if (m_semi[w] == 0) {
00112 m_parent[w] = v;
00113 dfs(w);
00114 }
00115 m_pred[w].insert(v);
00116 }
00117 ShCtrlGraphNodePtr w = v->follower;
00118
if (w) {
00119
if (m_semi[w] == 0) {
00120 m_parent[w] = v;
00121 dfs(w);
00122 }
00123 m_pred[w].insert(v);
00124 }
00125 }
00126
00127 ShCtrlGraphNodePtr ShDomTree::eval(ShCtrlGraphNodePtr v)
00128 {
00129
if (!m_ancestor[v]) {
00130
return v;
00131 }
else {
00132 compress(v);
00133
return m_label[v];
00134 }
00135 }
00136
00137
void ShDomTree::compress(ShCtrlGraphNodePtr v)
00138 {
00139
00140
if (m_ancestor[m_ancestor[v]]) {
00141 compress(m_ancestor[v]);
00142
if (m_semi[m_label[m_ancestor[v]]] < m_semi[m_label[v]]) {
00143 m_label[v] = m_label[m_ancestor[v]];
00144 }
00145 m_ancestor[v] = m_ancestor[m_ancestor[v]];
00146 }
00147 }
00148
00149
void ShDomTree::link(ShCtrlGraphNodePtr v, ShCtrlGraphNodePtr w)
00150 {
00151 m_ancestor[w] = v;
00152 m_children[v].insert(w);
00153 }
00154
00155 }