00001 // Sh: A GPU metaprogramming language. 00002 // 00003 // Copyright 2003-2005 Serious Hack Inc. 00004 // 00005 // This library is free software; you can redistribute it and/or 00006 // modify it under the terms of the GNU Lesser General Public 00007 // License as published by the Free Software Foundation; either 00008 // version 2.1 of the License, or (at your option) any later version. 00009 // 00010 // This library is distributed in the hope that it will be useful, 00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 // Lesser General Public License for more details. 00014 // 00015 // You should have received a copy of the GNU Lesser General Public 00016 // License along with this library; if not, write to the Free Software 00017 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00018 // MA 02110-1301, USA 00020 #ifndef SHSECTION_HPP 00021 #define SHSECTION_HPP 00022 00023 #include <map> 00024 #include <list> 00025 #include <iosfwd> 00026 #include "ShDllExport.hpp" 00027 #include "ShInfo.hpp" 00028 #include "ShRefCount.hpp" 00029 #include "ShCtrlGraph.hpp" 00030 #include "ShStructural.hpp" 00031 00037 // @todo range 00038 // This is poorly written...clean up if this ever needs to be merged into main 00039 00040 namespace SH { 00041 00042 /* Really just a bastard child of ShStructuralNode. 00043 * Maintains ShSectionNode information only in a much cleaner form 00044 * (Might just want to merge this into ShStructuralNode later...) 00045 */ 00046 class ShSectionNode: public ShRefCountable { 00047 public: 00049 ShSectionNode(); 00050 00051 typedef std::set<ShPointer<ShSectionNode> > SectionSet; 00052 typedef SectionSet::iterator iterator; 00053 typedef SectionSet::const_iterator const_iterator; 00054 00055 SectionSet children; 00056 ShSectionNode* parent; 00057 00058 iterator begin() { return children.begin(); } 00059 iterator end() { return children.end(); } 00060 const_iterator begin() const { return children.begin(); } 00061 const_iterator end() const { return children.end(); } 00062 void addChild(ShPointer<ShSectionNode> child); 00063 00064 typedef std::list<ShCtrlGraphNodePtr> CfgNodeList; 00065 typedef CfgNodeList::iterator cfg_iterator; 00066 typedef CfgNodeList::const_iterator const_cfg_iterator; 00067 00074 CfgNodeList cfgNodes; 00075 00076 cfg_iterator cfgBegin() { return cfgNodes.begin(); } 00077 cfg_iterator cfgEnd() { return cfgNodes.end(); } 00078 const_cfg_iterator cfgBegin() const { return cfgNodes.begin(); } 00079 const_cfg_iterator cfgEnd() const { return cfgNodes.end(); } 00080 void addCfg(ShCtrlGraphNodePtr cfgNode) { cfgNodes.push_back(cfgNode); } 00081 00082 /* Returns whether this is the root */ 00083 bool isRoot() const { return !parent; } 00084 00086 ShStatement* getStart(); 00087 ShStatement* getEnd(); 00088 00090 std::string name(); 00091 00092 /* Some useful queries about nodes in the tree */ 00093 int depth(); 00094 }; 00095 typedef ShPointer<ShSectionNode> ShSectionNodePtr; 00096 00097 class ShSectionTree { 00098 public: 00099 ShSectionNodePtr root; 00100 00101 ShSectionTree(ShStructural &structural); 00102 00103 /* DFS through the section tree 00104 * This is just a copy of the Cfg code...should really refactor */ 00105 template<class F> 00106 void dfs(F& functor); 00107 00108 /* Retrieves the section containing cfgNode */ 00109 ShSectionNodePtr operator[](ShCtrlGraphNodePtr cfgNode); 00110 00111 /* Returns whether a section node in this tree contains a particular section 00112 * node. */ 00113 bool contains(ShSectionNodePtr section, ShCtrlGraphNodePtr cfgNode); 00114 00115 /* Graphviz dump */ 00116 std::ostream& dump(std::ostream& out); 00117 00118 /* Graphviz dump with a special functor with two functions: 00119 * void operator()(std::ostream&, ShCtrlGraphNodePtr) that outputs a HTML-style label 00120 * for a cfg node 00121 * 00122 * void operator()(std::ostream&, ShSectionNodePtr) that outputs any section specific 00123 * attributes (as part of the stmts in a a section's subgraph) 00124 */ 00125 template<class F> 00126 std::ostream& dump(std::ostream& out, F& functor); 00127 00128 private: 00129 // adds structural subtree rooted at structNode to the section 00130 static void makeSection(ShStructuralNodePtr structNode, ShSectionNodePtr section); 00131 00132 typedef std::map<ShCtrlGraphNodePtr, ShSectionNodePtr> CfgSectionMap; 00133 CfgSectionMap cfgSection; 00134 void gatherCfgSection(ShSectionNodePtr section); 00135 00136 /* DFS through the section tree */ 00137 template<class F> 00138 static void realDfs(ShSectionNodePtr node, F& functor); 00139 00140 /* Dump a node and subtree using the given functor (functor described above in dump()) 00141 * 00142 * @param out Actual output stream to use 00143 * @param cfgout Output stream to use for edges that cross section 00144 * boundaries (These must be specified after all involved sections are, 00145 * otherwise DOT does stupid things with the cfg nodes) 00146 * @param node The root of the section subtree to process 00147 * @param F functor as described above in dump*/ 00148 template<class F> 00149 void realDump(std::ostream& out, std::ostream& cfgout, ShSectionNodePtr node, F& functor); 00150 }; 00151 00152 } 00153 00154 #include "ShSectionImpl.hpp" 00155 00156 #endif
1.4.5