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
#include "ShCtrlGraph.hpp"
00028
#include <iostream>
00029
#include <cassert>
00030
#include <vector>
00031
#include "ShBasicBlock.hpp"
00032
#include "ShToken.hpp"
00033
#include "ShTokenizer.hpp"
00034
#include "ShUtility.hpp"
00035
#include "ShParser.hpp"
00036
#include "ShDebug.hpp"
00037
00038
namespace SH {
00039
00040 ShCtrlGraphNode::ShCtrlGraphNode()
00041 : follower(0), m_marked(false)
00042 {
00043 }
00044
00045 ShCtrlGraphNode::~ShCtrlGraphNode() {
00046 }
00047
00048 std::ostream& ShCtrlGraphNode::print(std::ostream& out,
int indent)
const
00049
{
00050
if (
marked())
return out;
00051
mark();
00052
00053
if (block) block->print(out, indent);
00054
if (
follower) {
00055
shPrintIndent(out, indent);
00056 out <<
"->" << std::endl;
00057
follower->print(out, indent + 2);
00058 }
00059
for (SuccessorList::const_iterator I =
successors.begin();
00060 I !=
successors.end(); ++I) {
00061
shPrintIndent(out, indent);
00062
if (!I->cond.null()) {
00063 out <<
"[" << I->cond.name() <<
"]" << std::endl;
00064 }
00065 out <<
"->" << std::endl;
00066 I->node->print(out, indent + 2);
00067 }
00068
return out;
00069 }
00070
00071 std::ostream& ShCtrlGraphNode::graphvizDump(std::ostream& out)
const
00072
{
00073
if (
marked())
return out;
00074
mark();
00075 out <<
"\"" <<
this <<
"\" ";
00076
if (block) {
00077 out <<
" [label=\"";
00078 block->graphvizDump(out);
00079 out <<
"\", shape=box]";
00080 }
else {
00081 out <<
" [label=\"\", shape=circle, height=0.25]";
00082 }
00083 out <<
";" << std::endl;
00084
00085
for (SuccessorList::const_iterator I =
successors.begin();
00086 I !=
successors.end(); ++I) {
00087 I->node->graphvizDump(out);
00088 out <<
"\"" <<
this <<
"\" ";
00089 out <<
"-> ";
00090 out <<
"\"" << I->node.object() <<
"\" ";
00091
00092 out <<
"[style=dashed, label=\"" << I->cond.name() <<
"\"]";
00093 out <<
";" << std::endl;
00094 }
00095
00096
if (
follower) {
00097
follower->graphvizDump(out);
00098 out <<
"\"" <<
this <<
"\" ";
00099 out <<
"-> ";
00100 out <<
"\"" <<
follower.
object() <<
"\";" << std::endl;
00101 }
00102
00103
return out;
00104 }
00105
00106 bool ShCtrlGraphNode::marked()
const
00107
{
00108
return m_marked;
00109 }
00110
00111 void ShCtrlGraphNode::mark()
const
00112
{
00113 m_marked =
true;
00114 }
00115
00116 void ShCtrlGraphNode::clearMarked()
const
00117
{
00118
if (!
marked())
return ;
00119 m_marked =
false;
00120
00121
if (
follower)
follower->clearMarked();
00122
00123
for (SuccessorList::const_iterator I =
successors.begin();
00124 I !=
successors.end(); ++I) {
00125 I->node->clearMarked();
00126 }
00127 }
00128
00129 void ShCtrlGraphNode::append(
const ShPointer<ShCtrlGraphNode>& node)
00130 {
00131
if (!node)
return;
00132 assert(!
follower);
00133
follower = node;
00134 }
00135
00136 void ShCtrlGraphNode::append(
const ShPointer<ShCtrlGraphNode>& node,
00137
ShVariable cond)
00138 {
00139
if (node)
successors.push_back(ShCtrlGraphBranch(node,
cond));
00140 }
00141
00142 ShCtrlGraphBranch::ShCtrlGraphBranch(
const ShPointer<ShCtrlGraphNode>& node,
00143
ShVariable cond)
00144 : node(node),
cond(
cond)
00145 {
00146 }
00147
00148 ShCtrlGraph::ShCtrlGraph(ShCtrlGraphNodePtr head, ShCtrlGraphNodePtr tail)
00149 : m_entry(head),
00150 m_exit(tail)
00151 {
00152 }
00153
00154 ShCtrlGraph::ShCtrlGraph(ShBlockListPtr blocks)
00155 : m_entry(new ShCtrlGraphNode()),
00156 m_exit(new ShCtrlGraphNode())
00157 {
00158 ShCtrlGraphNodePtr head, tail;
00159
00160 ShParser::parse(head, tail, blocks);
00161
00162
if(!head && !tail) {
00163 m_entry->append(m_exit);
00164 }
else {
00165 SH_DEBUG_ASSERT(head && tail);
00166 m_entry->append(head);
00167 tail->append(m_exit);
00168 }
00169 }
00170
00171 ShCtrlGraph::~ShCtrlGraph()
00172 {
00173 }
00174
00175 ShCtrlGraphNodePtr ShCtrlGraph::entry()
const
00176
{
00177
return m_entry;
00178 }
00179
00180 ShCtrlGraphNodePtr ShCtrlGraph::exit()
const
00181
{
00182
return m_exit;
00183 }
00184
00185 ShCtrlGraphNodePtr ShCtrlGraph::prependEntry() {
00186
ShCtrlGraphNodePtr newEntry =
new ShCtrlGraphNode();
00187
ShCtrlGraphNodePtr oldEntry = m_entry;
00188 newEntry->append(oldEntry);
00189 newEntry->mark();
00190
00191
if( oldEntry->block ) {
00192 SH_DEBUG_WARN(
"Old entry to control graph did not have an empty block!");
00193 }
else {
00194 oldEntry->block =
new ShBasicBlock();
00195 }
00196 m_entry = newEntry;
00197
return oldEntry;
00198 }
00199
00200 ShCtrlGraphNodePtr ShCtrlGraph::appendExit() {
00201
ShCtrlGraphNodePtr newExit =
new ShCtrlGraphNode();
00202
ShCtrlGraphNodePtr oldExit = m_exit;
00203 oldExit->append(newExit);
00204
00205
if( oldExit->block ) {
00206 SH_DEBUG_WARN(
"Old exit to control graph did not have an empty block!");
00207 }
else {
00208 oldExit->block =
new ShBasicBlock();
00209 }
00210 m_exit = newExit;
00211
return oldExit;
00212 }
00213
00214 std::ostream& ShCtrlGraph::print(std::ostream& out,
int indent)
const
00215
{
00216
if (m_entry) {
00217 m_entry->clearMarked();
00218 m_entry->print(out, indent);
00219 }
00220
00221
return out;
00222 }
00223
00224 std::ostream& ShCtrlGraph::graphvizDump(std::ostream& out)
const
00225
{
00226 out <<
"digraph control {" << std::endl;
00227
00228
if (m_entry) {
00229 m_entry->clearMarked();
00230 m_entry->graphvizDump(out);
00231 }
00232
00233 out <<
"}" << std::endl;
00234
return out;
00235 }
00236
00237
struct ClearPreds {
00238
void operator()(ShCtrlGraphNodePtr node) {
00239
if (!node)
return;
00240 node->predecessors.clear();
00241 }
00242 };
00243
00244
struct ComputePreds {
00245
void operator()(ShCtrlGraphNode* node) {
00246
if (!node)
return;
00247
00248
for (ShCtrlGraphNode::SuccessorList::iterator I = node->successors.begin();
00249 I != node->successors.end(); ++I) {
00250
if (I->node) I->node->predecessors.push_back(node);
00251 }
00252
if (node->follower) node->follower->predecessors.push_back(node);
00253 }
00254 };
00255
00256
00257 void ShCtrlGraph::computePredecessors()
00258 {
00259 ClearPreds clear;
00260 dfs(clear);
00261
00262 ComputePreds comp;
00263 dfs(comp);
00264 }
00265
00266
typedef std::map<ShCtrlGraphNodePtr, ShCtrlGraphNodePtr> CtrlGraphCopyMap;
00267
00268
struct CtrlGraphCopier {
00269 CtrlGraphCopier(CtrlGraphCopyMap& copyMap)
00270 : copyMap(copyMap)
00271 {
00272 }
00273
00274
void operator()(ShCtrlGraphNodePtr node) {
00275
if (!node)
return;
00276 ShCtrlGraphNodePtr newNode =
new ShCtrlGraphNode(*node);
00277 copyMap[node] = newNode;
00278 }
00279
00280 CtrlGraphCopyMap& copyMap;
00281 };
00282
00283
void ShCtrlGraph::copy(ShCtrlGraphNodePtr& newHead, ShCtrlGraphNodePtr& newTail)
const
00284
{
00285 CtrlGraphCopyMap copyMap;
00286 copyMap[0] = 0;
00287
00288 CtrlGraphCopier copier(copyMap);
00289 SH_DEBUG_ASSERT(m_entry);
00290 SH_DEBUG_ASSERT(m_exit);
00291 m_entry->clearMarked();
00292 m_entry->dfs(copier);
00293
00294
00295
for (CtrlGraphCopyMap::iterator I = copyMap.begin(); I != copyMap.end(); ++I) {
00296 ShCtrlGraphNodePtr node = I->second;
00297
if (!node)
continue;
00298
for (ShCtrlGraphNode::SuccessorList::iterator J = node->successors.begin();
00299 J != node->successors.end(); ++J) {
00300 J->node = copyMap[J->node];
00301 }
00302 node->follower = copyMap[node->follower];
00303
if (node->block) {
00304 ShBasicBlockPtr new_block =
new ShBasicBlock(*node->block);
00305 node->block = new_block;
00306 }
00307 }
00308 newHead = copyMap[m_entry];
00309 newTail = copyMap[m_exit];
00310 SH_DEBUG_ASSERT(newHead);
00311 SH_DEBUG_ASSERT(newTail);
00312
00313 m_entry->clearMarked();
00314 }
00315
00316
00317
00318 }
00319