Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

ShCtrlGraph.cpp

00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright (c) 2003 University of Waterloo Computer Graphics Laboratory 00004 // Project administrator: Michael D. McCool 00005 // Authors: Zheng Qin, Stefanus Du Toit, Kevin Moule, Tiberiu S. Popa, 00006 // Michael D. McCool 00007 // 00008 // This software is provided 'as-is', without any express or implied 00009 // warranty. In no event will the authors be held liable for any damages 00010 // arising from the use of this software. 00011 // 00012 // Permission is granted to anyone to use this software for any purpose, 00013 // including commercial applications, and to alter it and redistribute it 00014 // freely, subject to the following restrictions: 00015 // 00016 // 1. The origin of this software must not be misrepresented; you must 00017 // not claim that you wrote the original software. If you use this 00018 // software in a product, an acknowledgment in the product documentation 00019 // would be appreciated but is not required. 00020 // 00021 // 2. Altered source versions must be plainly marked as such, and must 00022 // not be misrepresented as being the original software. 00023 // 00024 // 3. This notice may not be removed or altered from any source 00025 // distribution. 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); // catch empty tails 00291 m_entry->clearMarked(); 00292 m_entry->dfs(copier); 00293 00294 // Replace the successors and followers in the new graph with their new equivalents 00295 for (CtrlGraphCopyMap::iterator I = copyMap.begin(); I != copyMap.end(); ++I) { 00296 ShCtrlGraphNodePtr node = I->second; // Get the new node 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

Generated on Mon Oct 18 14:17:39 2004 for Sh by doxygen 1.3.7